1 /* 2 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de> 3 * Copyright 2012, Haiku Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 * 6 * Authors: 7 * John Scipione <jscipione@gmail.com> 8 */ 9 10 11 #include <ControlLook.h> 12 13 #include <Control.h> 14 #include <GradientLinear.h> 15 #include <Region.h> 16 #include <Shape.h> 17 #include <String.h> 18 #include <View.h> 19 #include <Window.h> 20 21 #include "ContainerWindow.h" 22 23 24 namespace BPrivate { 25 26 27 static const float kEdgeBevelLightTint = 0.59; 28 static const float kEdgeBevelShadowTint = 1.0735; 29 30 31 BControlLook::BControlLook(): 32 fCachedOutline(false), 33 fCachedWorkspace(-1) 34 { 35 } 36 37 38 BControlLook::~BControlLook() 39 { 40 } 41 42 43 BAlignment 44 BControlLook::DefaultLabelAlignment() const 45 { 46 return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER); 47 } 48 49 50 float 51 BControlLook::DefaultLabelSpacing() const 52 { 53 return ceilf(be_plain_font->Size() / 2.0); 54 } 55 56 57 float 58 BControlLook::DefaultItemSpacing() const 59 { 60 return ceilf(be_plain_font->Size() * 0.85); 61 } 62 63 64 float 65 BControlLook::ComposeSpacing(float spacing) 66 { 67 if (spacing == B_USE_DEFAULT_SPACING || spacing == B_USE_ITEM_SPACING) { 68 return be_control_look->DefaultItemSpacing(); 69 } else if (spacing == B_USE_HALF_ITEM_SPACING) { 70 return be_control_look->DefaultItemSpacing() * 0.5f; 71 } else if (spacing == B_USE_WINDOW_INSETS) { 72 return be_control_look->DefaultItemSpacing(); 73 } else if (spacing == B_USE_SMALL_SPACING) { 74 return be_control_look->DefaultItemSpacing() * 0.7f; 75 } else if (spacing == B_USE_BIG_SPACING) { 76 return be_control_look->DefaultItemSpacing() * 1.3f; 77 } 78 return spacing; 79 } 80 81 82 uint32 83 BControlLook::Flags(BControl* control) const 84 { 85 uint32 flags = 0; 86 87 if (!control->IsEnabled()) 88 flags |= B_DISABLED; 89 90 if (control->IsFocus()) 91 flags |= B_FOCUSED; 92 93 if (control->Value() == B_CONTROL_ON) 94 flags |= B_ACTIVATED; 95 96 if (control->Parent() != NULL 97 && (control->Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0) { 98 // In this constellation, assume we want to render the control 99 // against the already existing view contents of the parent view. 100 flags |= B_BLEND_FRAME; 101 } 102 103 return flags; 104 } 105 106 107 // #pragma mark - 108 109 110 void 111 BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, 112 const rgb_color& base, const rgb_color& background, uint32 flags, 113 uint32 borders) 114 { 115 _DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base, 116 background, 1.0, 1.0, flags, borders); 117 } 118 119 120 void 121 BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, 122 float radius, const rgb_color& base, const rgb_color& background, uint32 flags, 123 uint32 borders) 124 { 125 _DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius, 126 base, background, 1.0, 1.0, flags, borders); 127 } 128 129 130 void 131 BControlLook::DrawButtonFrame(BView* view, BRect& rect, 132 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 133 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 134 const rgb_color& background, uint32 flags, 135 uint32 borders) 136 { 137 _DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius, 138 leftBottomRadius, rightBottomRadius, base, background, 139 1.0, 1.0, flags, borders); 140 } 141 142 143 void 144 BControlLook::DrawButtonBackground(BView* view, BRect& rect, 145 const BRect& updateRect, const rgb_color& base, uint32 flags, 146 uint32 borders, enum orientation orientation) 147 { 148 _DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, 149 base, flags, borders, orientation); 150 } 151 152 153 void 154 BControlLook::DrawButtonBackground(BView* view, BRect& rect, 155 const BRect& updateRect, float radius, const rgb_color& base, uint32 flags, 156 uint32 borders, enum orientation orientation) 157 { 158 _DrawButtonBackground(view, rect, updateRect, radius, radius, radius, 159 radius, base, flags, borders, orientation); 160 } 161 162 163 void 164 BControlLook::DrawButtonBackground(BView* view, BRect& rect, 165 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 166 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 167 uint32 flags, uint32 borders, enum orientation orientation) 168 { 169 _DrawButtonBackground(view, rect, updateRect, leftTopRadius, 170 rightTopRadius, leftBottomRadius, rightBottomRadius, base, flags, 171 borders, orientation); 172 } 173 174 175 void 176 BControlLook::DrawMenuBarBackground(BView* view, BRect& rect, 177 const BRect& updateRect, const rgb_color& base, uint32 flags, 178 uint32 borders) 179 { 180 if (!rect.IsValid() || !rect.Intersects(updateRect)) 181 return; 182 183 // the surface edges 184 185 // colors 186 float topTint; 187 float bottomTint; 188 189 if ((flags & B_ACTIVATED) != 0) { 190 rgb_color bevelColor1 = tint_color(base, 1.40); 191 rgb_color bevelColor2 = tint_color(base, 1.25); 192 193 topTint = 1.25; 194 bottomTint = 1.20; 195 196 _DrawFrame(view, rect, 197 bevelColor1, bevelColor1, 198 bevelColor2, bevelColor2, 199 borders & B_TOP_BORDER); 200 } else { 201 rgb_color cornerColor = tint_color(base, 0.9); 202 rgb_color bevelColorTop = tint_color(base, 0.5); 203 rgb_color bevelColorLeft = tint_color(base, 0.7); 204 rgb_color bevelColorRightBottom = tint_color(base, 1.08); 205 206 topTint = 0.69; 207 bottomTint = 1.03; 208 209 _DrawFrame(view, rect, 210 bevelColorLeft, bevelColorTop, 211 bevelColorRightBottom, bevelColorRightBottom, 212 cornerColor, cornerColor, 213 borders); 214 } 215 216 // draw surface top 217 _FillGradient(view, rect, base, topTint, bottomTint); 218 } 219 220 221 void 222 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 223 const BRect& updateRect, const rgb_color& base, 224 const rgb_color& background, uint32 flags, uint32 borders) 225 { 226 _DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base, 227 background, 0.6, 1.0, flags, borders); 228 } 229 230 231 void 232 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 233 const BRect& updateRect, float radius, const rgb_color& base, 234 const rgb_color& background, uint32 flags, uint32 borders) 235 { 236 _DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius, 237 base, background, 0.6, 1.0, flags, borders); 238 } 239 240 241 void 242 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 243 const BRect& updateRect, float leftTopRadius, 244 float rightTopRadius, float leftBottomRadius, 245 float rightBottomRadius, const rgb_color& base, 246 const rgb_color& background, uint32 flags, uint32 borders) 247 { 248 _DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius, 249 leftBottomRadius, rightBottomRadius, base, background, 0.6, 1.0, 250 flags, borders); 251 } 252 253 254 void 255 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 256 const BRect& updateRect, const rgb_color& base, bool popupIndicator, 257 uint32 flags) 258 { 259 _DrawMenuFieldBackgroundOutside(view, rect, updateRect, 260 0.0f, 0.0f, 0.0f, 0.0f, base, popupIndicator, flags); 261 } 262 263 264 void 265 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 266 const BRect& updateRect, const rgb_color& base, uint32 flags, 267 uint32 borders) 268 { 269 _DrawMenuFieldBackgroundInside(view, rect, updateRect, 270 0.0f, 0.0f, 0.0f, 0.0f, base, flags, borders); 271 } 272 273 274 void 275 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 276 const BRect& updateRect, float radius, const rgb_color& base, 277 bool popupIndicator, uint32 flags) 278 { 279 _DrawMenuFieldBackgroundOutside(view, rect, updateRect, radius, radius, 280 radius, radius, base, popupIndicator, flags); 281 } 282 283 284 void 285 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 286 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 287 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 288 bool popupIndicator, uint32 flags) 289 { 290 _DrawMenuFieldBackgroundOutside(view, rect, updateRect, leftTopRadius, 291 rightTopRadius, leftBottomRadius, rightBottomRadius, base, 292 popupIndicator, flags); 293 } 294 295 296 void 297 BControlLook::DrawMenuBackground(BView* view, BRect& rect, 298 const BRect& updateRect, const rgb_color& base, uint32 flags, 299 uint32 borders) 300 { 301 if (!rect.IsValid() || !rect.Intersects(updateRect)) 302 return; 303 304 // surface top color 305 rgb_color background = tint_color(base, 0.75); 306 307 // inner bevel colors 308 rgb_color bevelLightColor; 309 rgb_color bevelShadowColor; 310 311 if ((flags & B_DISABLED) != 0) { 312 bevelLightColor = tint_color(background, 0.80); 313 bevelShadowColor = tint_color(background, 1.07); 314 } else { 315 bevelLightColor = tint_color(background, 0.6); 316 bevelShadowColor = tint_color(background, 1.12); 317 } 318 319 // draw inner bevel 320 _DrawFrame(view, rect, 321 bevelLightColor, bevelLightColor, 322 bevelShadowColor, bevelShadowColor, 323 borders); 324 325 // draw surface top 326 view->SetHighColor(background); 327 view->FillRect(rect); 328 } 329 330 331 void 332 BControlLook::DrawMenuItemBackground(BView* view, BRect& rect, 333 const BRect& updateRect, const rgb_color& base, uint32 flags, 334 uint32 borders) 335 { 336 if (!rect.IsValid() || !rect.Intersects(updateRect)) 337 return; 338 339 // surface edges 340 float topTint; 341 float bottomTint; 342 rgb_color selectedColor = base; 343 344 if ((flags & B_ACTIVATED) != 0) { 345 topTint = 0.9; 346 bottomTint = 1.05; 347 } else if ((flags & B_DISABLED) != 0) { 348 topTint = 0.80; 349 bottomTint = 1.07; 350 } else { 351 topTint = 0.6; 352 bottomTint = 1.12; 353 } 354 355 rgb_color bevelLightColor = tint_color(selectedColor, topTint); 356 rgb_color bevelShadowColor = tint_color(selectedColor, bottomTint); 357 358 // draw surface edges 359 _DrawFrame(view, rect, 360 bevelLightColor, bevelLightColor, 361 bevelShadowColor, bevelShadowColor, 362 borders); 363 364 // draw surface top 365 view->SetLowColor(selectedColor); 366 // _FillGradient(view, rect, selectedColor, topTint, bottomTint); 367 _FillGradient(view, rect, selectedColor, bottomTint, topTint); 368 } 369 370 371 void 372 BControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, 373 const rgb_color& base, const rgb_color& barColor, float progressPosition) 374 { 375 if (!rect.Intersects(updateRect)) 376 return; 377 378 _DrawOuterResessedFrame(view, rect, base, 0.6); 379 380 // colors 381 rgb_color dark1BorderColor = tint_color(base, 1.3); 382 rgb_color dark2BorderColor = tint_color(base, 1.2); 383 rgb_color dark1FilledBorderColor = tint_color(barColor, 1.20); 384 rgb_color dark2FilledBorderColor = tint_color(barColor, 1.45); 385 386 BRect filledRect(rect); 387 filledRect.right = progressPosition - 1; 388 389 BRect nonfilledRect(rect); 390 nonfilledRect.left = progressPosition; 391 392 bool filledSurface = filledRect.Width() > 0; 393 bool nonfilledSurface = nonfilledRect.Width() > 0; 394 395 if (filledSurface) { 396 _DrawFrame(view, filledRect, 397 dark1FilledBorderColor, dark1FilledBorderColor, 398 dark2FilledBorderColor, dark2FilledBorderColor); 399 400 _FillGlossyGradient(view, filledRect, barColor, 0.55, 0.68, 0.76, 0.90); 401 } 402 403 if (nonfilledSurface) { 404 _DrawFrame(view, nonfilledRect, dark1BorderColor, dark1BorderColor, 405 dark2BorderColor, dark2BorderColor, 406 B_TOP_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER); 407 408 if (nonfilledRect.left < nonfilledRect.right) { 409 // shadow from fill bar, or left border 410 rgb_color leftBorder = dark1BorderColor; 411 if (filledSurface) 412 leftBorder = tint_color(base, 0.50); 413 view->SetHighColor(leftBorder); 414 view->StrokeLine(nonfilledRect.LeftTop(), 415 nonfilledRect.LeftBottom()); 416 nonfilledRect.left++; 417 } 418 419 _FillGradient(view, nonfilledRect, base, 0.25, 0.06); 420 } 421 } 422 423 424 void 425 BControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, 426 const rgb_color& base, uint32 flags) 427 { 428 if (!rect.Intersects(updateRect)) 429 return; 430 431 rgb_color dark1BorderColor; 432 rgb_color dark2BorderColor; 433 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 434 435 if ((flags & B_DISABLED) != 0) { 436 _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags); 437 438 dark1BorderColor = tint_color(base, 1.15); 439 dark2BorderColor = tint_color(base, 1.15); 440 } else if ((flags & B_CLICKED) != 0) { 441 dark1BorderColor = tint_color(base, 1.50); 442 dark2BorderColor = tint_color(base, 1.48); 443 444 _DrawFrame(view, rect, 445 dark1BorderColor, dark1BorderColor, 446 dark2BorderColor, dark2BorderColor); 447 448 dark2BorderColor = dark1BorderColor; 449 } else { 450 _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags); 451 452 dark1BorderColor = tint_color(base, 1.40); 453 dark2BorderColor = tint_color(base, 1.38); 454 } 455 456 if ((flags & B_FOCUSED) != 0) { 457 dark1BorderColor = navigationColor; 458 dark2BorderColor = navigationColor; 459 } 460 461 _DrawFrame(view, rect, 462 dark1BorderColor, dark1BorderColor, 463 dark2BorderColor, dark2BorderColor); 464 465 if ((flags & B_DISABLED) != 0) { 466 _FillGradient(view, rect, base, 0.4, 0.2); 467 } else { 468 _FillGradient(view, rect, base, 0.15, 0.0); 469 } 470 471 rgb_color markColor; 472 if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { 473 view->SetHighColor(markColor); 474 475 rect.InsetBy(2, 2); 476 view->SetPenSize(max_c(1.0, ceilf(rect.Width() / 3.5))); 477 view->SetDrawingMode(B_OP_OVER); 478 479 view->StrokeLine(rect.LeftTop(), rect.RightBottom()); 480 view->StrokeLine(rect.LeftBottom(), rect.RightTop()); 481 } 482 } 483 484 485 void 486 BControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect, 487 const rgb_color& base, uint32 flags) 488 { 489 if (!rect.Intersects(updateRect)) 490 return; 491 492 rgb_color borderColor; 493 rgb_color bevelLight; 494 rgb_color bevelShadow; 495 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 496 497 if ((flags & B_DISABLED) != 0) { 498 borderColor = tint_color(base, 1.15); 499 bevelLight = base; 500 bevelShadow = base; 501 } else if ((flags & B_CLICKED) != 0) { 502 borderColor = tint_color(base, 1.50); 503 bevelLight = borderColor; 504 bevelShadow = borderColor; 505 } else { 506 borderColor = tint_color(base, 1.45); 507 bevelLight = tint_color(base, 0.55); 508 bevelShadow = tint_color(base, 1.11); 509 } 510 511 if ((flags & B_FOCUSED) != 0) { 512 borderColor = navigationColor; 513 } 514 515 BGradientLinear bevelGradient; 516 bevelGradient.AddColor(bevelShadow, 0); 517 bevelGradient.AddColor(bevelLight, 255); 518 bevelGradient.SetStart(rect.LeftTop()); 519 bevelGradient.SetEnd(rect.RightBottom()); 520 521 view->FillEllipse(rect, bevelGradient); 522 rect.InsetBy(1, 1); 523 524 bevelGradient.MakeEmpty(); 525 bevelGradient.AddColor(borderColor, 0); 526 bevelGradient.AddColor(tint_color(borderColor, 0.8), 255); 527 view->FillEllipse(rect, bevelGradient); 528 rect.InsetBy(1, 1); 529 530 float topTint; 531 float bottomTint; 532 if ((flags & B_DISABLED) != 0) { 533 topTint = 0.4; 534 bottomTint = 0.2; 535 } else { 536 topTint = 0.15; 537 bottomTint = 0.0; 538 } 539 540 BGradientLinear gradient; 541 _MakeGradient(gradient, rect, base, topTint, bottomTint); 542 view->FillEllipse(rect, gradient); 543 544 rgb_color markColor; 545 if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { 546 view->SetHighColor(markColor); 547 rect.InsetBy(3, 3); 548 view->FillEllipse(rect); 549 } 550 } 551 552 553 void 554 BControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, 555 const BRect& updateRect, const rgb_color& base, uint32 flags, 556 enum orientation orientation) 557 { 558 DrawScrollBarBackground(view, rect1, updateRect, base, flags, orientation); 559 DrawScrollBarBackground(view, rect2, updateRect, base, flags, orientation); 560 } 561 562 563 void 564 BControlLook::DrawScrollBarBackground(BView* view, BRect& rect, 565 const BRect& updateRect, const rgb_color& base, uint32 flags, 566 enum orientation orientation) 567 { 568 if (!rect.IsValid() || !rect.Intersects(updateRect)) 569 return; 570 571 float gradient1Tint; 572 float gradient2Tint; 573 float darkEdge1Tint; 574 float darkEdge2Tint; 575 float shadowTint; 576 577 if ((flags & B_DISABLED) != 0) { 578 gradient1Tint = 0.9; 579 gradient2Tint = 0.8; 580 darkEdge1Tint = B_DARKEN_2_TINT; 581 darkEdge2Tint = B_DARKEN_2_TINT; 582 shadowTint = gradient1Tint; 583 } else { 584 gradient1Tint = 1.10; 585 gradient2Tint = 1.05; 586 darkEdge1Tint = B_DARKEN_3_TINT; 587 darkEdge2Tint = B_DARKEN_2_TINT; 588 shadowTint = gradient1Tint; 589 } 590 591 rgb_color darkEdge1 = tint_color(base, darkEdge1Tint); 592 rgb_color darkEdge2 = tint_color(base, darkEdge2Tint); 593 rgb_color shadow = tint_color(base, shadowTint); 594 595 if (orientation == B_HORIZONTAL) { 596 // dark vertical line on left edge 597 if (rect.Width() > 0) { 598 view->SetHighColor(darkEdge1); 599 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 600 rect.left++; 601 } 602 // dark vertical line on right edge 603 if (rect.Width() >= 0) { 604 view->SetHighColor(darkEdge2); 605 view->StrokeLine(rect.RightTop(), rect.RightBottom()); 606 rect.right--; 607 } 608 // vertical shadow line after left edge 609 if (rect.Width() >= 0) { 610 view->SetHighColor(shadow); 611 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 612 rect.left++; 613 } 614 // fill 615 if (rect.Width() >= 0) { 616 _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, 617 orientation); 618 } 619 } else { 620 // dark vertical line on top edge 621 if (rect.Height() > 0) { 622 view->SetHighColor(darkEdge1); 623 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 624 rect.top++; 625 } 626 // dark vertical line on bottom edge 627 if (rect.Height() >= 0) { 628 view->SetHighColor(darkEdge2); 629 view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); 630 rect.bottom--; 631 } 632 // horizontal shadow line after top edge 633 if (rect.Height() >= 0) { 634 view->SetHighColor(shadow); 635 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 636 rect.top++; 637 } 638 // fill 639 if (rect.Height() >= 0) { 640 _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, 641 orientation); 642 } 643 } 644 } 645 646 647 void 648 BControlLook::DrawScrollViewFrame(BView* view, BRect& rect, 649 const BRect& updateRect, BRect verticalScrollBarFrame, 650 BRect horizontalScrollBarFrame, const rgb_color& base, 651 border_style border, uint32 flags, uint32 _borders) 652 { 653 // calculate scroll corner rect before messing with the "rect" 654 BRect scrollCornerFillRect(rect.right, rect.bottom, 655 rect.right, rect.bottom); 656 if (horizontalScrollBarFrame.IsValid()) 657 scrollCornerFillRect.left = horizontalScrollBarFrame.right + 1; 658 if (verticalScrollBarFrame.IsValid()) 659 scrollCornerFillRect.top = verticalScrollBarFrame.bottom + 1; 660 661 if (border == B_NO_BORDER) { 662 if (scrollCornerFillRect.IsValid()) { 663 view->SetHighColor(base); 664 view->FillRect(scrollCornerFillRect); 665 } 666 return; 667 } 668 669 bool excludeScrollCorner = border == B_FANCY_BORDER 670 && horizontalScrollBarFrame.IsValid() 671 && verticalScrollBarFrame.IsValid(); 672 673 uint32 borders = _borders; 674 if (excludeScrollCorner) { 675 rect.bottom = horizontalScrollBarFrame.top; 676 rect.right = verticalScrollBarFrame.left; 677 borders &= ~(B_RIGHT_BORDER | B_BOTTOM_BORDER); 678 } 679 680 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 681 682 if (border == B_FANCY_BORDER) 683 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 684 685 if ((flags & B_FOCUSED) != 0) { 686 rgb_color focusColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 687 _DrawFrame(view, rect, focusColor, focusColor, focusColor, focusColor, 688 borders); 689 } else { 690 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 691 scrollbarFrameColor, scrollbarFrameColor, borders); 692 } 693 694 if (excludeScrollCorner) { 695 horizontalScrollBarFrame.InsetBy(-1, -1); 696 // do not overdraw the top edge 697 horizontalScrollBarFrame.top += 2; 698 borders = _borders; 699 borders &= ~B_TOP_BORDER; 700 _DrawOuterResessedFrame(view, horizontalScrollBarFrame, base, 701 1.0, 1.0, flags, borders); 702 _DrawFrame(view, horizontalScrollBarFrame, scrollbarFrameColor, 703 scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, 704 borders); 705 706 707 verticalScrollBarFrame.InsetBy(-1, -1); 708 // do not overdraw the left edge 709 verticalScrollBarFrame.left += 2; 710 borders = _borders; 711 borders &= ~B_LEFT_BORDER; 712 _DrawOuterResessedFrame(view, verticalScrollBarFrame, base, 713 1.0, 1.0, flags, borders); 714 _DrawFrame(view, verticalScrollBarFrame, scrollbarFrameColor, 715 scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, 716 borders); 717 718 // exclude recessed frame 719 scrollCornerFillRect.top++; 720 scrollCornerFillRect.left++; 721 } 722 723 if (scrollCornerFillRect.IsValid()) { 724 view->SetHighColor(base); 725 view->FillRect(scrollCornerFillRect); 726 } 727 } 728 729 730 void 731 BControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, 732 const rgb_color& base, uint32 direction, uint32 flags, float tint) 733 { 734 BPoint tri1, tri2, tri3; 735 float hInset = rect.Width() / 3; 736 float vInset = rect.Height() / 3; 737 rect.InsetBy(hInset, vInset); 738 739 switch (direction) { 740 case B_LEFT_ARROW: 741 tri1.Set(rect.right, rect.top); 742 tri2.Set(rect.right - rect.Width() / 1.33, 743 (rect.top + rect.bottom + 1) /2 ); 744 tri3.Set(rect.right, rect.bottom + 1); 745 break; 746 case B_RIGHT_ARROW: 747 tri1.Set(rect.left, rect.bottom + 1); 748 tri2.Set(rect.left + rect.Width() / 1.33, 749 (rect.top + rect.bottom + 1) / 2); 750 tri3.Set(rect.left, rect.top); 751 break; 752 case B_UP_ARROW: 753 tri1.Set(rect.left, rect.bottom); 754 tri2.Set((rect.left + rect.right + 1) / 2, 755 rect.bottom - rect.Height() / 1.33); 756 tri3.Set(rect.right + 1, rect.bottom); 757 break; 758 case B_DOWN_ARROW: 759 default: 760 tri1.Set(rect.left, rect.top); 761 tri2.Set((rect.left + rect.right + 1) / 2, 762 rect.top + rect.Height() / 1.33); 763 tri3.Set(rect.right + 1, rect.top); 764 break; 765 } 766 // offset triangle if down 767 if ((flags & B_ACTIVATED) != 0) 768 view->MovePenTo(BPoint(1, 1)); 769 else 770 view->MovePenTo(BPoint(0, 0)); 771 772 BShape arrowShape; 773 arrowShape.MoveTo(tri1); 774 arrowShape.LineTo(tri2); 775 arrowShape.LineTo(tri3); 776 777 if ((flags & B_DISABLED) != 0) 778 tint = (tint + B_NO_TINT + B_NO_TINT) / 3; 779 780 view->SetHighColor(tint_color(base, tint)); 781 782 float penSize = view->PenSize(); 783 drawing_mode mode = view->DrawingMode(); 784 785 view->SetPenSize(ceilf(hInset / 2.0)); 786 view->SetDrawingMode(B_OP_OVER); 787 view->StrokeShape(&arrowShape); 788 789 view->SetPenSize(penSize); 790 view->SetDrawingMode(mode); 791 } 792 793 794 rgb_color 795 BControlLook::SliderBarColor(const rgb_color& base) 796 { 797 return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT); 798 } 799 800 801 void 802 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 803 const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, 804 float sliderScale, uint32 flags, enum orientation orientation) 805 { 806 if (!rect.IsValid() || !rect.Intersects(updateRect)) 807 return; 808 809 // save the clipping constraints of the view 810 view->PushState(); 811 812 // separate the bar in two sides 813 float sliderPosition; 814 BRect leftBarSide = rect; 815 BRect rightBarSide = rect; 816 817 if (orientation == B_HORIZONTAL) { 818 sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) 819 * sliderScale); 820 leftBarSide.right = sliderPosition - 1; 821 rightBarSide.left = sliderPosition; 822 } else { 823 // NOTE: position is reverse of coords 824 sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) 825 * (1.0 - sliderScale)); 826 leftBarSide.top = sliderPosition; 827 rightBarSide.bottom = sliderPosition - 1; 828 } 829 830 // fill the background for the corners, exclude the middle bar for now 831 BRegion region(rect); 832 region.Exclude(rightBarSide); 833 view->ConstrainClippingRegion(®ion); 834 835 view->PushState(); 836 837 DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, 838 orientation); 839 840 view->PopState(); 841 842 region.Set(rect); 843 region.Exclude(leftBarSide); 844 view->ConstrainClippingRegion(®ion); 845 846 view->PushState(); 847 848 DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, 849 orientation); 850 851 view->PopState(); 852 853 // restore the clipping constraints of the view 854 view->PopState(); 855 } 856 857 858 void 859 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 860 const rgb_color& base, rgb_color fillColor, uint32 flags, 861 enum orientation orientation) 862 { 863 if (!rect.IsValid() || !rect.Intersects(updateRect)) 864 return; 865 866 // separate the rect into corners 867 BRect leftCorner(rect); 868 BRect rightCorner(rect); 869 BRect barRect(rect); 870 871 if (orientation == B_HORIZONTAL) { 872 leftCorner.right = leftCorner.left + leftCorner.Height(); 873 rightCorner.left = rightCorner.right - rightCorner.Height(); 874 barRect.left += ceilf(barRect.Height() / 2); 875 barRect.right -= ceilf(barRect.Height() / 2); 876 } else { 877 leftCorner.bottom = leftCorner.top + leftCorner.Width(); 878 rightCorner.top = rightCorner.bottom - rightCorner.Width(); 879 barRect.top += ceilf(barRect.Width() / 2); 880 barRect.bottom -= ceilf(barRect.Width() / 2); 881 } 882 883 // fill the background for the corners, exclude the middle bar for now 884 BRegion region(rect); 885 region.Exclude(barRect); 886 view->ConstrainClippingRegion(®ion); 887 888 if ((flags & B_BLEND_FRAME) == 0) { 889 view->SetHighColor(base); 890 view->FillRect(rect); 891 } 892 893 // figure out the tints to be used 894 float edgeLightTint; 895 float edgeShadowTint; 896 float frameLightTint; 897 float frameShadowTint; 898 float fillLightTint; 899 float fillShadowTint; 900 uint8 edgeLightAlpha; 901 uint8 edgeShadowAlpha; 902 uint8 frameLightAlpha; 903 uint8 frameShadowAlpha; 904 905 if ((flags & B_DISABLED) != 0) { 906 edgeLightTint = 1.0; 907 edgeShadowTint = 1.0; 908 frameLightTint = 1.20; 909 frameShadowTint = 1.25; 910 fillLightTint = 0.9; 911 fillShadowTint = 1.05; 912 edgeLightAlpha = 12; 913 edgeShadowAlpha = 12; 914 frameLightAlpha = 40; 915 frameShadowAlpha = 45; 916 917 fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6); 918 fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6); 919 fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6); 920 } else { 921 edgeLightTint = 0.65; 922 edgeShadowTint = 1.07; 923 frameLightTint = 1.40; 924 frameShadowTint = 1.50; 925 fillLightTint = 0.8; 926 fillShadowTint = 1.1; 927 edgeLightAlpha = 15; 928 edgeShadowAlpha = 15; 929 frameLightAlpha = 92; 930 frameShadowAlpha = 107; 931 } 932 933 rgb_color edgeLightColor; 934 rgb_color edgeShadowColor; 935 rgb_color frameLightColor; 936 rgb_color frameShadowColor; 937 rgb_color fillLightColor = tint_color(fillColor, fillLightTint); 938 rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); 939 940 drawing_mode oldMode = view->DrawingMode(); 941 942 if ((flags & B_BLEND_FRAME) != 0) { 943 edgeLightColor = (rgb_color){ 255, 255, 255, edgeLightAlpha }; 944 edgeShadowColor = (rgb_color){ 0, 0, 0, edgeShadowAlpha }; 945 frameLightColor = (rgb_color){ 0, 0, 0, frameLightAlpha }; 946 frameShadowColor = (rgb_color){ 0, 0, 0, frameShadowAlpha }; 947 948 view->SetDrawingMode(B_OP_ALPHA); 949 } else { 950 edgeLightColor = tint_color(base, edgeLightTint); 951 edgeShadowColor = tint_color(base, edgeShadowTint); 952 frameLightColor = tint_color(fillColor, frameLightTint); 953 frameShadowColor = tint_color(fillColor, frameShadowTint); 954 } 955 956 if (orientation == B_HORIZONTAL) { 957 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 958 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 959 fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); 960 961 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 962 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 963 fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); 964 } else { 965 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 966 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 967 fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); 968 969 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 970 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 971 fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); 972 } 973 974 view->ConstrainClippingRegion(NULL); 975 976 view->BeginLineArray(4); 977 if (orientation == B_HORIZONTAL) { 978 view->AddLine(barRect.LeftTop(), barRect.RightTop(), edgeShadowColor); 979 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 980 edgeLightColor); 981 barRect.InsetBy(0, 1); 982 view->AddLine(barRect.LeftTop(), barRect.RightTop(), frameShadowColor); 983 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 984 frameLightColor); 985 barRect.InsetBy(0, 1); 986 } else { 987 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), edgeShadowColor); 988 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 989 edgeLightColor); 990 barRect.InsetBy(1, 0); 991 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), frameShadowColor); 992 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 993 frameLightColor); 994 barRect.InsetBy(1, 0); 995 } 996 view->EndLineArray(); 997 998 view->SetDrawingMode(oldMode); 999 1000 _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, 1001 orientation); 1002 } 1003 1004 1005 void 1006 BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, 1007 const rgb_color& base, uint32 flags, enum orientation orientation) 1008 { 1009 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1010 return; 1011 1012 // figure out frame color 1013 rgb_color frameLightColor; 1014 rgb_color frameShadowColor; 1015 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1016 1017 if ((flags & B_FOCUSED) != 0) { 1018 // focused 1019 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1020 frameShadowColor = frameLightColor; 1021 } else { 1022 // figure out the tints to be used 1023 float frameLightTint; 1024 float frameShadowTint; 1025 1026 if ((flags & B_DISABLED) != 0) { 1027 frameLightTint = 1.30; 1028 frameShadowTint = 1.35; 1029 shadowColor.alpha = 30; 1030 } else { 1031 frameLightTint = 1.6; 1032 frameShadowTint = 1.65; 1033 } 1034 1035 frameLightColor = tint_color(base, frameLightTint); 1036 frameShadowColor = tint_color(base, frameShadowTint); 1037 } 1038 1039 BRect originalRect(rect); 1040 rect.right--; 1041 rect.bottom--; 1042 1043 _DrawFrame(view, rect, frameLightColor, frameLightColor, 1044 frameShadowColor, frameShadowColor); 1045 1046 flags &= ~B_ACTIVATED; 1047 DrawButtonBackground(view, rect, updateRect, base, flags); 1048 1049 // thumb shadow 1050 view->SetDrawingMode(B_OP_ALPHA); 1051 view->SetHighColor(shadowColor); 1052 originalRect.left++; 1053 originalRect.top++; 1054 view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom()); 1055 originalRect.bottom--; 1056 view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom()); 1057 1058 // thumb edge 1059 if (orientation == B_HORIZONTAL) { 1060 rect.InsetBy(0, floorf(rect.Height() / 4)); 1061 rect.left = floorf((rect.left + rect.right) / 2); 1062 rect.right = rect.left + 1; 1063 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1064 shadowColor.alpha = 128; 1065 view->SetHighColor(shadowColor); 1066 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 1067 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1068 lightColor.alpha = 128; 1069 view->SetHighColor(lightColor); 1070 view->StrokeLine(rect.RightTop(), rect.RightBottom()); 1071 } else { 1072 rect.InsetBy(floorf(rect.Width() / 4), 0); 1073 rect.top = floorf((rect.top + rect.bottom) / 2); 1074 rect.bottom = rect.top + 1; 1075 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1076 shadowColor.alpha = 128; 1077 view->SetHighColor(shadowColor); 1078 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 1079 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1080 lightColor.alpha = 128; 1081 view->SetHighColor(lightColor); 1082 view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); 1083 } 1084 1085 view->SetDrawingMode(B_OP_COPY); 1086 } 1087 1088 1089 void 1090 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1091 const BRect& updateRect, const rgb_color& base, uint32 flags, 1092 enum orientation orientation) 1093 { 1094 DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); 1095 } 1096 1097 1098 void 1099 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1100 const BRect& updateRect, const rgb_color& base, const rgb_color& fill, 1101 uint32 flags, enum orientation orientation) 1102 { 1103 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1104 return; 1105 1106 // figure out frame color 1107 rgb_color frameLightColor; 1108 rgb_color frameShadowColor; 1109 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1110 1111 float topTint = 0.49; 1112 float middleTint1 = 0.62; 1113 float middleTint2 = 0.76; 1114 float bottomTint = 0.90; 1115 1116 if ((flags & B_DISABLED) != 0) { 1117 topTint = (topTint + B_NO_TINT) / 2; 1118 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 1119 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 1120 bottomTint = (bottomTint + B_NO_TINT) / 2; 1121 } else if ((flags & B_HOVER) != 0) { 1122 static const float kHoverTintFactor = 0.85; 1123 topTint *= kHoverTintFactor; 1124 middleTint1 *= kHoverTintFactor; 1125 middleTint2 *= kHoverTintFactor; 1126 bottomTint *= kHoverTintFactor; 1127 } 1128 1129 if ((flags & B_FOCUSED) != 0) { 1130 // focused 1131 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1132 frameShadowColor = frameLightColor; 1133 } else { 1134 // figure out the tints to be used 1135 float frameLightTint; 1136 float frameShadowTint; 1137 1138 if ((flags & B_DISABLED) != 0) { 1139 frameLightTint = 1.30; 1140 frameShadowTint = 1.35; 1141 shadowColor.alpha = 30; 1142 } else { 1143 frameLightTint = 1.6; 1144 frameShadowTint = 1.65; 1145 } 1146 1147 frameLightColor = tint_color(base, frameLightTint); 1148 frameShadowColor = tint_color(base, frameShadowTint); 1149 } 1150 1151 // make room for the shadow 1152 rect.right--; 1153 rect.bottom--; 1154 1155 uint32 viewFlags = view->Flags(); 1156 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 1157 view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); 1158 1159 float centerh = (rect.left + rect.right) / 2; 1160 float centerv = (rect.top + rect.bottom) / 2; 1161 1162 BShape shape; 1163 if (orientation == B_HORIZONTAL) { 1164 shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5)); 1165 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); 1166 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5)); 1167 shape.LineTo(BPoint(centerh + 0.5, rect.top + 0.5)); 1168 shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); 1169 } else { 1170 shape.MoveTo(BPoint(rect.right + 0.5, rect.top + 0.5)); 1171 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); 1172 shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.bottom + 0.5)); 1173 shape.LineTo(BPoint(rect.left + 0.5, centerv + 0.5)); 1174 shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.top + 0.5)); 1175 } 1176 shape.Close(); 1177 1178 view->MovePenTo(BPoint(1, 1)); 1179 1180 view->SetDrawingMode(B_OP_ALPHA); 1181 view->SetHighColor(shadowColor); 1182 view->StrokeShape(&shape); 1183 1184 view->MovePenTo(B_ORIGIN); 1185 1186 view->SetDrawingMode(B_OP_COPY); 1187 view->SetHighColor(frameLightColor); 1188 view->StrokeShape(&shape); 1189 1190 rect.InsetBy(1, 1); 1191 shape.Clear(); 1192 if (orientation == B_HORIZONTAL) { 1193 shape.MoveTo(BPoint(rect.left, rect.bottom + 1)); 1194 shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); 1195 shape.LineTo(BPoint(centerh + 0.5, rect.top)); 1196 } else { 1197 shape.MoveTo(BPoint(rect.right + 1, rect.top)); 1198 shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); 1199 shape.LineTo(BPoint(rect.left, centerv + 0.5)); 1200 } 1201 shape.Close(); 1202 1203 BGradientLinear gradient; 1204 if ((flags & B_DISABLED) != 0) { 1205 _MakeGradient(gradient, rect, fill, topTint, bottomTint); 1206 } else { 1207 _MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1, 1208 middleTint2, bottomTint); 1209 } 1210 1211 view->FillShape(&shape, gradient); 1212 1213 view->SetFlags(viewFlags); 1214 } 1215 1216 1217 void 1218 BControlLook::DrawSliderHashMarks(BView* view, BRect& rect, 1219 const BRect& updateRect, const rgb_color& base, int32 count, 1220 hash_mark_location location, uint32 flags, enum orientation orientation) 1221 { 1222 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1223 return; 1224 1225 rgb_color lightColor; 1226 rgb_color darkColor; 1227 1228 if ((flags & B_DISABLED) != 0) { 1229 lightColor = tint_color(base, 0.9); 1230 darkColor = tint_color(base, 1.07); 1231 } else { 1232 lightColor = tint_color(base, 0.8); 1233 darkColor = tint_color(base, 1.14); 1234 } 1235 1236 int32 hashMarkCount = max_c(count, 2); 1237 // draw at least two hashmarks at min/max if 1238 // fHashMarks != B_HASH_MARKS_NONE 1239 float factor; 1240 float startPos; 1241 if (orientation == B_HORIZONTAL) { 1242 factor = (rect.Width() - 2) / (hashMarkCount - 1); 1243 startPos = rect.left + 1; 1244 } else { 1245 factor = (rect.Height() - 2) / (hashMarkCount - 1); 1246 startPos = rect.top + 1; 1247 } 1248 1249 if (location & B_HASH_MARKS_TOP) { 1250 view->BeginLineArray(hashMarkCount * 2); 1251 1252 if (orientation == B_HORIZONTAL) { 1253 float pos = startPos; 1254 for (int32 i = 0; i < hashMarkCount; i++) { 1255 view->AddLine(BPoint(pos, rect.top), 1256 BPoint(pos, rect.top + 4), darkColor); 1257 view->AddLine(BPoint(pos + 1, rect.top), 1258 BPoint(pos + 1, rect.top + 4), lightColor); 1259 1260 pos += factor; 1261 } 1262 } else { 1263 float pos = startPos; 1264 for (int32 i = 0; i < hashMarkCount; i++) { 1265 view->AddLine(BPoint(rect.left, pos), 1266 BPoint(rect.left + 4, pos), darkColor); 1267 view->AddLine(BPoint(rect.left, pos + 1), 1268 BPoint(rect.left + 4, pos + 1), lightColor); 1269 1270 pos += factor; 1271 } 1272 } 1273 1274 view->EndLineArray(); 1275 } 1276 1277 if (location & B_HASH_MARKS_BOTTOM) { 1278 1279 view->BeginLineArray(hashMarkCount * 2); 1280 1281 if (orientation == B_HORIZONTAL) { 1282 float pos = startPos; 1283 for (int32 i = 0; i < hashMarkCount; i++) { 1284 view->AddLine(BPoint(pos, rect.bottom - 4), 1285 BPoint(pos, rect.bottom), darkColor); 1286 view->AddLine(BPoint(pos + 1, rect.bottom - 4), 1287 BPoint(pos + 1, rect.bottom), lightColor); 1288 1289 pos += factor; 1290 } 1291 } else { 1292 float pos = startPos; 1293 for (int32 i = 0; i < hashMarkCount; i++) { 1294 view->AddLine(BPoint(rect.right - 4, pos), 1295 BPoint(rect.right, pos), darkColor); 1296 view->AddLine(BPoint(rect.right - 4, pos + 1), 1297 BPoint(rect.right, pos + 1), lightColor); 1298 1299 pos += factor; 1300 } 1301 } 1302 1303 view->EndLineArray(); 1304 } 1305 } 1306 1307 1308 void 1309 BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, 1310 const rgb_color& base, uint32 flags, uint32 borders) 1311 { 1312 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1313 return; 1314 1315 // save the clipping constraints of the view 1316 view->PushState(); 1317 1318 // set clipping constraints to updateRect 1319 BRegion clipping(updateRect); 1320 view->ConstrainClippingRegion(&clipping); 1321 1322 rgb_color edgeShadowColor; 1323 rgb_color edgeLightColor; 1324 rgb_color frameShadowColor; 1325 rgb_color frameLightColor; 1326 rgb_color bevelShadowColor; 1327 rgb_color bevelLightColor; 1328 BGradientLinear fillGradient; 1329 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1330 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1331 1332 if ((flags & B_DISABLED) != 0) { 1333 edgeLightColor = base; 1334 edgeShadowColor = base; 1335 frameLightColor = tint_color(base, 1.25); 1336 frameShadowColor = tint_color(base, 1.30); 1337 bevelLightColor = tint_color(base, 0.8); 1338 bevelShadowColor = tint_color(base, 1.07); 1339 fillGradient.AddColor(tint_color(base, 0.85), 0); 1340 fillGradient.AddColor(base, 255); 1341 } else { 1342 edgeLightColor = tint_color(base, 0.80); 1343 edgeShadowColor = tint_color(base, 1.03); 1344 frameLightColor = tint_color(base, 1.30); 1345 frameShadowColor = tint_color(base, 1.30); 1346 bevelLightColor = tint_color(base, 0.6); 1347 bevelShadowColor = tint_color(base, 1.07); 1348 fillGradient.AddColor(tint_color(base, 0.75), 0); 1349 fillGradient.AddColor(tint_color(base, 1.03), 255); 1350 } 1351 1352 static const float kRoundCornerRadius = 4.0f; 1353 1354 // left top corner dimensions 1355 BRect leftTopCorner(rect); 1356 leftTopCorner.right = floorf(leftTopCorner.left + kRoundCornerRadius); 1357 leftTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); 1358 clipping.Exclude(leftTopCorner); 1359 1360 // draw the left top corner 1361 _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, 1362 edgeShadowColor, frameLightColor, bevelLightColor, 1363 fillGradient); 1364 1365 // right top corner dimensions 1366 BRect rightTopCorner(rect); 1367 rightTopCorner.right = floorf(rect.right); 1368 rightTopCorner.left = floorf(rightTopCorner.right - kRoundCornerRadius); 1369 rightTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); 1370 clipping.Exclude(rightTopCorner); 1371 1372 // draw the right top corner 1373 _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, 1374 edgeShadowColor, edgeLightColor, frameLightColor, 1375 frameShadowColor, bevelLightColor, bevelShadowColor, 1376 fillGradient); 1377 1378 // clip out the corners 1379 view->ConstrainClippingRegion(&clipping); 1380 1381 // draw the rest of frame and fill 1382 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1383 edgeLightColor, 1384 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1385 if ((borders & B_LEFT_BORDER) == 0) 1386 rect.left++; 1387 if ((borders & B_RIGHT_BORDER) == 0) 1388 rect.right--; 1389 1390 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1391 frameShadowColor, B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); 1392 1393 _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, 1394 bevelShadowColor); 1395 1396 view->FillRect(rect, fillGradient); 1397 1398 // restore the clipping constraints of the view 1399 view->PopState(); 1400 } 1401 1402 1403 void 1404 BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, 1405 const rgb_color& base, uint32 flags, uint32 borders) 1406 { 1407 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1408 return; 1409 1410 rgb_color edgeShadowColor; 1411 rgb_color edgeLightColor; 1412 rgb_color frameShadowColor; 1413 rgb_color frameLightColor; 1414 rgb_color bevelShadowColor; 1415 rgb_color bevelLightColor; 1416 BGradientLinear fillGradient; 1417 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1418 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1419 1420 if ((flags & B_DISABLED) != 0) { 1421 edgeLightColor = base; 1422 edgeShadowColor = base; 1423 frameLightColor = tint_color(base, 1.25); 1424 frameShadowColor = tint_color(base, 1.30); 1425 bevelLightColor = tint_color(base, 0.8); 1426 bevelShadowColor = tint_color(base, 1.07); 1427 fillGradient.AddColor(tint_color(base, 0.85), 0); 1428 fillGradient.AddColor(base, 255); 1429 } else { 1430 edgeLightColor = tint_color(base, 0.80); 1431 edgeShadowColor = tint_color(base, 1.03); 1432 frameLightColor = tint_color(base, 1.30); 1433 frameShadowColor = tint_color(base, 1.30); 1434 bevelLightColor = tint_color(base, 1.10); 1435 bevelShadowColor = tint_color(base, 1.17); 1436 fillGradient.AddColor(tint_color(base, 1.12), 0); 1437 fillGradient.AddColor(tint_color(base, 1.08), 255); 1438 } 1439 1440 // active tabs stand out at the top, but this is an inactive tab 1441 view->SetHighColor(base); 1442 view->FillRect(BRect(rect.left, rect.top, rect.right, rect.top + 4)); 1443 rect.top += 4; 1444 1445 // frame and fill 1446 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1447 edgeLightColor, 1448 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1449 1450 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1451 frameShadowColor, 1452 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1453 1454 if (rect.IsValid()) { 1455 _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, 1456 bevelLightColor, bevelLightColor, B_LEFT_BORDER & ~borders); 1457 } else { 1458 if ((B_LEFT_BORDER & ~borders) != 0) 1459 rect.left++; 1460 } 1461 1462 view->FillRect(rect, fillGradient); 1463 } 1464 1465 1466 void 1467 BControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, 1468 const rgb_color& base, enum orientation orientation, uint32 flags, 1469 uint32 borders) 1470 { 1471 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1472 return; 1473 1474 rgb_color background; 1475 if ((flags & (B_CLICKED | B_ACTIVATED)) != 0) 1476 background = tint_color(base, B_DARKEN_1_TINT); 1477 else 1478 background = base; 1479 1480 rgb_color light = tint_color(background, 0.6); 1481 rgb_color shadow = tint_color(background, 1.21); 1482 1483 // frame 1484 if (borders != 0 && rect.Width() > 3 && rect.Height() > 3) 1485 DrawRaisedBorder(view, rect, updateRect, background, flags, borders); 1486 1487 // dots and rest of background 1488 if (orientation == B_HORIZONTAL) { 1489 if (rect.Width() > 2) { 1490 // background on left/right 1491 BRegion region(rect); 1492 rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5); 1493 rect.right = rect.left + 1; 1494 region.Exclude(rect); 1495 view->SetHighColor(background); 1496 view->FillRegion(®ion); 1497 } 1498 1499 BPoint dot = rect.LeftTop(); 1500 BPoint stop = rect.LeftBottom(); 1501 int32 num = 1; 1502 while (dot.y <= stop.y) { 1503 rgb_color col1; 1504 rgb_color col2; 1505 switch (num) { 1506 case 1: 1507 col1 = background; 1508 col2 = background; 1509 break; 1510 case 2: 1511 col1 = shadow; 1512 col2 = background; 1513 break; 1514 case 3: 1515 default: 1516 col1 = background; 1517 col2 = light; 1518 num = 0; 1519 break; 1520 } 1521 view->SetHighColor(col1); 1522 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1523 view->SetHighColor(col2); 1524 dot.x++; 1525 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1526 dot.x -= 1.0; 1527 // next pixel 1528 num++; 1529 dot.y++; 1530 } 1531 } else { 1532 if (rect.Height() > 2) { 1533 // background on left/right 1534 BRegion region(rect); 1535 rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5); 1536 rect.bottom = rect.top + 1; 1537 region.Exclude(rect); 1538 view->SetHighColor(background); 1539 view->FillRegion(®ion); 1540 } 1541 1542 BPoint dot = rect.LeftTop(); 1543 BPoint stop = rect.RightTop(); 1544 int32 num = 1; 1545 while (dot.x <= stop.x) { 1546 rgb_color col1; 1547 rgb_color col2; 1548 switch (num) { 1549 case 1: 1550 col1 = background; 1551 col2 = background; 1552 break; 1553 case 2: 1554 col1 = shadow; 1555 col2 = background; 1556 break; 1557 case 3: 1558 default: 1559 col1 = background; 1560 col2 = light; 1561 num = 0; 1562 break; 1563 } 1564 view->SetHighColor(col1); 1565 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1566 view->SetHighColor(col2); 1567 dot.y++; 1568 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1569 dot.y -= 1.0; 1570 // next pixel 1571 num++; 1572 dot.x++; 1573 } 1574 } 1575 } 1576 1577 1578 // #pragma mark - 1579 1580 1581 void 1582 BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, 1583 const rgb_color& base, border_style border, uint32 flags, uint32 borders) 1584 { 1585 if (border == B_NO_BORDER) 1586 return; 1587 1588 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 1589 if ((flags & B_FOCUSED) != 0) 1590 scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1591 1592 if (border == B_FANCY_BORDER) 1593 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 1594 1595 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 1596 scrollbarFrameColor, scrollbarFrameColor, borders); 1597 } 1598 1599 1600 void 1601 BControlLook::DrawRaisedBorder(BView* view, BRect& rect, 1602 const BRect& updateRect, const rgb_color& base, uint32 flags, 1603 uint32 borders) 1604 { 1605 rgb_color lightColor; 1606 rgb_color shadowColor; 1607 1608 if ((flags & B_DISABLED) != 0) { 1609 lightColor = base; 1610 shadowColor = base; 1611 } else { 1612 lightColor = tint_color(base, 0.85); 1613 shadowColor = tint_color(base, 1.07); 1614 } 1615 1616 _DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor, 1617 borders); 1618 } 1619 1620 1621 void 1622 BControlLook::DrawTextControlBorder(BView* view, BRect& rect, 1623 const BRect& updateRect, const rgb_color& base, uint32 flags, 1624 uint32 borders) 1625 { 1626 if (!rect.Intersects(updateRect)) 1627 return; 1628 1629 rgb_color dark1BorderColor; 1630 rgb_color dark2BorderColor; 1631 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1632 1633 if ((flags & B_DISABLED) != 0) { 1634 _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders); 1635 1636 if ((flags & B_BLEND_FRAME) != 0) 1637 dark1BorderColor = (rgb_color){ 0, 0, 0, 40 }; 1638 else 1639 dark1BorderColor = tint_color(base, 1.15); 1640 dark2BorderColor = dark1BorderColor; 1641 } else if ((flags & B_CLICKED) != 0) { 1642 dark1BorderColor = tint_color(base, 1.50); 1643 dark2BorderColor = tint_color(base, 1.49); 1644 1645 // BCheckBox uses this to indicate the clicked state... 1646 _DrawFrame(view, rect, 1647 dark1BorderColor, dark1BorderColor, 1648 dark2BorderColor, dark2BorderColor); 1649 1650 dark2BorderColor = dark1BorderColor; 1651 } else { 1652 _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders); 1653 1654 if ((flags & B_BLEND_FRAME) != 0) { 1655 dark1BorderColor = (rgb_color){ 0, 0, 0, 102 }; 1656 dark2BorderColor = (rgb_color){ 0, 0, 0, 97 }; 1657 } else { 1658 dark1BorderColor = tint_color(base, 1.40); 1659 dark2BorderColor = tint_color(base, 1.38); 1660 } 1661 } 1662 1663 if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED) != 0) { 1664 dark1BorderColor = navigationColor; 1665 dark2BorderColor = navigationColor; 1666 } 1667 1668 if ((flags & B_BLEND_FRAME) != 0) { 1669 drawing_mode oldMode = view->DrawingMode(); 1670 view->SetDrawingMode(B_OP_ALPHA); 1671 1672 _DrawFrame(view, rect, 1673 dark1BorderColor, dark1BorderColor, 1674 dark2BorderColor, dark2BorderColor, borders); 1675 1676 view->SetDrawingMode(oldMode); 1677 } else { 1678 _DrawFrame(view, rect, 1679 dark1BorderColor, dark1BorderColor, 1680 dark2BorderColor, dark2BorderColor, borders); 1681 } 1682 } 1683 1684 1685 void 1686 BControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, 1687 const rgb_color& base, uint32 borders) 1688 { 1689 rgb_color frameColor = tint_color(base, 1.30); 1690 rgb_color bevelLight = tint_color(base, 0.8); 1691 rgb_color bevelShadow = tint_color(base, 1.03); 1692 1693 _DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight, 1694 borders); 1695 1696 _DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor, 1697 borders); 1698 1699 _DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow, 1700 borders); 1701 } 1702 1703 1704 void 1705 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1706 const BRect& updateRect, const rgb_color& base, uint32 flags) 1707 { 1708 DrawLabel(view, label, rect, updateRect, base, flags, 1709 DefaultLabelAlignment()); 1710 } 1711 1712 1713 void 1714 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1715 const BRect& updateRect, const rgb_color& base, uint32 flags, 1716 const BAlignment& alignment) 1717 { 1718 if (!rect.Intersects(updateRect)) 1719 return; 1720 1721 // truncate the label if necessary and get the width and height 1722 BString truncatedLabel(label); 1723 1724 BFont font; 1725 view->GetFont(&font); 1726 1727 float width = rect.Width(); 1728 font.TruncateString(&truncatedLabel, B_TRUNCATE_END, width); 1729 width = font.StringWidth(truncatedLabel.String()); 1730 1731 font_height fontHeight; 1732 font.GetHeight(&fontHeight); 1733 float height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); 1734 1735 // handle alignment 1736 BPoint location; 1737 1738 switch (alignment.horizontal) { 1739 default: 1740 case B_ALIGN_LEFT: 1741 location.x = rect.left; 1742 break; 1743 case B_ALIGN_RIGHT: 1744 location.x = rect.right - width; 1745 break; 1746 case B_ALIGN_CENTER: 1747 location.x = (rect.left + rect.right - width) / 2.0f; 1748 break; 1749 } 1750 1751 switch (alignment.vertical) { 1752 case B_ALIGN_TOP: 1753 location.y = rect.top + ceilf(fontHeight.ascent); 1754 break; 1755 default: 1756 case B_ALIGN_MIDDLE: 1757 location.y = floorf((rect.top + rect.bottom - height) / 2.0f + 0.5f) 1758 + ceilf(fontHeight.ascent); 1759 break; 1760 case B_ALIGN_BOTTOM: 1761 location.y = rect.bottom - ceilf(fontHeight.descent); 1762 break; 1763 } 1764 1765 DrawLabel(view, truncatedLabel.String(), base, flags, location); 1766 } 1767 1768 1769 void 1770 BControlLook::DrawLabel(BView* view, const char* label, const rgb_color& base, 1771 uint32 flags, const BPoint& where) 1772 { 1773 // setup the text color 1774 // TODO: Should either use the ui_color(B_CONTROL_TEXT_COLOR) here, 1775 // or elliminate that constant alltogether (stippi: +1). 1776 1777 BWindow* window = view->Window(); 1778 bool isDesktop = window 1779 && window->Feel() == kPrivateDesktopWindowFeel 1780 && window->Look() == kPrivateDesktopWindowLook 1781 && view->Parent() 1782 && view->Parent()->Parent() == NULL 1783 && (flags & B_IGNORE_OUTLINE) == 0; 1784 1785 rgb_color low; 1786 rgb_color color; 1787 rgb_color glowColor; 1788 1789 if (isDesktop) 1790 low = view->Parent()->ViewColor(); 1791 else 1792 low = base; 1793 1794 if (low.red + low.green + low.blue > 128 * 3) { 1795 color = tint_color(low, B_DARKEN_MAX_TINT); 1796 glowColor = kWhite; 1797 } else { 1798 color = tint_color(low, B_LIGHTEN_MAX_TINT); 1799 glowColor = kBlack; 1800 } 1801 1802 if ((flags & B_DISABLED) != 0) { 1803 color.red = (uint8)(((int32)low.red + color.red + 1) / 2); 1804 color.green = (uint8)(((int32)low.green + color.green + 1) / 2); 1805 color.blue = (uint8)(((int32)low.blue + color.blue + 1) / 2); 1806 } 1807 1808 drawing_mode oldMode = view->DrawingMode(); 1809 1810 if (isDesktop) { 1811 // drawing occurs on the desktop 1812 if (fCachedWorkspace != current_workspace()) { 1813 int8 indice = 0; 1814 int32 mask; 1815 bool tmpOutline; 1816 while (fBackgroundInfo.FindInt32("be:bgndimginfoworkspaces", 1817 indice, &mask) == B_OK 1818 && fBackgroundInfo.FindBool("be:bgndimginfoerasetext", 1819 indice, &tmpOutline) == B_OK) { 1820 1821 if (((1 << current_workspace()) & mask) != 0) { 1822 fCachedOutline = tmpOutline; 1823 fCachedWorkspace = current_workspace(); 1824 break; 1825 } 1826 indice++; 1827 } 1828 } 1829 1830 if (fCachedOutline) { 1831 BFont font; 1832 view->GetFont(&font); 1833 1834 view->SetDrawingMode(B_OP_ALPHA); 1835 view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); 1836 // Draw glow or outline 1837 if (glowColor == kWhite) { 1838 font.SetFalseBoldWidth(2.0); 1839 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1840 1841 glowColor.alpha = 30; 1842 view->SetHighColor(glowColor); 1843 view->DrawString(label, where); 1844 1845 font.SetFalseBoldWidth(1.0); 1846 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1847 1848 glowColor.alpha = 65; 1849 view->SetHighColor(glowColor); 1850 view->DrawString(label, where); 1851 1852 font.SetFalseBoldWidth(0.0); 1853 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1854 } else if (glowColor == kBlack) { 1855 font.SetFalseBoldWidth(1.0); 1856 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1857 1858 glowColor.alpha = 30; 1859 view->SetHighColor(glowColor); 1860 view->DrawString(label, where); 1861 1862 font.SetFalseBoldWidth(0.0); 1863 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1864 1865 glowColor.alpha = 200; 1866 view->SetHighColor(glowColor); 1867 view->DrawString(label, BPoint(where.x + 1, where.y + 1)); 1868 } 1869 } 1870 } 1871 1872 view->SetHighColor(color); 1873 view->SetDrawingMode(B_OP_OVER); 1874 view->DrawString(label, where); 1875 view->SetDrawingMode(oldMode); 1876 } 1877 1878 1879 void 1880 BControlLook::SetBackgroundInfo(const BMessage& backgroundInfo) 1881 { 1882 fBackgroundInfo = backgroundInfo; 1883 fCachedWorkspace = -1; 1884 } 1885 1886 1887 // #pragma mark - 1888 1889 1890 void 1891 BControlLook::_DrawButtonFrame(BView* view, BRect& rect, 1892 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 1893 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 1894 const rgb_color& background, float contrast, float brightness, 1895 uint32 flags, uint32 borders) 1896 { 1897 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1898 return; 1899 1900 // save the clipping constraints of the view 1901 view->PushState(); 1902 1903 // set clipping constraints to updateRect 1904 BRegion clipping(updateRect); 1905 view->ConstrainClippingRegion(&clipping); 1906 1907 // outer edge colors 1908 rgb_color edgeLightColor; 1909 rgb_color edgeShadowColor; 1910 1911 // default button frame color 1912 // TODO: B_BLEND_FRAME 1913 float defaultIndicatorTint = 1.2; 1914 if ((flags & B_DISABLED) != 0) 1915 defaultIndicatorTint = (B_NO_TINT + defaultIndicatorTint) / 2; 1916 1917 rgb_color defaultIndicatorColor = tint_color(base, defaultIndicatorTint); 1918 rgb_color cornerBgColor; 1919 1920 drawing_mode oldMode = view->DrawingMode(); 1921 1922 if ((flags & B_DEFAULT_BUTTON) != 0) { 1923 cornerBgColor = defaultIndicatorColor; 1924 edgeLightColor = _EdgeLightColor(defaultIndicatorColor, 1925 contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), 1926 brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); 1927 edgeShadowColor = _EdgeShadowColor(defaultIndicatorColor, 1928 contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), 1929 brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); 1930 1931 // draw default button indicator 1932 view->SetHighColor(background); 1933 view->FillRect(rect); 1934 view->SetHighColor(base); 1935 view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); 1936 rect.InsetBy(1, 1); 1937 1938 view->SetHighColor(defaultIndicatorColor); 1939 view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); 1940 rect.InsetBy(1, 1); 1941 1942 view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); 1943 rect.InsetBy(1, 1); 1944 } else { 1945 cornerBgColor = background; 1946 if ((flags & B_BLEND_FRAME) != 0) { 1947 // set the background color to transparent for the case 1948 // that we are on the desktop 1949 cornerBgColor.alpha = 0; 1950 view->SetDrawingMode(B_OP_ALPHA); 1951 } 1952 1953 edgeLightColor = _EdgeLightColor(background, 1954 contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), 1955 brightness * 1.0, flags); 1956 edgeShadowColor = _EdgeShadowColor(background, 1957 contrast * (flags & B_DISABLED) != 0 ? 0.0 : 1.0, 1958 brightness * 1.0, flags); 1959 } 1960 1961 // frame colors 1962 rgb_color frameLightColor = _FrameLightColor(base, flags); 1963 rgb_color frameShadowColor = _FrameShadowColor(base, flags); 1964 1965 // rounded corners 1966 1967 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 1968 && leftTopRadius > 0) { 1969 // draw left top rounded corner 1970 BRect leftTopCorner(floorf(rect.left), floorf(rect.top), 1971 floorf(rect.left + leftTopRadius), 1972 floorf(rect.top + leftTopRadius)); 1973 clipping.Exclude(leftTopCorner); 1974 _DrawRoundCornerFrameLeftTop(view, leftTopCorner, updateRect, 1975 cornerBgColor, edgeShadowColor, frameLightColor); 1976 } 1977 1978 if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 1979 && rightTopRadius > 0) { 1980 // draw right top rounded corner 1981 BRect rightTopCorner(floorf(rect.right - rightTopRadius), 1982 floorf(rect.top), floorf(rect.right), 1983 floorf(rect.top + rightTopRadius)); 1984 clipping.Exclude(rightTopCorner); 1985 _DrawRoundCornerFrameRightTop(view, rightTopCorner, updateRect, 1986 cornerBgColor, edgeShadowColor, edgeLightColor, 1987 frameLightColor, frameShadowColor); 1988 } 1989 1990 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 1991 && leftBottomRadius > 0) { 1992 // draw left bottom rounded corner 1993 BRect leftBottomCorner(floorf(rect.left), 1994 floorf(rect.bottom - leftBottomRadius), 1995 floorf(rect.left + leftBottomRadius), floorf(rect.bottom)); 1996 clipping.Exclude(leftBottomCorner); 1997 _DrawRoundCornerFrameLeftBottom(view, leftBottomCorner, updateRect, 1998 cornerBgColor, edgeShadowColor, edgeLightColor, 1999 frameLightColor, frameShadowColor); 2000 } 2001 2002 if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2003 && rightBottomRadius > 0) { 2004 // draw right bottom rounded corner 2005 BRect rightBottomCorner(floorf(rect.right - rightBottomRadius), 2006 floorf(rect.bottom - rightBottomRadius), floorf(rect.right), 2007 floorf(rect.bottom)); 2008 clipping.Exclude(rightBottomCorner); 2009 _DrawRoundCornerFrameRightBottom(view, rightBottomCorner, 2010 updateRect, cornerBgColor, edgeLightColor, frameShadowColor); 2011 } 2012 2013 // clip out the corners 2014 view->ConstrainClippingRegion(&clipping); 2015 2016 // draw outer edge 2017 if ((flags & B_DEFAULT_BUTTON) != 0) { 2018 _DrawOuterResessedFrame(view, rect, defaultIndicatorColor, 2019 contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), 2020 brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), 2021 flags, borders); 2022 } else { 2023 _DrawOuterResessedFrame(view, rect, background, 2024 contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), 2025 brightness * 1.0, flags, borders); 2026 } 2027 2028 view->SetDrawingMode(oldMode); 2029 2030 // draw frame 2031 if ((flags & B_BLEND_FRAME) != 0) { 2032 drawing_mode oldDrawingMode = view->DrawingMode(); 2033 view->SetDrawingMode(B_OP_ALPHA); 2034 2035 _DrawFrame(view, rect, frameLightColor, frameLightColor, 2036 frameShadowColor, frameShadowColor, borders); 2037 2038 view->SetDrawingMode(oldDrawingMode); 2039 } else { 2040 _DrawFrame(view, rect, frameLightColor, frameLightColor, 2041 frameShadowColor, frameShadowColor, borders); 2042 } 2043 2044 // restore the clipping constraints of the view 2045 view->PopState(); 2046 } 2047 2048 2049 void 2050 BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, 2051 const rgb_color& base, float contrast, float brightness, uint32 flags, 2052 uint32 borders) 2053 { 2054 rgb_color edgeLightColor = _EdgeLightColor(base, contrast, 2055 brightness, flags); 2056 rgb_color edgeShadowColor = _EdgeShadowColor(base, contrast, 2057 brightness, flags); 2058 2059 if ((flags & B_BLEND_FRAME) != 0) { 2060 // assumes the background has already been painted 2061 drawing_mode oldDrawingMode = view->DrawingMode(); 2062 view->SetDrawingMode(B_OP_ALPHA); 2063 2064 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, 2065 edgeLightColor, edgeLightColor, borders); 2066 2067 view->SetDrawingMode(oldDrawingMode); 2068 } else { 2069 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, 2070 edgeLightColor, edgeLightColor, borders); 2071 } 2072 } 2073 2074 2075 void 2076 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 2077 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 2078 uint32 borders) 2079 { 2080 view->BeginLineArray(4); 2081 2082 if (borders & B_LEFT_BORDER) { 2083 view->AddLine( 2084 BPoint(rect.left, rect.bottom), 2085 BPoint(rect.left, rect.top), left); 2086 rect.left++; 2087 } 2088 if (borders & B_TOP_BORDER) { 2089 view->AddLine( 2090 BPoint(rect.left, rect.top), 2091 BPoint(rect.right, rect.top), top); 2092 rect.top++; 2093 } 2094 if (borders & B_RIGHT_BORDER) { 2095 view->AddLine( 2096 BPoint(rect.right, rect.top), 2097 BPoint(rect.right, rect.bottom), right); 2098 rect.right--; 2099 } 2100 if (borders & B_BOTTOM_BORDER) { 2101 view->AddLine( 2102 BPoint(rect.left, rect.bottom), 2103 BPoint(rect.right, rect.bottom), bottom); 2104 rect.bottom--; 2105 } 2106 2107 view->EndLineArray(); 2108 } 2109 2110 2111 void 2112 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 2113 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 2114 const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders) 2115 { 2116 view->BeginLineArray(6); 2117 2118 if (borders & B_TOP_BORDER) { 2119 if (borders & B_RIGHT_BORDER) { 2120 view->AddLine( 2121 BPoint(rect.left, rect.top), 2122 BPoint(rect.right - 1, rect.top), top); 2123 view->AddLine( 2124 BPoint(rect.right, rect.top), 2125 BPoint(rect.right, rect.top), rightTop); 2126 } else { 2127 view->AddLine( 2128 BPoint(rect.left, rect.top), 2129 BPoint(rect.right, rect.top), top); 2130 } 2131 rect.top++; 2132 } 2133 2134 if (borders & B_LEFT_BORDER) { 2135 view->AddLine( 2136 BPoint(rect.left, rect.top), 2137 BPoint(rect.left, rect.bottom - 1), left); 2138 view->AddLine( 2139 BPoint(rect.left, rect.bottom), 2140 BPoint(rect.left, rect.bottom), leftBottom); 2141 rect.left++; 2142 } 2143 2144 if (borders & B_BOTTOM_BORDER) { 2145 view->AddLine( 2146 BPoint(rect.left, rect.bottom), 2147 BPoint(rect.right, rect.bottom), bottom); 2148 rect.bottom--; 2149 } 2150 2151 if (borders & B_RIGHT_BORDER) { 2152 view->AddLine( 2153 BPoint(rect.right, rect.bottom), 2154 BPoint(rect.right, rect.top), right); 2155 rect.right--; 2156 } 2157 2158 view->EndLineArray(); 2159 } 2160 2161 2162 void 2163 BControlLook::_DrawButtonBackground(BView* view, BRect& rect, 2164 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2165 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2166 uint32 flags, uint32 borders, enum orientation orientation) 2167 { 2168 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2169 return; 2170 2171 // save the clipping constraints of the view 2172 view->PushState(); 2173 2174 // set clipping constraints to updateRect 2175 BRegion clipping(updateRect); 2176 view->ConstrainClippingRegion(&clipping); 2177 2178 // inner bevel colors 2179 rgb_color bevelLightColor = _BevelLightColor(base, flags); 2180 rgb_color bevelShadowColor = _BevelShadowColor(base, flags); 2181 2182 // button background color 2183 rgb_color buttonBgColor; 2184 if ((flags & B_DISABLED) != 0) 2185 buttonBgColor = tint_color(base, 0.7); 2186 else 2187 buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT); 2188 2189 // surface top gradient 2190 BGradientLinear fillGradient; 2191 _MakeButtonGradient(fillGradient, rect, base, flags, orientation); 2192 2193 // rounded corners 2194 2195 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 2196 && leftTopRadius > 0) { 2197 // draw left top rounded corner 2198 BRect leftTopCorner(floorf(rect.left), floorf(rect.top), 2199 floorf(rect.left + leftTopRadius - 2.0), 2200 floorf(rect.top + leftTopRadius - 2.0)); 2201 clipping.Exclude(leftTopCorner); 2202 _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, 2203 bevelLightColor, fillGradient); 2204 } 2205 2206 if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 2207 && rightTopRadius > 0) { 2208 // draw right top rounded corner 2209 BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), 2210 floorf(rect.top), floorf(rect.right), 2211 floorf(rect.top + rightTopRadius - 2.0)); 2212 clipping.Exclude(rightTopCorner); 2213 _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, 2214 updateRect, bevelLightColor, bevelShadowColor, fillGradient); 2215 } 2216 2217 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2218 && leftBottomRadius > 0) { 2219 // draw left bottom rounded corner 2220 BRect leftBottomCorner(floorf(rect.left), 2221 floorf(rect.bottom - leftBottomRadius + 2.0), 2222 floorf(rect.left + leftBottomRadius - 2.0), 2223 floorf(rect.bottom)); 2224 clipping.Exclude(leftBottomCorner); 2225 _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, 2226 updateRect, bevelLightColor, bevelShadowColor, fillGradient); 2227 } 2228 2229 if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2230 && rightBottomRadius > 0) { 2231 // draw right bottom rounded corner 2232 BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), 2233 floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), 2234 floorf(rect.bottom)); 2235 clipping.Exclude(rightBottomCorner); 2236 _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, 2237 updateRect, bevelShadowColor, fillGradient); 2238 } 2239 2240 // clip out the corners 2241 view->ConstrainClippingRegion(&clipping); 2242 2243 // draw inner bevel 2244 2245 if ((flags & B_ACTIVATED) != 0) { 2246 view->BeginLineArray(4); 2247 2248 // shadow along left/top borders 2249 if (borders & B_LEFT_BORDER) { 2250 view->AddLine(BPoint(rect.left, rect.top), 2251 BPoint(rect.left, rect.bottom), bevelLightColor); 2252 rect.left++; 2253 } 2254 if (borders & B_TOP_BORDER) { 2255 view->AddLine(BPoint(rect.left, rect.top), 2256 BPoint(rect.right, rect.top), bevelLightColor); 2257 rect.top++; 2258 } 2259 2260 // softer shadow along left/top borders 2261 if (borders & B_LEFT_BORDER) { 2262 view->AddLine(BPoint(rect.left, rect.top), 2263 BPoint(rect.left, rect.bottom), bevelShadowColor); 2264 rect.left++; 2265 } 2266 if (borders & B_TOP_BORDER) { 2267 view->AddLine(BPoint(rect.left, rect.top), 2268 BPoint(rect.right, rect.top), bevelShadowColor); 2269 rect.top++; 2270 } 2271 2272 view->EndLineArray(); 2273 } else { 2274 _DrawFrame(view, rect, 2275 bevelLightColor, bevelLightColor, 2276 bevelShadowColor, bevelShadowColor, 2277 buttonBgColor, buttonBgColor, borders); 2278 } 2279 2280 // fill in the background 2281 view->FillRect(rect, fillGradient); 2282 2283 // restore the clipping constraints of the view 2284 view->PopState(); 2285 } 2286 2287 2288 void 2289 BControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect, 2290 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2291 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2292 bool popupIndicator, uint32 flags) 2293 { 2294 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2295 return; 2296 2297 if (popupIndicator) { 2298 BRect leftRect(rect); 2299 leftRect.right -= 10; 2300 2301 BRect rightRect(rect); 2302 rightRect.left = rightRect.right - 9; 2303 2304 _DrawMenuFieldBackgroundInside(view, leftRect, updateRect, 2305 leftTopRadius, 0.0f, leftBottomRadius, 0.0f, base, flags, 2306 B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); 2307 2308 _DrawMenuFieldBackgroundInside(view, rightRect, updateRect, 2309 0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, 2310 B_TOP_BORDER | B_RIGHT_BORDER | B_BOTTOM_BORDER); 2311 2312 // popup marker 2313 BPoint center(roundf((rightRect.left + rightRect.right) / 2.0), 2314 roundf((rightRect.top + rightRect.bottom) / 2.0)); 2315 BPoint triangle[3]; 2316 triangle[0] = center + BPoint(-2.5, -0.5); 2317 triangle[1] = center + BPoint(2.5, -0.5); 2318 triangle[2] = center + BPoint(0.0, 2.0); 2319 2320 uint32 viewFlags = view->Flags(); 2321 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 2322 2323 rgb_color markColor; 2324 if ((flags & B_DISABLED) != 0) 2325 markColor = tint_color(base, 1.35); 2326 else 2327 markColor = tint_color(base, 1.65); 2328 2329 view->SetHighColor(markColor); 2330 view->FillTriangle(triangle[0], triangle[1], triangle[2]); 2331 2332 // draw a line on the left of the popup frame 2333 rgb_color bevelShadowColor = _BevelShadowColor(base, flags); 2334 view->SetHighColor(bevelShadowColor); 2335 BPoint leftTopCorner(floorf(rightRect.left - 1.0), 2336 floorf(rightRect.top - 1.0)); 2337 BPoint leftBottomCorner(floorf(rightRect.left - 1.0), 2338 floorf(rightRect.bottom + 1.0)); 2339 view->StrokeLine(leftTopCorner, leftBottomCorner); 2340 2341 view->SetFlags(viewFlags); 2342 2343 rect = leftRect; 2344 } else { 2345 _DrawMenuFieldBackgroundInside(view, rect, updateRect, leftTopRadius, 2346 rightTopRadius, leftBottomRadius, rightBottomRadius, base, flags); 2347 } 2348 } 2349 2350 2351 void 2352 BControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, 2353 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2354 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2355 uint32 flags, uint32 borders) 2356 { 2357 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2358 return; 2359 2360 // save the clipping constraints of the view 2361 view->PushState(); 2362 2363 // set clipping constraints to updateRect 2364 BRegion clipping(updateRect); 2365 view->ConstrainClippingRegion(&clipping); 2366 2367 // frame colors 2368 rgb_color frameLightColor = _FrameLightColor(base, flags); 2369 rgb_color frameShadowColor = _FrameShadowColor(base, flags); 2370 2371 // indicator background color 2372 rgb_color indicatorBase; 2373 if ((borders & B_LEFT_BORDER) != 0) 2374 indicatorBase = base; 2375 else { 2376 if ((flags & B_DISABLED) != 0) 2377 indicatorBase = tint_color(base, 1.05); 2378 else 2379 indicatorBase = tint_color(base, 1.12); 2380 } 2381 2382 // bevel colors 2383 rgb_color cornerColor = tint_color(indicatorBase, 0.85); 2384 rgb_color bevelColor1 = tint_color(indicatorBase, 0.3); 2385 rgb_color bevelColor2 = tint_color(indicatorBase, 0.5); 2386 rgb_color bevelColor3 = tint_color(indicatorBase, 1.03); 2387 2388 if ((flags & B_DISABLED) != 0) { 2389 cornerColor = tint_color(indicatorBase, 0.8); 2390 bevelColor1 = tint_color(indicatorBase, 0.7); 2391 bevelColor2 = tint_color(indicatorBase, 0.8); 2392 bevelColor3 = tint_color(indicatorBase, 1.01); 2393 } else { 2394 cornerColor = tint_color(indicatorBase, 0.85); 2395 bevelColor1 = tint_color(indicatorBase, 0.3); 2396 bevelColor2 = tint_color(indicatorBase, 0.5); 2397 bevelColor3 = tint_color(indicatorBase, 1.03); 2398 } 2399 2400 // surface top gradient 2401 BGradientLinear fillGradient; 2402 _MakeButtonGradient(fillGradient, rect, indicatorBase, flags); 2403 2404 // rounded corners 2405 2406 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 2407 && leftTopRadius > 0) { 2408 // draw left top rounded corner 2409 BRect leftTopCorner(floorf(rect.left), floorf(rect.top), 2410 floorf(rect.left + leftTopRadius - 2.0), 2411 floorf(rect.top + leftTopRadius - 2.0)); 2412 clipping.Exclude(leftTopCorner); 2413 2414 BRegion cornerClipping(leftTopCorner); 2415 view->ConstrainClippingRegion(&cornerClipping); 2416 2417 BRect ellipseRect(leftTopCorner); 2418 ellipseRect.InsetBy(-1.0, -1.0); 2419 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2420 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2421 2422 // draw the frame (again) 2423 view->SetHighColor(frameLightColor); 2424 view->FillEllipse(ellipseRect); 2425 2426 // draw the bevel and background 2427 _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, 2428 bevelColor1, fillGradient); 2429 } 2430 2431 if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 2432 && rightTopRadius > 0) { 2433 // draw right top rounded corner 2434 BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), 2435 floorf(rect.top), floorf(rect.right), 2436 floorf(rect.top + rightTopRadius - 2.0)); 2437 clipping.Exclude(rightTopCorner); 2438 2439 BRegion cornerClipping(rightTopCorner); 2440 view->ConstrainClippingRegion(&cornerClipping); 2441 2442 BRect ellipseRect(rightTopCorner); 2443 ellipseRect.InsetBy(-1.0, -1.0); 2444 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2445 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2446 2447 // draw the frame (again) 2448 if (frameLightColor == frameShadowColor) { 2449 view->SetHighColor(frameLightColor); 2450 view->FillEllipse(ellipseRect); 2451 } else { 2452 BGradientLinear gradient; 2453 gradient.AddColor(frameLightColor, 0); 2454 gradient.AddColor(frameShadowColor, 255); 2455 gradient.SetStart(rightTopCorner.LeftTop()); 2456 gradient.SetEnd(rightTopCorner.RightBottom()); 2457 view->FillEllipse(ellipseRect, gradient); 2458 } 2459 2460 // draw the bevel and background 2461 _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect, 2462 bevelColor1, bevelColor3, fillGradient); 2463 } 2464 2465 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2466 && leftBottomRadius > 0) { 2467 // draw left bottom rounded corner 2468 BRect leftBottomCorner(floorf(rect.left), 2469 floorf(rect.bottom - leftBottomRadius + 2.0), 2470 floorf(rect.left + leftBottomRadius - 2.0), 2471 floorf(rect.bottom)); 2472 clipping.Exclude(leftBottomCorner); 2473 2474 BRegion cornerClipping(leftBottomCorner); 2475 view->ConstrainClippingRegion(&cornerClipping); 2476 2477 BRect ellipseRect(leftBottomCorner); 2478 ellipseRect.InsetBy(-1.0, -1.0); 2479 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2480 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2481 2482 // draw the frame (again) 2483 if (frameLightColor == frameShadowColor) { 2484 view->SetHighColor(frameLightColor); 2485 view->FillEllipse(ellipseRect); 2486 } else { 2487 BGradientLinear gradient; 2488 gradient.AddColor(frameLightColor, 0); 2489 gradient.AddColor(frameShadowColor, 255); 2490 gradient.SetStart(leftBottomCorner.LeftTop()); 2491 gradient.SetEnd(leftBottomCorner.RightBottom()); 2492 view->FillEllipse(ellipseRect, gradient); 2493 } 2494 2495 // draw the bevel and background 2496 _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, 2497 updateRect, bevelColor2, bevelColor3, fillGradient); 2498 } 2499 2500 if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2501 && rightBottomRadius > 0) { 2502 // draw right bottom rounded corner 2503 BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), 2504 floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), 2505 floorf(rect.bottom)); 2506 clipping.Exclude(rightBottomCorner); 2507 2508 BRegion cornerClipping(rightBottomCorner); 2509 view->ConstrainClippingRegion(&cornerClipping); 2510 2511 BRect ellipseRect(rightBottomCorner); 2512 ellipseRect.InsetBy(-1.0, -1.0); 2513 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2514 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2515 2516 // draw the frame (again) 2517 view->SetHighColor(frameShadowColor); 2518 view->FillEllipse(ellipseRect); 2519 2520 // draw the bevel and background 2521 _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, 2522 updateRect, bevelColor3, fillGradient); 2523 } 2524 2525 // clip out the corners 2526 view->ConstrainClippingRegion(&clipping); 2527 2528 // draw the bevel 2529 _DrawFrame(view, rect, 2530 bevelColor2, bevelColor1, 2531 bevelColor3, bevelColor3, 2532 cornerColor, cornerColor, 2533 borders); 2534 2535 // fill in the background 2536 view->FillRect(rect, fillGradient); 2537 2538 // restore the clipping constraints of the view 2539 view->PopState(); 2540 } 2541 2542 2543 void 2544 BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& cornerRect, 2545 const BRect& updateRect, const rgb_color& background, 2546 const rgb_color& edgeColor, const rgb_color& frameColor, 2547 const rgb_color& bevelColor, const BGradientLinear& fillGradient) 2548 { 2549 _DrawRoundCornerFrameLeftTop(view, cornerRect, updateRect, 2550 background, edgeColor, frameColor); 2551 _DrawRoundCornerBackgroundLeftTop(view, cornerRect, updateRect, 2552 bevelColor, fillGradient); 2553 } 2554 2555 2556 void 2557 BControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect, 2558 const BRect& updateRect, const rgb_color& background, 2559 const rgb_color& edgeColor, const rgb_color& frameColor) 2560 { 2561 // constrain clipping region to corner 2562 BRegion clipping(cornerRect); 2563 view->ConstrainClippingRegion(&clipping); 2564 2565 // background 2566 view->SetHighColor(background); 2567 view->FillRect(cornerRect); 2568 2569 // outer edge 2570 BRect ellipseRect(cornerRect); 2571 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2572 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2573 2574 view->SetHighColor(edgeColor); 2575 view->FillEllipse(ellipseRect); 2576 2577 // frame 2578 ellipseRect.InsetBy(1, 1); 2579 cornerRect.left++; 2580 cornerRect.top++; 2581 view->SetHighColor(frameColor); 2582 view->FillEllipse(ellipseRect); 2583 2584 // prepare for bevel 2585 cornerRect.left++; 2586 cornerRect.top++; 2587 } 2588 2589 2590 void 2591 BControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRect, 2592 const BRect& updateRect, const rgb_color& bevelColor, 2593 const BGradientLinear& fillGradient) 2594 { 2595 // constrain clipping region to corner 2596 BRegion clipping(cornerRect); 2597 view->ConstrainClippingRegion(&clipping); 2598 2599 BRect ellipseRect(cornerRect); 2600 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2601 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2602 2603 // bevel 2604 view->SetHighColor(bevelColor); 2605 view->FillEllipse(ellipseRect); 2606 2607 // gradient 2608 ellipseRect.InsetBy(1, 1); 2609 view->FillEllipse(ellipseRect, fillGradient); 2610 } 2611 2612 2613 void 2614 BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& cornerRect, 2615 const BRect& updateRect, const rgb_color& background, 2616 const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, 2617 const rgb_color& frameTopColor, const rgb_color& frameRightColor, 2618 const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, 2619 const BGradientLinear& fillGradient) 2620 { 2621 _DrawRoundCornerFrameRightTop(view, cornerRect, updateRect, 2622 background, edgeTopColor, edgeRightColor, frameTopColor, 2623 frameRightColor); 2624 _DrawRoundCornerBackgroundRightTop(view, cornerRect, updateRect, 2625 bevelTopColor, bevelRightColor, fillGradient); 2626 } 2627 2628 2629 void 2630 BControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect, 2631 const BRect& updateRect, const rgb_color& background, 2632 const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, 2633 const rgb_color& frameTopColor, const rgb_color& frameRightColor) 2634 { 2635 // constrain clipping region to corner 2636 BRegion clipping(cornerRect); 2637 view->ConstrainClippingRegion(&clipping); 2638 2639 // background 2640 view->SetHighColor(background); 2641 view->FillRect(cornerRect); 2642 2643 // outer edge 2644 BRect ellipseRect(cornerRect); 2645 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2646 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2647 2648 BGradientLinear gradient; 2649 gradient.AddColor(edgeTopColor, 0); 2650 gradient.AddColor(edgeRightColor, 255); 2651 gradient.SetStart(cornerRect.LeftTop()); 2652 gradient.SetEnd(cornerRect.RightBottom()); 2653 view->FillEllipse(ellipseRect, gradient); 2654 2655 // frame 2656 ellipseRect.InsetBy(1, 1); 2657 cornerRect.right--; 2658 cornerRect.top++; 2659 if (frameTopColor == frameRightColor) { 2660 view->SetHighColor(frameTopColor); 2661 view->FillEllipse(ellipseRect); 2662 } else { 2663 gradient.SetColor(0, frameTopColor); 2664 gradient.SetColor(1, frameRightColor); 2665 gradient.SetStart(cornerRect.LeftTop()); 2666 gradient.SetEnd(cornerRect.RightBottom()); 2667 view->FillEllipse(ellipseRect, gradient); 2668 } 2669 2670 // prepare for bevel 2671 cornerRect.right--; 2672 cornerRect.top++; 2673 } 2674 2675 2676 void 2677 BControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerRect, 2678 const BRect& updateRect, const rgb_color& bevelTopColor, 2679 const rgb_color& bevelRightColor, const BGradientLinear& fillGradient) 2680 { 2681 // constrain clipping region to corner 2682 BRegion clipping(cornerRect); 2683 view->ConstrainClippingRegion(&clipping); 2684 2685 BRect ellipseRect(cornerRect); 2686 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2687 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2688 2689 // bevel 2690 BGradientLinear gradient; 2691 gradient.AddColor(bevelTopColor, 0); 2692 gradient.AddColor(bevelRightColor, 255); 2693 gradient.SetStart(cornerRect.LeftTop()); 2694 gradient.SetEnd(cornerRect.RightBottom()); 2695 view->FillEllipse(ellipseRect, gradient); 2696 2697 // gradient 2698 ellipseRect.InsetBy(1, 1); 2699 view->FillEllipse(ellipseRect, fillGradient); 2700 } 2701 2702 2703 void 2704 BControlLook::_DrawRoundCornerLeftBottom(BView* view, BRect& cornerRect, 2705 const BRect& updateRect, const rgb_color& background, 2706 const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, 2707 const rgb_color& frameLeftColor, const rgb_color& frameBottomColor, 2708 const rgb_color& bevelLeftColor, const rgb_color& bevelBottomColor, 2709 const BGradientLinear& fillGradient) 2710 { 2711 _DrawRoundCornerFrameLeftBottom(view, cornerRect, updateRect, 2712 background, edgeLeftColor, edgeBottomColor, frameLeftColor, 2713 frameBottomColor); 2714 _DrawRoundCornerBackgroundLeftBottom(view, cornerRect, updateRect, 2715 bevelLeftColor, bevelBottomColor, fillGradient); 2716 } 2717 2718 2719 void 2720 BControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect, 2721 const BRect& updateRect, const rgb_color& background, 2722 const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, 2723 const rgb_color& frameLeftColor, const rgb_color& frameBottomColor) 2724 { 2725 // constrain clipping region to corner 2726 BRegion clipping(cornerRect); 2727 view->ConstrainClippingRegion(&clipping); 2728 2729 // background 2730 view->SetHighColor(background); 2731 view->FillRect(cornerRect); 2732 2733 // outer edge 2734 BRect ellipseRect(cornerRect); 2735 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2736 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2737 2738 BGradientLinear gradient; 2739 gradient.AddColor(edgeLeftColor, 0); 2740 gradient.AddColor(edgeBottomColor, 255); 2741 gradient.SetStart(cornerRect.LeftTop()); 2742 gradient.SetEnd(cornerRect.RightBottom()); 2743 view->FillEllipse(ellipseRect, gradient); 2744 2745 // frame 2746 ellipseRect.InsetBy(1, 1); 2747 cornerRect.left++; 2748 cornerRect.bottom--; 2749 if (frameLeftColor == frameBottomColor) { 2750 view->SetHighColor(frameLeftColor); 2751 view->FillEllipse(ellipseRect); 2752 } else { 2753 gradient.SetColor(0, frameLeftColor); 2754 gradient.SetColor(1, frameBottomColor); 2755 gradient.SetStart(cornerRect.LeftTop()); 2756 gradient.SetEnd(cornerRect.RightBottom()); 2757 view->FillEllipse(ellipseRect, gradient); 2758 } 2759 2760 // prepare for bevel 2761 cornerRect.left++; 2762 cornerRect.bottom--; 2763 } 2764 2765 2766 void 2767 BControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& cornerRect, 2768 const BRect& updateRect, const rgb_color& bevelLeftColor, 2769 const rgb_color& bevelBottomColor, const BGradientLinear& fillGradient) 2770 { 2771 // constrain clipping region to corner 2772 BRegion clipping(cornerRect); 2773 view->ConstrainClippingRegion(&clipping); 2774 2775 BRect ellipseRect(cornerRect); 2776 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2777 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2778 2779 // bevel 2780 BGradientLinear gradient; 2781 gradient.AddColor(bevelLeftColor, 0); 2782 gradient.AddColor(bevelBottomColor, 255); 2783 gradient.SetStart(cornerRect.LeftTop()); 2784 gradient.SetEnd(cornerRect.RightBottom()); 2785 view->FillEllipse(ellipseRect, gradient); 2786 2787 // gradient 2788 ellipseRect.InsetBy(1, 1); 2789 view->FillEllipse(ellipseRect, fillGradient); 2790 2791 view->PopState(); 2792 } 2793 2794 2795 void 2796 BControlLook::_DrawRoundCornerRightBottom(BView* view, BRect& cornerRect, 2797 const BRect& updateRect, const rgb_color& background, 2798 const rgb_color& edgeColor, const rgb_color& frameColor, 2799 const rgb_color& bevelColor, const BGradientLinear& fillGradient) 2800 { 2801 _DrawRoundCornerFrameRightBottom(view, cornerRect, updateRect, 2802 background, edgeColor, frameColor); 2803 _DrawRoundCornerBackgroundRightBottom(view, cornerRect, updateRect, 2804 bevelColor, fillGradient); 2805 } 2806 2807 2808 void 2809 BControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRect, 2810 const BRect& updateRect, const rgb_color& background, 2811 const rgb_color& edgeColor, const rgb_color& frameColor) 2812 { 2813 // constrain clipping region to corner 2814 BRegion clipping(cornerRect); 2815 view->ConstrainClippingRegion(&clipping); 2816 2817 // background 2818 view->SetHighColor(background); 2819 view->FillRect(cornerRect); 2820 2821 // outer edge 2822 BRect ellipseRect(cornerRect); 2823 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2824 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2825 2826 view->SetHighColor(edgeColor); 2827 view->FillEllipse(ellipseRect); 2828 2829 // frame 2830 ellipseRect.InsetBy(1, 1); 2831 cornerRect.right--; 2832 cornerRect.bottom++; 2833 view->SetHighColor(frameColor); 2834 view->FillEllipse(ellipseRect); 2835 2836 // prepare for bevel 2837 cornerRect.left++; 2838 cornerRect.bottom--; 2839 } 2840 2841 2842 void 2843 BControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view, 2844 BRect& cornerRect, const BRect& updateRect, const rgb_color& bevelColor, 2845 const BGradientLinear& fillGradient) 2846 { 2847 // constrain clipping region to corner 2848 BRegion clipping(cornerRect); 2849 view->ConstrainClippingRegion(&clipping); 2850 2851 BRect ellipseRect(cornerRect); 2852 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2853 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2854 2855 // bevel 2856 view->SetHighColor(bevelColor); 2857 view->FillEllipse(ellipseRect); 2858 2859 // gradient 2860 ellipseRect.InsetBy(1, 1); 2861 view->FillEllipse(ellipseRect, fillGradient); 2862 } 2863 2864 2865 void 2866 BControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, 2867 const BRect& updateRect, 2868 const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor, 2869 const rgb_color& frameLightColor, const rgb_color& frameShadowColor, 2870 const rgb_color& fillLightColor, const rgb_color& fillShadowColor, 2871 float leftInset, float topInset, float rightInset, float bottomInset, 2872 enum orientation orientation) 2873 { 2874 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2875 return; 2876 2877 BGradientLinear gradient; 2878 gradient.AddColor(edgeShadowColor, 0); 2879 gradient.AddColor(edgeLightColor, 255); 2880 gradient.SetStart(rect.LeftTop()); 2881 if (orientation == B_HORIZONTAL) 2882 gradient.SetEnd(rect.LeftBottom()); 2883 else 2884 gradient.SetEnd(rect.RightTop()); 2885 2886 view->FillEllipse(rect, gradient); 2887 2888 rect.left += leftInset; 2889 rect.top += topInset; 2890 rect.right += rightInset; 2891 rect.bottom += bottomInset; 2892 2893 gradient.MakeEmpty(); 2894 gradient.AddColor(frameShadowColor, 0); 2895 gradient.AddColor(frameLightColor, 255); 2896 gradient.SetStart(rect.LeftTop()); 2897 if (orientation == B_HORIZONTAL) 2898 gradient.SetEnd(rect.LeftBottom()); 2899 else 2900 gradient.SetEnd(rect.RightTop()); 2901 2902 view->FillEllipse(rect, gradient); 2903 2904 rect.left += leftInset; 2905 rect.top += topInset; 2906 rect.right += rightInset; 2907 rect.bottom += bottomInset; 2908 2909 gradient.MakeEmpty(); 2910 gradient.AddColor(fillShadowColor, 0); 2911 gradient.AddColor(fillLightColor, 255); 2912 gradient.SetStart(rect.LeftTop()); 2913 if (orientation == B_HORIZONTAL) 2914 gradient.SetEnd(rect.LeftBottom()); 2915 else 2916 gradient.SetEnd(rect.RightTop()); 2917 2918 view->FillEllipse(rect, gradient); 2919 } 2920 2921 2922 rgb_color 2923 BControlLook::_EdgeLightColor(const rgb_color& base, float contrast, 2924 float brightness, uint32 flags) 2925 { 2926 rgb_color edgeLightColor; 2927 2928 if ((flags & B_BLEND_FRAME) != 0) { 2929 uint8 alpha = uint8(20 * contrast); 2930 uint32 white = uint8(255 * brightness); 2931 2932 edgeLightColor = (rgb_color){ white, white, white, alpha }; 2933 } else { 2934 // colors 2935 float tintLight = kEdgeBevelLightTint; 2936 2937 if (contrast == 0.0) 2938 tintLight = B_NO_TINT; 2939 else if (contrast != 1.0) 2940 tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; 2941 2942 edgeLightColor = tint_color(base, tintLight); 2943 2944 if (brightness < 1.0) { 2945 edgeLightColor.red = uint8(edgeLightColor.red * brightness); 2946 edgeLightColor.green = uint8(edgeLightColor.green * brightness); 2947 edgeLightColor.blue = uint8(edgeLightColor.blue * brightness); 2948 } 2949 } 2950 2951 return edgeLightColor; 2952 } 2953 2954 2955 rgb_color 2956 BControlLook::_EdgeShadowColor(const rgb_color& base, float contrast, 2957 float brightness, uint32 flags) 2958 { 2959 rgb_color edgeShadowColor; 2960 2961 if ((flags & B_BLEND_FRAME) != 0) { 2962 uint8 alpha = uint8(20 * contrast); 2963 edgeShadowColor = (rgb_color){ 0, 0, 0, alpha }; 2964 } else { 2965 float tintShadow = kEdgeBevelShadowTint; 2966 2967 if (contrast == 0.0) 2968 tintShadow = B_NO_TINT; 2969 else if (contrast != 1.0) 2970 tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; 2971 2972 edgeShadowColor = tint_color(base, tintShadow); 2973 2974 if (brightness < 1.0) { 2975 edgeShadowColor.red = uint8(edgeShadowColor.red * brightness); 2976 edgeShadowColor.green = uint8(edgeShadowColor.green * brightness); 2977 edgeShadowColor.blue = uint8(edgeShadowColor.blue * brightness); 2978 } 2979 } 2980 2981 return edgeShadowColor; 2982 } 2983 2984 2985 rgb_color 2986 BControlLook::_FrameLightColor(const rgb_color& base, uint32 flags) 2987 { 2988 if ((flags & B_FOCUSED) != 0) 2989 return ui_color(B_KEYBOARD_NAVIGATION_COLOR); 2990 2991 if ((flags & B_ACTIVATED) != 0) 2992 return _FrameShadowColor(base, flags & ~B_ACTIVATED); 2993 2994 rgb_color frameLightColor; 2995 2996 if ((flags & B_DISABLED) != 0) { 2997 // TODO: B_BLEND_FRAME 2998 frameLightColor = tint_color(base, 1.145); 2999 3000 if ((flags & B_DEFAULT_BUTTON) != 0) 3001 frameLightColor = tint_color(frameLightColor, 1.14); 3002 } else { 3003 if ((flags & B_BLEND_FRAME) != 0) 3004 frameLightColor = (rgb_color){ 0, 0, 0, 75 }; 3005 else 3006 frameLightColor = tint_color(base, 1.33); 3007 3008 if ((flags & B_DEFAULT_BUTTON) != 0) 3009 frameLightColor = tint_color(frameLightColor, 1.35); 3010 } 3011 3012 return frameLightColor; 3013 } 3014 3015 3016 rgb_color 3017 BControlLook::_FrameShadowColor(const rgb_color& base, uint32 flags) 3018 { 3019 if ((flags & B_FOCUSED) != 0) 3020 return ui_color(B_KEYBOARD_NAVIGATION_COLOR); 3021 3022 if ((flags & B_ACTIVATED) != 0) 3023 return _FrameLightColor(base, flags & ~B_ACTIVATED); 3024 3025 rgb_color frameShadowColor; 3026 3027 if ((flags & B_DISABLED) != 0) { 3028 // TODO: B_BLEND_FRAME 3029 frameShadowColor = tint_color(base, 1.24); 3030 3031 if ((flags & B_DEFAULT_BUTTON) != 0) { 3032 frameShadowColor = tint_color(base, 1.145); 3033 frameShadowColor = tint_color(frameShadowColor, 1.12); 3034 } 3035 } else { 3036 if ((flags & B_DEFAULT_BUTTON) != 0) { 3037 if ((flags & B_BLEND_FRAME) != 0) 3038 frameShadowColor = (rgb_color){ 0, 0, 0, 75 }; 3039 else 3040 frameShadowColor = tint_color(base, 1.33); 3041 3042 frameShadowColor = tint_color(frameShadowColor, 1.5); 3043 } else { 3044 if ((flags & B_BLEND_FRAME) != 0) 3045 frameShadowColor = (rgb_color){ 0, 0, 0, 95 }; 3046 else 3047 frameShadowColor = tint_color(base, 1.47); 3048 } 3049 } 3050 3051 return frameShadowColor; 3052 } 3053 3054 3055 rgb_color 3056 BControlLook::_BevelLightColor(const rgb_color& base, uint32 flags) 3057 { 3058 rgb_color bevelLightColor = tint_color(base, 0.2); 3059 3060 if ((flags & B_DISABLED) != 0) 3061 bevelLightColor = tint_color(base, B_LIGHTEN_1_TINT); 3062 3063 if ((flags & B_ACTIVATED) != 0) 3064 bevelLightColor = tint_color(base, B_DARKEN_1_TINT); 3065 3066 return bevelLightColor; 3067 } 3068 3069 3070 rgb_color 3071 BControlLook::_BevelShadowColor(const rgb_color& base, uint32 flags) 3072 { 3073 rgb_color bevelShadowColor = tint_color(base, 1.08); 3074 3075 if ((flags & B_DISABLED) != 0) 3076 bevelShadowColor = base; 3077 3078 if ((flags & B_ACTIVATED) != 0) 3079 bevelShadowColor = tint_color(base, B_DARKEN_1_TINT); 3080 3081 return bevelShadowColor; 3082 } 3083 3084 3085 void 3086 BControlLook::_FillGradient(BView* view, const BRect& rect, 3087 const rgb_color& base, float topTint, float bottomTint, 3088 enum orientation orientation) 3089 { 3090 BGradientLinear gradient; 3091 _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); 3092 view->FillRect(rect, gradient); 3093 } 3094 3095 3096 void 3097 BControlLook::_FillGlossyGradient(BView* view, const BRect& rect, 3098 const rgb_color& base, float topTint, float middle1Tint, 3099 float middle2Tint, float bottomTint, enum orientation orientation) 3100 { 3101 BGradientLinear gradient; 3102 _MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint, 3103 middle2Tint, bottomTint, orientation); 3104 view->FillRect(rect, gradient); 3105 } 3106 3107 3108 void 3109 BControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect, 3110 const rgb_color& base, float topTint, float bottomTint, 3111 enum orientation orientation) const 3112 { 3113 gradient.AddColor(tint_color(base, topTint), 0); 3114 gradient.AddColor(tint_color(base, bottomTint), 255); 3115 gradient.SetStart(rect.LeftTop()); 3116 if (orientation == B_HORIZONTAL) 3117 gradient.SetEnd(rect.LeftBottom()); 3118 else 3119 gradient.SetEnd(rect.RightTop()); 3120 } 3121 3122 3123 void 3124 BControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect, 3125 const rgb_color& base, float topTint, float middle1Tint, 3126 float middle2Tint, float bottomTint, 3127 enum orientation orientation) const 3128 { 3129 gradient.AddColor(tint_color(base, topTint), 0); 3130 gradient.AddColor(tint_color(base, middle1Tint), 132); 3131 gradient.AddColor(tint_color(base, middle2Tint), 136); 3132 gradient.AddColor(tint_color(base, bottomTint), 255); 3133 gradient.SetStart(rect.LeftTop()); 3134 if (orientation == B_HORIZONTAL) 3135 gradient.SetEnd(rect.LeftBottom()); 3136 else 3137 gradient.SetEnd(rect.RightTop()); 3138 } 3139 3140 3141 void 3142 BControlLook::_MakeButtonGradient(BGradientLinear& gradient, BRect& rect, 3143 const rgb_color& base, uint32 flags, enum orientation orientation) const 3144 { 3145 float topTint = 0.49; 3146 float middleTint1 = 0.62; 3147 float middleTint2 = 0.76; 3148 float bottomTint = 0.90; 3149 3150 if ((flags & B_ACTIVATED) != 0) { 3151 topTint = 1.11; 3152 bottomTint = 1.08; 3153 } 3154 3155 if ((flags & B_DISABLED) != 0) { 3156 topTint = (topTint + B_NO_TINT) / 2; 3157 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 3158 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 3159 bottomTint = (bottomTint + B_NO_TINT) / 2; 3160 } else if ((flags & B_HOVER) != 0) { 3161 static const float kHoverTintFactor = 0.85; 3162 topTint *= kHoverTintFactor; 3163 middleTint1 *= kHoverTintFactor; 3164 middleTint2 *= kHoverTintFactor; 3165 bottomTint *= kHoverTintFactor; 3166 } 3167 3168 if ((flags & B_ACTIVATED) != 0) { 3169 _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); 3170 } else { 3171 _MakeGlossyGradient(gradient, rect, base, topTint, middleTint1, 3172 middleTint2, bottomTint, orientation); 3173 } 3174 } 3175 3176 3177 3178 bool 3179 BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, 3180 rgb_color& color, uint32 flags) const 3181 { 3182 if ((flags & (B_ACTIVATED | B_CLICKED)) == 0) { 3183 // no mark to be drawn at all 3184 return false; 3185 } 3186 3187 color = ui_color(B_CONTROL_MARK_COLOR); 3188 3189 float mix = 1.0; 3190 3191 if ((flags & B_DISABLED) != 0) { 3192 // activated, but disabled 3193 mix = 0.4; 3194 } else if ((flags & B_CLICKED) != 0) { 3195 if ((flags & B_ACTIVATED) != 0) { 3196 // loosing activation 3197 mix = 0.7; 3198 } else { 3199 // becoming activated 3200 mix = 0.3; 3201 } 3202 } else { 3203 // simply activated 3204 } 3205 3206 color.red = uint8(color.red * mix + base.red * (1.0 - mix)); 3207 color.green = uint8(color.green * mix + base.green * (1.0 - mix)); 3208 color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix)); 3209 3210 return true; 3211 } 3212 3213 3214 // NOTE: May come from a add-on in the future. Initialized in 3215 // InterfaceDefs.cpp 3216 BControlLook* be_control_look = NULL; 3217 3218 3219 } // namespace BPrivate 3220