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 // separate the bar in two sides 810 float sliderPosition; 811 BRect leftBarSide = rect; 812 BRect rightBarSide = rect; 813 814 if (orientation == B_HORIZONTAL) { 815 sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) 816 * sliderScale); 817 leftBarSide.right = sliderPosition - 1; 818 rightBarSide.left = sliderPosition; 819 } else { 820 // NOTE: position is reverse of coords 821 sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) 822 * (1.0 - sliderScale)); 823 leftBarSide.top = sliderPosition; 824 rightBarSide.bottom = sliderPosition - 1; 825 } 826 827 // fill the background for the corners, exclude the middle bar for now 828 BRegion region(rect); 829 region.Exclude(rightBarSide); 830 view->ConstrainClippingRegion(®ion); 831 832 view->PushState(); 833 834 DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, 835 orientation); 836 837 view->PopState(); 838 839 region.Set(rect); 840 region.Exclude(leftBarSide); 841 view->ConstrainClippingRegion(®ion); 842 843 view->PushState(); 844 845 DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, 846 orientation); 847 848 view->PopState(); 849 850 // reset clipping constraints 851 view->ConstrainClippingRegion(NULL); 852 } 853 854 855 void 856 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 857 const rgb_color& base, rgb_color fillColor, uint32 flags, 858 enum orientation orientation) 859 { 860 if (!rect.IsValid() || !rect.Intersects(updateRect)) 861 return; 862 863 // separate the rect into corners 864 BRect leftCorner(rect); 865 BRect rightCorner(rect); 866 BRect barRect(rect); 867 868 if (orientation == B_HORIZONTAL) { 869 leftCorner.right = leftCorner.left + leftCorner.Height(); 870 rightCorner.left = rightCorner.right - rightCorner.Height(); 871 barRect.left += ceilf(barRect.Height() / 2); 872 barRect.right -= ceilf(barRect.Height() / 2); 873 } else { 874 leftCorner.bottom = leftCorner.top + leftCorner.Width(); 875 rightCorner.top = rightCorner.bottom - rightCorner.Width(); 876 barRect.top += ceilf(barRect.Width() / 2); 877 barRect.bottom -= ceilf(barRect.Width() / 2); 878 } 879 880 // fill the background for the corners, exclude the middle bar for now 881 BRegion region(rect); 882 region.Exclude(barRect); 883 view->ConstrainClippingRegion(®ion); 884 885 if ((flags & B_BLEND_FRAME) == 0) { 886 view->SetHighColor(base); 887 view->FillRect(rect); 888 } 889 890 // figure out the tints to be used 891 float edgeLightTint; 892 float edgeShadowTint; 893 float frameLightTint; 894 float frameShadowTint; 895 float fillLightTint; 896 float fillShadowTint; 897 uint8 edgeLightAlpha; 898 uint8 edgeShadowAlpha; 899 uint8 frameLightAlpha; 900 uint8 frameShadowAlpha; 901 902 if ((flags & B_DISABLED) != 0) { 903 edgeLightTint = 1.0; 904 edgeShadowTint = 1.0; 905 frameLightTint = 1.20; 906 frameShadowTint = 1.25; 907 fillLightTint = 0.9; 908 fillShadowTint = 1.05; 909 edgeLightAlpha = 12; 910 edgeShadowAlpha = 12; 911 frameLightAlpha = 40; 912 frameShadowAlpha = 45; 913 914 fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6); 915 fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6); 916 fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6); 917 } else { 918 edgeLightTint = 0.65; 919 edgeShadowTint = 1.07; 920 frameLightTint = 1.40; 921 frameShadowTint = 1.50; 922 fillLightTint = 0.8; 923 fillShadowTint = 1.1; 924 edgeLightAlpha = 15; 925 edgeShadowAlpha = 15; 926 frameLightAlpha = 92; 927 frameShadowAlpha = 107; 928 } 929 930 rgb_color edgeLightColor; 931 rgb_color edgeShadowColor; 932 rgb_color frameLightColor; 933 rgb_color frameShadowColor; 934 rgb_color fillLightColor = tint_color(fillColor, fillLightTint); 935 rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); 936 937 drawing_mode oldMode = view->DrawingMode(); 938 939 if ((flags & B_BLEND_FRAME) != 0) { 940 edgeLightColor = (rgb_color){ 255, 255, 255, edgeLightAlpha }; 941 edgeShadowColor = (rgb_color){ 0, 0, 0, edgeShadowAlpha }; 942 frameLightColor = (rgb_color){ 0, 0, 0, frameLightAlpha }; 943 frameShadowColor = (rgb_color){ 0, 0, 0, frameShadowAlpha }; 944 945 view->SetDrawingMode(B_OP_ALPHA); 946 } else { 947 edgeLightColor = tint_color(base, edgeLightTint); 948 edgeShadowColor = tint_color(base, edgeShadowTint); 949 frameLightColor = tint_color(fillColor, frameLightTint); 950 frameShadowColor = tint_color(fillColor, frameShadowTint); 951 } 952 953 if (orientation == B_HORIZONTAL) { 954 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 955 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 956 fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); 957 958 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 959 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 960 fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); 961 } else { 962 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 963 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 964 fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); 965 966 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 967 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 968 fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); 969 } 970 971 view->ConstrainClippingRegion(NULL); 972 973 view->BeginLineArray(4); 974 if (orientation == B_HORIZONTAL) { 975 view->AddLine(barRect.LeftTop(), barRect.RightTop(), edgeShadowColor); 976 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 977 edgeLightColor); 978 barRect.InsetBy(0, 1); 979 view->AddLine(barRect.LeftTop(), barRect.RightTop(), frameShadowColor); 980 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 981 frameLightColor); 982 barRect.InsetBy(0, 1); 983 } else { 984 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), edgeShadowColor); 985 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 986 edgeLightColor); 987 barRect.InsetBy(1, 0); 988 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), frameShadowColor); 989 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 990 frameLightColor); 991 barRect.InsetBy(1, 0); 992 } 993 view->EndLineArray(); 994 995 view->SetDrawingMode(oldMode); 996 997 _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, 998 orientation); 999 } 1000 1001 1002 void 1003 BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, 1004 const rgb_color& base, uint32 flags, enum orientation orientation) 1005 { 1006 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1007 return; 1008 1009 // figure out frame color 1010 rgb_color frameLightColor; 1011 rgb_color frameShadowColor; 1012 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1013 1014 if ((flags & B_FOCUSED) != 0) { 1015 // focused 1016 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1017 frameShadowColor = frameLightColor; 1018 } else { 1019 // figure out the tints to be used 1020 float frameLightTint; 1021 float frameShadowTint; 1022 1023 if ((flags & B_DISABLED) != 0) { 1024 frameLightTint = 1.30; 1025 frameShadowTint = 1.35; 1026 shadowColor.alpha = 30; 1027 } else { 1028 frameLightTint = 1.6; 1029 frameShadowTint = 1.65; 1030 } 1031 1032 frameLightColor = tint_color(base, frameLightTint); 1033 frameShadowColor = tint_color(base, frameShadowTint); 1034 } 1035 1036 BRect originalRect(rect); 1037 rect.right--; 1038 rect.bottom--; 1039 1040 _DrawFrame(view, rect, frameLightColor, frameLightColor, 1041 frameShadowColor, frameShadowColor); 1042 1043 flags &= ~B_ACTIVATED; 1044 DrawButtonBackground(view, rect, updateRect, base, flags); 1045 1046 // thumb shadow 1047 view->SetDrawingMode(B_OP_ALPHA); 1048 view->SetHighColor(shadowColor); 1049 originalRect.left++; 1050 originalRect.top++; 1051 view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom()); 1052 originalRect.bottom--; 1053 view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom()); 1054 1055 // thumb edge 1056 if (orientation == B_HORIZONTAL) { 1057 rect.InsetBy(0, floorf(rect.Height() / 4)); 1058 rect.left = floorf((rect.left + rect.right) / 2); 1059 rect.right = rect.left + 1; 1060 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1061 shadowColor.alpha = 128; 1062 view->SetHighColor(shadowColor); 1063 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 1064 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1065 lightColor.alpha = 128; 1066 view->SetHighColor(lightColor); 1067 view->StrokeLine(rect.RightTop(), rect.RightBottom()); 1068 } else { 1069 rect.InsetBy(floorf(rect.Width() / 4), 0); 1070 rect.top = floorf((rect.top + rect.bottom) / 2); 1071 rect.bottom = rect.top + 1; 1072 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1073 shadowColor.alpha = 128; 1074 view->SetHighColor(shadowColor); 1075 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 1076 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1077 lightColor.alpha = 128; 1078 view->SetHighColor(lightColor); 1079 view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); 1080 } 1081 1082 view->SetDrawingMode(B_OP_COPY); 1083 } 1084 1085 1086 void 1087 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1088 const BRect& updateRect, const rgb_color& base, uint32 flags, 1089 enum orientation orientation) 1090 { 1091 DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); 1092 } 1093 1094 1095 void 1096 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1097 const BRect& updateRect, const rgb_color& base, const rgb_color& fill, 1098 uint32 flags, enum orientation orientation) 1099 { 1100 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1101 return; 1102 1103 // figure out frame color 1104 rgb_color frameLightColor; 1105 rgb_color frameShadowColor; 1106 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1107 1108 float topTint = 0.49; 1109 float middleTint1 = 0.62; 1110 float middleTint2 = 0.76; 1111 float bottomTint = 0.90; 1112 1113 if ((flags & B_DISABLED) != 0) { 1114 topTint = (topTint + B_NO_TINT) / 2; 1115 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 1116 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 1117 bottomTint = (bottomTint + B_NO_TINT) / 2; 1118 } else if ((flags & B_HOVER) != 0) { 1119 static const float kHoverTintFactor = 0.85; 1120 topTint *= kHoverTintFactor; 1121 middleTint1 *= kHoverTintFactor; 1122 middleTint2 *= kHoverTintFactor; 1123 bottomTint *= kHoverTintFactor; 1124 } 1125 1126 if ((flags & B_FOCUSED) != 0) { 1127 // focused 1128 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1129 frameShadowColor = frameLightColor; 1130 } else { 1131 // figure out the tints to be used 1132 float frameLightTint; 1133 float frameShadowTint; 1134 1135 if ((flags & B_DISABLED) != 0) { 1136 frameLightTint = 1.30; 1137 frameShadowTint = 1.35; 1138 shadowColor.alpha = 30; 1139 } else { 1140 frameLightTint = 1.6; 1141 frameShadowTint = 1.65; 1142 } 1143 1144 frameLightColor = tint_color(base, frameLightTint); 1145 frameShadowColor = tint_color(base, frameShadowTint); 1146 } 1147 1148 // make room for the shadow 1149 rect.right--; 1150 rect.bottom--; 1151 1152 uint32 viewFlags = view->Flags(); 1153 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 1154 view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); 1155 1156 float centerh = (rect.left + rect.right) / 2; 1157 float centerv = (rect.top + rect.bottom) / 2; 1158 1159 BShape shape; 1160 if (orientation == B_HORIZONTAL) { 1161 shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5)); 1162 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); 1163 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5)); 1164 shape.LineTo(BPoint(centerh + 0.5, rect.top + 0.5)); 1165 shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); 1166 } else { 1167 shape.MoveTo(BPoint(rect.right + 0.5, rect.top + 0.5)); 1168 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); 1169 shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.bottom + 0.5)); 1170 shape.LineTo(BPoint(rect.left + 0.5, centerv + 0.5)); 1171 shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.top + 0.5)); 1172 } 1173 shape.Close(); 1174 1175 view->MovePenTo(BPoint(1, 1)); 1176 1177 view->SetDrawingMode(B_OP_ALPHA); 1178 view->SetHighColor(shadowColor); 1179 view->StrokeShape(&shape); 1180 1181 view->MovePenTo(B_ORIGIN); 1182 1183 view->SetDrawingMode(B_OP_COPY); 1184 view->SetHighColor(frameLightColor); 1185 view->StrokeShape(&shape); 1186 1187 rect.InsetBy(1, 1); 1188 shape.Clear(); 1189 if (orientation == B_HORIZONTAL) { 1190 shape.MoveTo(BPoint(rect.left, rect.bottom + 1)); 1191 shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); 1192 shape.LineTo(BPoint(centerh + 0.5, rect.top)); 1193 } else { 1194 shape.MoveTo(BPoint(rect.right + 1, rect.top)); 1195 shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); 1196 shape.LineTo(BPoint(rect.left, centerv + 0.5)); 1197 } 1198 shape.Close(); 1199 1200 BGradientLinear gradient; 1201 if ((flags & B_DISABLED) != 0) { 1202 _MakeGradient(gradient, rect, fill, topTint, bottomTint); 1203 } else { 1204 _MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1, 1205 middleTint2, bottomTint); 1206 } 1207 1208 view->FillShape(&shape, gradient); 1209 1210 view->SetFlags(viewFlags); 1211 } 1212 1213 1214 void 1215 BControlLook::DrawSliderHashMarks(BView* view, BRect& rect, 1216 const BRect& updateRect, const rgb_color& base, int32 count, 1217 hash_mark_location location, uint32 flags, enum orientation orientation) 1218 { 1219 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1220 return; 1221 1222 rgb_color lightColor; 1223 rgb_color darkColor; 1224 1225 if ((flags & B_DISABLED) != 0) { 1226 lightColor = tint_color(base, 0.9); 1227 darkColor = tint_color(base, 1.07); 1228 } else { 1229 lightColor = tint_color(base, 0.8); 1230 darkColor = tint_color(base, 1.14); 1231 } 1232 1233 int32 hashMarkCount = max_c(count, 2); 1234 // draw at least two hashmarks at min/max if 1235 // fHashMarks != B_HASH_MARKS_NONE 1236 float factor; 1237 float startPos; 1238 if (orientation == B_HORIZONTAL) { 1239 factor = (rect.Width() - 2) / (hashMarkCount - 1); 1240 startPos = rect.left + 1; 1241 } else { 1242 factor = (rect.Height() - 2) / (hashMarkCount - 1); 1243 startPos = rect.top + 1; 1244 } 1245 1246 if (location & B_HASH_MARKS_TOP) { 1247 view->BeginLineArray(hashMarkCount * 2); 1248 1249 if (orientation == B_HORIZONTAL) { 1250 float pos = startPos; 1251 for (int32 i = 0; i < hashMarkCount; i++) { 1252 view->AddLine(BPoint(pos, rect.top), 1253 BPoint(pos, rect.top + 4), darkColor); 1254 view->AddLine(BPoint(pos + 1, rect.top), 1255 BPoint(pos + 1, rect.top + 4), lightColor); 1256 1257 pos += factor; 1258 } 1259 } else { 1260 float pos = startPos; 1261 for (int32 i = 0; i < hashMarkCount; i++) { 1262 view->AddLine(BPoint(rect.left, pos), 1263 BPoint(rect.left + 4, pos), darkColor); 1264 view->AddLine(BPoint(rect.left, pos + 1), 1265 BPoint(rect.left + 4, pos + 1), lightColor); 1266 1267 pos += factor; 1268 } 1269 } 1270 1271 view->EndLineArray(); 1272 } 1273 1274 if (location & B_HASH_MARKS_BOTTOM) { 1275 1276 view->BeginLineArray(hashMarkCount * 2); 1277 1278 if (orientation == B_HORIZONTAL) { 1279 float pos = startPos; 1280 for (int32 i = 0; i < hashMarkCount; i++) { 1281 view->AddLine(BPoint(pos, rect.bottom - 4), 1282 BPoint(pos, rect.bottom), darkColor); 1283 view->AddLine(BPoint(pos + 1, rect.bottom - 4), 1284 BPoint(pos + 1, rect.bottom), lightColor); 1285 1286 pos += factor; 1287 } 1288 } else { 1289 float pos = startPos; 1290 for (int32 i = 0; i < hashMarkCount; i++) { 1291 view->AddLine(BPoint(rect.right - 4, pos), 1292 BPoint(rect.right, pos), darkColor); 1293 view->AddLine(BPoint(rect.right - 4, pos + 1), 1294 BPoint(rect.right, pos + 1), lightColor); 1295 1296 pos += factor; 1297 } 1298 } 1299 1300 view->EndLineArray(); 1301 } 1302 } 1303 1304 1305 void 1306 BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, 1307 const rgb_color& base, uint32 flags, uint32 borders) 1308 { 1309 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1310 return; 1311 1312 // clipping constraints for the view 1313 BRegion clipping; 1314 view->GetClippingRegion(&clipping); 1315 1316 // intersect constraints with updateRect 1317 BRegion updateClipping(updateRect); 1318 clipping.IntersectWith(&updateClipping); 1319 1320 // clip to the intersection 1321 view->ConstrainClippingRegion(&clipping); 1322 1323 rgb_color edgeShadowColor; 1324 rgb_color edgeLightColor; 1325 rgb_color frameShadowColor; 1326 rgb_color frameLightColor; 1327 rgb_color bevelShadowColor; 1328 rgb_color bevelLightColor; 1329 BGradientLinear fillGradient; 1330 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1331 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1332 1333 if ((flags & B_DISABLED) != 0) { 1334 edgeLightColor = base; 1335 edgeShadowColor = base; 1336 frameLightColor = tint_color(base, 1.25); 1337 frameShadowColor = tint_color(base, 1.30); 1338 bevelLightColor = tint_color(base, 0.8); 1339 bevelShadowColor = tint_color(base, 1.07); 1340 fillGradient.AddColor(tint_color(base, 0.85), 0); 1341 fillGradient.AddColor(base, 255); 1342 } else { 1343 edgeLightColor = tint_color(base, 0.80); 1344 edgeShadowColor = tint_color(base, 1.03); 1345 frameLightColor = tint_color(base, 1.30); 1346 frameShadowColor = tint_color(base, 1.30); 1347 bevelLightColor = tint_color(base, 0.6); 1348 bevelShadowColor = tint_color(base, 1.07); 1349 fillGradient.AddColor(tint_color(base, 0.75), 0); 1350 fillGradient.AddColor(tint_color(base, 1.03), 255); 1351 } 1352 1353 static const float kRoundCornerRadius = 4.0f; 1354 1355 // left top corner dimensions 1356 BRect leftTopCorner(rect); 1357 leftTopCorner.right = floorf(leftTopCorner.left + kRoundCornerRadius); 1358 leftTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); 1359 clipping.Exclude(leftTopCorner); 1360 1361 // draw the left top corner 1362 _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, 1363 edgeShadowColor, frameLightColor, bevelLightColor, 1364 fillGradient); 1365 1366 // right top corner dimensions 1367 BRect rightTopCorner(rect); 1368 rightTopCorner.right = floorf(rect.right); 1369 rightTopCorner.left = floorf(rightTopCorner.right - kRoundCornerRadius); 1370 rightTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); 1371 clipping.Exclude(rightTopCorner); 1372 1373 // draw the right top corner 1374 _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, 1375 edgeShadowColor, edgeLightColor, frameLightColor, 1376 frameShadowColor, bevelLightColor, bevelShadowColor, 1377 fillGradient); 1378 1379 // clip out the corners 1380 view->ConstrainClippingRegion(&clipping); 1381 1382 // draw the rest of frame and fill 1383 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1384 edgeLightColor, 1385 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1386 if ((borders & B_LEFT_BORDER) == 0) 1387 rect.left++; 1388 if ((borders & B_RIGHT_BORDER) == 0) 1389 rect.right--; 1390 1391 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1392 frameShadowColor, B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); 1393 1394 _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, 1395 bevelShadowColor); 1396 1397 view->FillRect(rect, fillGradient); 1398 1399 // reset clipping constraints 1400 view->ConstrainClippingRegion(NULL); 1401 } 1402 1403 1404 void 1405 BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, 1406 const rgb_color& base, uint32 flags, uint32 borders) 1407 { 1408 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1409 return; 1410 1411 rgb_color edgeShadowColor; 1412 rgb_color edgeLightColor; 1413 rgb_color frameShadowColor; 1414 rgb_color frameLightColor; 1415 rgb_color bevelShadowColor; 1416 rgb_color bevelLightColor; 1417 BGradientLinear fillGradient; 1418 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1419 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1420 1421 if ((flags & B_DISABLED) != 0) { 1422 edgeLightColor = base; 1423 edgeShadowColor = base; 1424 frameLightColor = tint_color(base, 1.25); 1425 frameShadowColor = tint_color(base, 1.30); 1426 bevelLightColor = tint_color(base, 0.8); 1427 bevelShadowColor = tint_color(base, 1.07); 1428 fillGradient.AddColor(tint_color(base, 0.85), 0); 1429 fillGradient.AddColor(base, 255); 1430 } else { 1431 edgeLightColor = tint_color(base, 0.80); 1432 edgeShadowColor = tint_color(base, 1.03); 1433 frameLightColor = tint_color(base, 1.30); 1434 frameShadowColor = tint_color(base, 1.30); 1435 bevelLightColor = tint_color(base, 1.10); 1436 bevelShadowColor = tint_color(base, 1.17); 1437 fillGradient.AddColor(tint_color(base, 1.12), 0); 1438 fillGradient.AddColor(tint_color(base, 1.08), 255); 1439 } 1440 1441 // active tabs stand out at the top, but this is an inactive tab 1442 view->SetHighColor(base); 1443 view->FillRect(BRect(rect.left, rect.top, rect.right, rect.top + 4)); 1444 rect.top += 4; 1445 1446 // frame and fill 1447 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1448 edgeLightColor, 1449 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1450 1451 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1452 frameShadowColor, 1453 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1454 1455 if (rect.IsValid()) { 1456 _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, 1457 bevelLightColor, bevelLightColor, B_LEFT_BORDER & ~borders); 1458 } else { 1459 if ((B_LEFT_BORDER & ~borders) != 0) 1460 rect.left++; 1461 } 1462 1463 view->FillRect(rect, fillGradient); 1464 } 1465 1466 1467 void 1468 BControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, 1469 const rgb_color& base, enum orientation orientation, uint32 flags, 1470 uint32 borders) 1471 { 1472 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1473 return; 1474 1475 rgb_color background; 1476 if ((flags & (B_CLICKED | B_ACTIVATED)) != 0) 1477 background = tint_color(base, B_DARKEN_1_TINT); 1478 else 1479 background = base; 1480 1481 rgb_color light = tint_color(background, 0.6); 1482 rgb_color shadow = tint_color(background, 1.21); 1483 1484 // frame 1485 if (borders != 0 && rect.Width() > 3 && rect.Height() > 3) 1486 DrawRaisedBorder(view, rect, updateRect, background, flags, borders); 1487 1488 // dots and rest of background 1489 if (orientation == B_HORIZONTAL) { 1490 if (rect.Width() > 2) { 1491 // background on left/right 1492 BRegion region(rect); 1493 rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5); 1494 rect.right = rect.left + 1; 1495 region.Exclude(rect); 1496 view->SetHighColor(background); 1497 view->FillRegion(®ion); 1498 } 1499 1500 BPoint dot = rect.LeftTop(); 1501 BPoint stop = rect.LeftBottom(); 1502 int32 num = 1; 1503 while (dot.y <= stop.y) { 1504 rgb_color col1; 1505 rgb_color col2; 1506 switch (num) { 1507 case 1: 1508 col1 = background; 1509 col2 = background; 1510 break; 1511 case 2: 1512 col1 = shadow; 1513 col2 = background; 1514 break; 1515 case 3: 1516 default: 1517 col1 = background; 1518 col2 = light; 1519 num = 0; 1520 break; 1521 } 1522 view->SetHighColor(col1); 1523 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1524 view->SetHighColor(col2); 1525 dot.x++; 1526 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1527 dot.x -= 1.0; 1528 // next pixel 1529 num++; 1530 dot.y++; 1531 } 1532 } else { 1533 if (rect.Height() > 2) { 1534 // background on left/right 1535 BRegion region(rect); 1536 rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5); 1537 rect.bottom = rect.top + 1; 1538 region.Exclude(rect); 1539 view->SetHighColor(background); 1540 view->FillRegion(®ion); 1541 } 1542 1543 BPoint dot = rect.LeftTop(); 1544 BPoint stop = rect.RightTop(); 1545 int32 num = 1; 1546 while (dot.x <= stop.x) { 1547 rgb_color col1; 1548 rgb_color col2; 1549 switch (num) { 1550 case 1: 1551 col1 = background; 1552 col2 = background; 1553 break; 1554 case 2: 1555 col1 = shadow; 1556 col2 = background; 1557 break; 1558 case 3: 1559 default: 1560 col1 = background; 1561 col2 = light; 1562 num = 0; 1563 break; 1564 } 1565 view->SetHighColor(col1); 1566 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1567 view->SetHighColor(col2); 1568 dot.y++; 1569 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1570 dot.y -= 1.0; 1571 // next pixel 1572 num++; 1573 dot.x++; 1574 } 1575 } 1576 } 1577 1578 1579 // #pragma mark - 1580 1581 1582 void 1583 BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, 1584 const rgb_color& base, border_style border, uint32 flags, uint32 borders) 1585 { 1586 if (border == B_NO_BORDER) 1587 return; 1588 1589 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 1590 if ((flags & B_FOCUSED) != 0) 1591 scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1592 1593 if (border == B_FANCY_BORDER) 1594 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 1595 1596 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 1597 scrollbarFrameColor, scrollbarFrameColor, borders); 1598 } 1599 1600 1601 void 1602 BControlLook::DrawRaisedBorder(BView* view, BRect& rect, 1603 const BRect& updateRect, const rgb_color& base, uint32 flags, 1604 uint32 borders) 1605 { 1606 rgb_color lightColor; 1607 rgb_color shadowColor; 1608 1609 if ((flags & B_DISABLED) != 0) { 1610 lightColor = base; 1611 shadowColor = base; 1612 } else { 1613 lightColor = tint_color(base, 0.85); 1614 shadowColor = tint_color(base, 1.07); 1615 } 1616 1617 _DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor, 1618 borders); 1619 } 1620 1621 1622 void 1623 BControlLook::DrawTextControlBorder(BView* view, BRect& rect, 1624 const BRect& updateRect, const rgb_color& base, uint32 flags, 1625 uint32 borders) 1626 { 1627 if (!rect.Intersects(updateRect)) 1628 return; 1629 1630 rgb_color dark1BorderColor; 1631 rgb_color dark2BorderColor; 1632 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1633 1634 if ((flags & B_DISABLED) != 0) { 1635 _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders); 1636 1637 if ((flags & B_BLEND_FRAME) != 0) 1638 dark1BorderColor = (rgb_color){ 0, 0, 0, 40 }; 1639 else 1640 dark1BorderColor = tint_color(base, 1.15); 1641 dark2BorderColor = dark1BorderColor; 1642 } else if ((flags & B_CLICKED) != 0) { 1643 dark1BorderColor = tint_color(base, 1.50); 1644 dark2BorderColor = tint_color(base, 1.49); 1645 1646 // BCheckBox uses this to indicate the clicked state... 1647 _DrawFrame(view, rect, 1648 dark1BorderColor, dark1BorderColor, 1649 dark2BorderColor, dark2BorderColor); 1650 1651 dark2BorderColor = dark1BorderColor; 1652 } else { 1653 _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders); 1654 1655 if ((flags & B_BLEND_FRAME) != 0) { 1656 dark1BorderColor = (rgb_color){ 0, 0, 0, 102 }; 1657 dark2BorderColor = (rgb_color){ 0, 0, 0, 97 }; 1658 } else { 1659 dark1BorderColor = tint_color(base, 1.40); 1660 dark2BorderColor = tint_color(base, 1.38); 1661 } 1662 } 1663 1664 if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED) != 0) { 1665 dark1BorderColor = navigationColor; 1666 dark2BorderColor = navigationColor; 1667 } 1668 1669 if ((flags & B_BLEND_FRAME) != 0) { 1670 drawing_mode oldMode = view->DrawingMode(); 1671 view->SetDrawingMode(B_OP_ALPHA); 1672 1673 _DrawFrame(view, rect, 1674 dark1BorderColor, dark1BorderColor, 1675 dark2BorderColor, dark2BorderColor, borders); 1676 1677 view->SetDrawingMode(oldMode); 1678 } else { 1679 _DrawFrame(view, rect, 1680 dark1BorderColor, dark1BorderColor, 1681 dark2BorderColor, dark2BorderColor, borders); 1682 } 1683 } 1684 1685 1686 void 1687 BControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, 1688 const rgb_color& base, uint32 borders) 1689 { 1690 rgb_color frameColor = tint_color(base, 1.30); 1691 rgb_color bevelLight = tint_color(base, 0.8); 1692 rgb_color bevelShadow = tint_color(base, 1.03); 1693 1694 _DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight, 1695 borders); 1696 1697 _DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor, 1698 borders); 1699 1700 _DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow, 1701 borders); 1702 } 1703 1704 1705 void 1706 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1707 const BRect& updateRect, const rgb_color& base, uint32 flags) 1708 { 1709 DrawLabel(view, label, rect, updateRect, base, flags, 1710 DefaultLabelAlignment()); 1711 } 1712 1713 1714 void 1715 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1716 const BRect& updateRect, const rgb_color& base, uint32 flags, 1717 const BAlignment& alignment) 1718 { 1719 if (!rect.Intersects(updateRect)) 1720 return; 1721 1722 // truncate the label if necessary and get the width and height 1723 BString truncatedLabel(label); 1724 1725 BFont font; 1726 view->GetFont(&font); 1727 1728 float width = rect.Width(); 1729 font.TruncateString(&truncatedLabel, B_TRUNCATE_END, width); 1730 width = font.StringWidth(truncatedLabel.String()); 1731 1732 font_height fontHeight; 1733 font.GetHeight(&fontHeight); 1734 float height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); 1735 1736 // handle alignment 1737 BPoint location; 1738 1739 switch (alignment.horizontal) { 1740 default: 1741 case B_ALIGN_LEFT: 1742 location.x = rect.left; 1743 break; 1744 case B_ALIGN_RIGHT: 1745 location.x = rect.right - width; 1746 break; 1747 case B_ALIGN_CENTER: 1748 location.x = (rect.left + rect.right - width) / 2.0f; 1749 break; 1750 } 1751 1752 switch (alignment.vertical) { 1753 case B_ALIGN_TOP: 1754 location.y = rect.top + ceilf(fontHeight.ascent); 1755 break; 1756 default: 1757 case B_ALIGN_MIDDLE: 1758 location.y = floorf((rect.top + rect.bottom - height) / 2.0f + 0.5f) 1759 + ceilf(fontHeight.ascent); 1760 break; 1761 case B_ALIGN_BOTTOM: 1762 location.y = rect.bottom - ceilf(fontHeight.descent); 1763 break; 1764 } 1765 1766 DrawLabel(view, truncatedLabel.String(), base, flags, location); 1767 } 1768 1769 1770 void 1771 BControlLook::DrawLabel(BView* view, const char* label, const rgb_color& base, 1772 uint32 flags, const BPoint& where) 1773 { 1774 // setup the text color 1775 // TODO: Should either use the ui_color(B_CONTROL_TEXT_COLOR) here, 1776 // or elliminate that constant alltogether (stippi: +1). 1777 1778 BWindow* window = view->Window(); 1779 bool isDesktop = window 1780 && window->Feel() == kPrivateDesktopWindowFeel 1781 && window->Look() == kPrivateDesktopWindowLook 1782 && view->Parent() 1783 && view->Parent()->Parent() == NULL 1784 && (flags & B_IGNORE_OUTLINE) == 0; 1785 1786 rgb_color low; 1787 rgb_color color; 1788 rgb_color glowColor; 1789 1790 if (isDesktop) 1791 low = view->Parent()->ViewColor(); 1792 else 1793 low = base; 1794 1795 if (low.red + low.green + low.blue > 128 * 3) { 1796 color = tint_color(low, B_DARKEN_MAX_TINT); 1797 glowColor = kWhite; 1798 } else { 1799 color = tint_color(low, B_LIGHTEN_MAX_TINT); 1800 glowColor = kBlack; 1801 } 1802 1803 if ((flags & B_DISABLED) != 0) { 1804 color.red = (uint8)(((int32)low.red + color.red + 1) / 2); 1805 color.green = (uint8)(((int32)low.green + color.green + 1) / 2); 1806 color.blue = (uint8)(((int32)low.blue + color.blue + 1) / 2); 1807 } 1808 1809 drawing_mode oldMode = view->DrawingMode(); 1810 1811 if (isDesktop) { 1812 // drawing occurs on the desktop 1813 if (fCachedWorkspace != current_workspace()) { 1814 int8 indice = 0; 1815 int32 mask; 1816 bool tmpOutline; 1817 while (fBackgroundInfo.FindInt32("be:bgndimginfoworkspaces", 1818 indice, &mask) == B_OK 1819 && fBackgroundInfo.FindBool("be:bgndimginfoerasetext", 1820 indice, &tmpOutline) == B_OK) { 1821 1822 if (((1 << current_workspace()) & mask) != 0) { 1823 fCachedOutline = tmpOutline; 1824 fCachedWorkspace = current_workspace(); 1825 break; 1826 } 1827 indice++; 1828 } 1829 } 1830 1831 if (fCachedOutline) { 1832 BFont font; 1833 view->GetFont(&font); 1834 1835 view->SetDrawingMode(B_OP_ALPHA); 1836 view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); 1837 // Draw glow or outline 1838 if (glowColor == kWhite) { 1839 font.SetFalseBoldWidth(2.0); 1840 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1841 1842 glowColor.alpha = 30; 1843 view->SetHighColor(glowColor); 1844 view->DrawString(label, where); 1845 1846 font.SetFalseBoldWidth(1.0); 1847 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1848 1849 glowColor.alpha = 65; 1850 view->SetHighColor(glowColor); 1851 view->DrawString(label, where); 1852 1853 font.SetFalseBoldWidth(0.0); 1854 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1855 } else if (glowColor == kBlack) { 1856 font.SetFalseBoldWidth(1.0); 1857 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1858 1859 glowColor.alpha = 30; 1860 view->SetHighColor(glowColor); 1861 view->DrawString(label, where); 1862 1863 font.SetFalseBoldWidth(0.0); 1864 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 1865 1866 glowColor.alpha = 200; 1867 view->SetHighColor(glowColor); 1868 view->DrawString(label, BPoint(where.x + 1, where.y + 1)); 1869 } 1870 } 1871 } 1872 1873 view->SetHighColor(color); 1874 view->SetDrawingMode(B_OP_OVER); 1875 view->DrawString(label, where); 1876 view->SetDrawingMode(oldMode); 1877 } 1878 1879 1880 void 1881 BControlLook::SetBackgroundInfo(const BMessage& backgroundInfo) 1882 { 1883 fBackgroundInfo = backgroundInfo; 1884 fCachedWorkspace = -1; 1885 } 1886 1887 1888 // #pragma mark - 1889 1890 1891 void 1892 BControlLook::_DrawButtonFrame(BView* view, BRect& rect, 1893 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 1894 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 1895 const rgb_color& background, float contrast, float brightness, 1896 uint32 flags, uint32 borders) 1897 { 1898 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1899 return; 1900 1901 // clipping constraints for the view 1902 BRegion clipping; 1903 view->GetClippingRegion(&clipping); 1904 1905 // intersect constraints with updateRect 1906 BRegion updateClipping(updateRect); 1907 clipping.IntersectWith(&updateClipping); 1908 1909 // clip to the intersection 1910 view->ConstrainClippingRegion(&clipping); 1911 1912 // outer edge colors 1913 rgb_color edgeLightColor; 1914 rgb_color edgeShadowColor; 1915 1916 // default button frame color 1917 // TODO: B_BLEND_FRAME 1918 float defaultIndicatorTint = 1.2; 1919 if ((flags & B_DISABLED) != 0) 1920 defaultIndicatorTint = (B_NO_TINT + defaultIndicatorTint) / 2; 1921 1922 rgb_color defaultIndicatorColor = tint_color(base, defaultIndicatorTint); 1923 rgb_color cornerBgColor; 1924 1925 drawing_mode oldMode = view->DrawingMode(); 1926 1927 if ((flags & B_DEFAULT_BUTTON) != 0) { 1928 cornerBgColor = defaultIndicatorColor; 1929 edgeLightColor = _EdgeLightColor(defaultIndicatorColor, 1930 contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), 1931 brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); 1932 edgeShadowColor = _EdgeShadowColor(defaultIndicatorColor, 1933 contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), 1934 brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); 1935 1936 // draw default button indicator 1937 view->SetHighColor(background); 1938 view->FillRect(rect); 1939 view->SetHighColor(base); 1940 view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); 1941 rect.InsetBy(1, 1); 1942 1943 view->SetHighColor(defaultIndicatorColor); 1944 view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); 1945 rect.InsetBy(1, 1); 1946 1947 view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); 1948 rect.InsetBy(1, 1); 1949 } else { 1950 cornerBgColor = background; 1951 if ((flags & B_BLEND_FRAME) != 0) { 1952 // set the background color to transparent for the case 1953 // that we are on the desktop 1954 cornerBgColor.alpha = 0; 1955 view->SetDrawingMode(B_OP_ALPHA); 1956 } 1957 1958 edgeLightColor = _EdgeLightColor(background, 1959 contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), 1960 brightness * 1.0, flags); 1961 edgeShadowColor = _EdgeShadowColor(background, 1962 contrast * (flags & B_DISABLED) != 0 ? 0.0 : 1.0, 1963 brightness * 1.0, flags); 1964 } 1965 1966 // frame colors 1967 rgb_color frameLightColor = _FrameLightColor(base, flags); 1968 rgb_color frameShadowColor = _FrameShadowColor(base, flags); 1969 1970 // rounded corners 1971 1972 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 1973 && leftTopRadius > 0) { 1974 // draw left top rounded corner 1975 BRect leftTopCorner(floorf(rect.left), floorf(rect.top), 1976 floorf(rect.left + leftTopRadius), 1977 floorf(rect.top + leftTopRadius)); 1978 clipping.Exclude(leftTopCorner); 1979 _DrawRoundCornerFrameLeftTop(view, leftTopCorner, updateRect, 1980 cornerBgColor, edgeShadowColor, frameLightColor); 1981 } 1982 1983 if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 1984 && rightTopRadius > 0) { 1985 // draw right top rounded corner 1986 BRect rightTopCorner(floorf(rect.right - rightTopRadius), 1987 floorf(rect.top), floorf(rect.right), 1988 floorf(rect.top + rightTopRadius)); 1989 clipping.Exclude(rightTopCorner); 1990 _DrawRoundCornerFrameRightTop(view, rightTopCorner, updateRect, 1991 cornerBgColor, edgeShadowColor, edgeLightColor, 1992 frameLightColor, frameShadowColor); 1993 } 1994 1995 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 1996 && leftBottomRadius > 0) { 1997 // draw left bottom rounded corner 1998 BRect leftBottomCorner(floorf(rect.left), 1999 floorf(rect.bottom - leftBottomRadius), 2000 floorf(rect.left + leftBottomRadius), floorf(rect.bottom)); 2001 clipping.Exclude(leftBottomCorner); 2002 _DrawRoundCornerFrameLeftBottom(view, leftBottomCorner, updateRect, 2003 cornerBgColor, edgeShadowColor, edgeLightColor, 2004 frameLightColor, frameShadowColor); 2005 } 2006 2007 if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2008 && rightBottomRadius > 0) { 2009 // draw right bottom rounded corner 2010 BRect rightBottomCorner(floorf(rect.right - rightBottomRadius), 2011 floorf(rect.bottom - rightBottomRadius), floorf(rect.right), 2012 floorf(rect.bottom)); 2013 clipping.Exclude(rightBottomCorner); 2014 _DrawRoundCornerFrameRightBottom(view, rightBottomCorner, 2015 updateRect, cornerBgColor, edgeLightColor, frameShadowColor); 2016 } 2017 2018 // clip out the corners 2019 view->ConstrainClippingRegion(&clipping); 2020 2021 // draw outer edge 2022 if ((flags & B_DEFAULT_BUTTON) != 0) { 2023 _DrawOuterResessedFrame(view, rect, defaultIndicatorColor, 2024 contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), 2025 brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), 2026 flags, borders); 2027 } else { 2028 _DrawOuterResessedFrame(view, rect, background, 2029 contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), 2030 brightness * 1.0, flags, borders); 2031 } 2032 2033 view->SetDrawingMode(oldMode); 2034 2035 // draw frame 2036 if ((flags & B_BLEND_FRAME) != 0) { 2037 drawing_mode oldDrawingMode = view->DrawingMode(); 2038 view->SetDrawingMode(B_OP_ALPHA); 2039 2040 _DrawFrame(view, rect, frameLightColor, frameLightColor, 2041 frameShadowColor, frameShadowColor, borders); 2042 2043 view->SetDrawingMode(oldDrawingMode); 2044 } else { 2045 _DrawFrame(view, rect, frameLightColor, frameLightColor, 2046 frameShadowColor, frameShadowColor, borders); 2047 } 2048 2049 view->ConstrainClippingRegion(NULL); 2050 } 2051 2052 2053 void 2054 BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, 2055 const rgb_color& base, float contrast, float brightness, uint32 flags, 2056 uint32 borders) 2057 { 2058 rgb_color edgeLightColor = _EdgeLightColor(base, contrast, 2059 brightness, flags); 2060 rgb_color edgeShadowColor = _EdgeShadowColor(base, contrast, 2061 brightness, flags); 2062 2063 if ((flags & B_BLEND_FRAME) != 0) { 2064 // assumes the background has already been painted 2065 drawing_mode oldDrawingMode = view->DrawingMode(); 2066 view->SetDrawingMode(B_OP_ALPHA); 2067 2068 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, 2069 edgeLightColor, edgeLightColor, borders); 2070 2071 view->SetDrawingMode(oldDrawingMode); 2072 } else { 2073 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, 2074 edgeLightColor, edgeLightColor, borders); 2075 } 2076 } 2077 2078 2079 void 2080 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 2081 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 2082 uint32 borders) 2083 { 2084 view->BeginLineArray(4); 2085 2086 if (borders & B_LEFT_BORDER) { 2087 view->AddLine( 2088 BPoint(rect.left, rect.bottom), 2089 BPoint(rect.left, rect.top), left); 2090 rect.left++; 2091 } 2092 if (borders & B_TOP_BORDER) { 2093 view->AddLine( 2094 BPoint(rect.left, rect.top), 2095 BPoint(rect.right, rect.top), top); 2096 rect.top++; 2097 } 2098 if (borders & B_RIGHT_BORDER) { 2099 view->AddLine( 2100 BPoint(rect.right, rect.top), 2101 BPoint(rect.right, rect.bottom), right); 2102 rect.right--; 2103 } 2104 if (borders & B_BOTTOM_BORDER) { 2105 view->AddLine( 2106 BPoint(rect.left, rect.bottom), 2107 BPoint(rect.right, rect.bottom), bottom); 2108 rect.bottom--; 2109 } 2110 2111 view->EndLineArray(); 2112 } 2113 2114 2115 void 2116 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 2117 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 2118 const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders) 2119 { 2120 view->BeginLineArray(6); 2121 2122 if (borders & B_TOP_BORDER) { 2123 if (borders & B_RIGHT_BORDER) { 2124 view->AddLine( 2125 BPoint(rect.left, rect.top), 2126 BPoint(rect.right - 1, rect.top), top); 2127 view->AddLine( 2128 BPoint(rect.right, rect.top), 2129 BPoint(rect.right, rect.top), rightTop); 2130 } else { 2131 view->AddLine( 2132 BPoint(rect.left, rect.top), 2133 BPoint(rect.right, rect.top), top); 2134 } 2135 rect.top++; 2136 } 2137 2138 if (borders & B_LEFT_BORDER) { 2139 view->AddLine( 2140 BPoint(rect.left, rect.top), 2141 BPoint(rect.left, rect.bottom - 1), left); 2142 view->AddLine( 2143 BPoint(rect.left, rect.bottom), 2144 BPoint(rect.left, rect.bottom), leftBottom); 2145 rect.left++; 2146 } 2147 2148 if (borders & B_BOTTOM_BORDER) { 2149 view->AddLine( 2150 BPoint(rect.left, rect.bottom), 2151 BPoint(rect.right, rect.bottom), bottom); 2152 rect.bottom--; 2153 } 2154 2155 if (borders & B_RIGHT_BORDER) { 2156 view->AddLine( 2157 BPoint(rect.right, rect.bottom), 2158 BPoint(rect.right, rect.top), right); 2159 rect.right--; 2160 } 2161 2162 view->EndLineArray(); 2163 } 2164 2165 2166 void 2167 BControlLook::_DrawButtonBackground(BView* view, BRect& rect, 2168 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2169 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2170 uint32 flags, uint32 borders, enum orientation orientation) 2171 { 2172 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2173 return; 2174 2175 // clipping constraints for the view 2176 BRegion clipping; 2177 view->GetClippingRegion(&clipping); 2178 2179 // intersect constraints with updateRect 2180 BRegion updateClipping(updateRect); 2181 clipping.IntersectWith(&updateClipping); 2182 2183 // clip to the intersection 2184 view->ConstrainClippingRegion(&clipping); 2185 2186 // inner bevel colors 2187 rgb_color bevelLightColor = _BevelLightColor(base, flags); 2188 rgb_color bevelShadowColor = _BevelShadowColor(base, flags); 2189 2190 // button background color 2191 rgb_color buttonBgColor; 2192 if ((flags & B_DISABLED) != 0) 2193 buttonBgColor = tint_color(base, 0.7); 2194 else 2195 buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT); 2196 2197 // surface top gradient 2198 BGradientLinear fillGradient; 2199 _MakeButtonGradient(fillGradient, rect, base, flags, orientation); 2200 2201 // rounded corners 2202 2203 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 2204 && leftTopRadius > 0) { 2205 // draw left top rounded corner 2206 BRect leftTopCorner(floorf(rect.left), floorf(rect.top), 2207 floorf(rect.left + leftTopRadius - 2.0), 2208 floorf(rect.top + leftTopRadius - 2.0)); 2209 clipping.Exclude(leftTopCorner); 2210 _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, 2211 bevelLightColor, fillGradient); 2212 } 2213 2214 if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 2215 && rightTopRadius > 0) { 2216 // draw right top rounded corner 2217 BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), 2218 floorf(rect.top), floorf(rect.right), 2219 floorf(rect.top + rightTopRadius - 2.0)); 2220 clipping.Exclude(rightTopCorner); 2221 _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, 2222 updateRect, bevelLightColor, bevelShadowColor, fillGradient); 2223 } 2224 2225 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2226 && leftBottomRadius > 0) { 2227 // draw left bottom rounded corner 2228 BRect leftBottomCorner(floorf(rect.left), 2229 floorf(rect.bottom - leftBottomRadius + 2.0), 2230 floorf(rect.left + leftBottomRadius - 2.0), 2231 floorf(rect.bottom)); 2232 clipping.Exclude(leftBottomCorner); 2233 _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, 2234 updateRect, bevelLightColor, bevelShadowColor, fillGradient); 2235 } 2236 2237 if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2238 && rightBottomRadius > 0) { 2239 // draw right bottom rounded corner 2240 BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), 2241 floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), 2242 floorf(rect.bottom)); 2243 clipping.Exclude(rightBottomCorner); 2244 _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, 2245 updateRect, bevelShadowColor, fillGradient); 2246 } 2247 2248 // clip out the corners 2249 view->ConstrainClippingRegion(&clipping); 2250 2251 // draw inner bevel 2252 2253 if ((flags & B_ACTIVATED) != 0) { 2254 view->BeginLineArray(4); 2255 2256 // shadow along left/top borders 2257 if (borders & B_LEFT_BORDER) { 2258 view->AddLine(BPoint(rect.left, rect.top), 2259 BPoint(rect.left, rect.bottom), bevelLightColor); 2260 rect.left++; 2261 } 2262 if (borders & B_TOP_BORDER) { 2263 view->AddLine(BPoint(rect.left, rect.top), 2264 BPoint(rect.right, rect.top), bevelLightColor); 2265 rect.top++; 2266 } 2267 2268 // softer shadow along left/top borders 2269 if (borders & B_LEFT_BORDER) { 2270 view->AddLine(BPoint(rect.left, rect.top), 2271 BPoint(rect.left, rect.bottom), bevelShadowColor); 2272 rect.left++; 2273 } 2274 if (borders & B_TOP_BORDER) { 2275 view->AddLine(BPoint(rect.left, rect.top), 2276 BPoint(rect.right, rect.top), bevelShadowColor); 2277 rect.top++; 2278 } 2279 2280 view->EndLineArray(); 2281 } else { 2282 _DrawFrame(view, rect, 2283 bevelLightColor, bevelLightColor, 2284 bevelShadowColor, bevelShadowColor, 2285 buttonBgColor, buttonBgColor, borders); 2286 } 2287 2288 // fill in the background 2289 view->FillRect(rect, fillGradient); 2290 2291 // reset clipping constraints 2292 view->ConstrainClippingRegion(NULL); 2293 } 2294 2295 2296 void 2297 BControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect, 2298 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2299 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2300 bool popupIndicator, uint32 flags) 2301 { 2302 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2303 return; 2304 2305 if (popupIndicator) { 2306 BRect leftRect(rect); 2307 leftRect.right -= 10; 2308 2309 BRect rightRect(rect); 2310 rightRect.left = rightRect.right - 9; 2311 2312 _DrawMenuFieldBackgroundInside(view, leftRect, updateRect, 2313 leftTopRadius, 0.0f, leftBottomRadius, 0.0f, base, flags, 2314 B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); 2315 2316 _DrawMenuFieldBackgroundInside(view, rightRect, updateRect, 2317 0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, 2318 B_TOP_BORDER | B_RIGHT_BORDER | B_BOTTOM_BORDER); 2319 2320 // popup marker 2321 BPoint center(roundf((rightRect.left + rightRect.right) / 2.0), 2322 roundf((rightRect.top + rightRect.bottom) / 2.0)); 2323 BPoint triangle[3]; 2324 triangle[0] = center + BPoint(-2.5, -0.5); 2325 triangle[1] = center + BPoint(2.5, -0.5); 2326 triangle[2] = center + BPoint(0.0, 2.0); 2327 2328 uint32 viewFlags = view->Flags(); 2329 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 2330 2331 rgb_color markColor; 2332 if ((flags & B_DISABLED) != 0) 2333 markColor = tint_color(base, 1.35); 2334 else 2335 markColor = tint_color(base, 1.65); 2336 2337 view->SetHighColor(markColor); 2338 view->FillTriangle(triangle[0], triangle[1], triangle[2]); 2339 2340 // draw a line on the left of the popup frame 2341 rgb_color bevelShadowColor = _BevelShadowColor(base, flags); 2342 view->SetHighColor(bevelShadowColor); 2343 BPoint leftTopCorner(floorf(rightRect.left - 1.0), 2344 floorf(rightRect.top - 1.0)); 2345 BPoint leftBottomCorner(floorf(rightRect.left - 1.0), 2346 floorf(rightRect.bottom + 1.0)); 2347 view->StrokeLine(leftTopCorner, leftBottomCorner); 2348 2349 view->SetFlags(viewFlags); 2350 2351 rect = leftRect; 2352 } else { 2353 _DrawMenuFieldBackgroundInside(view, rect, updateRect, leftTopRadius, 2354 rightTopRadius, leftBottomRadius, rightBottomRadius, base, flags); 2355 } 2356 } 2357 2358 2359 void 2360 BControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, 2361 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2362 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2363 uint32 flags, uint32 borders) 2364 { 2365 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2366 return; 2367 2368 // clipping constraints for the view 2369 BRegion clipping; 2370 view->GetClippingRegion(&clipping); 2371 2372 // intersect constraints with updateRect 2373 BRegion updateClipping(updateRect); 2374 clipping.IntersectWith(&updateClipping); 2375 2376 // clip to the intersection 2377 view->ConstrainClippingRegion(&clipping); 2378 2379 // frame colors 2380 rgb_color frameLightColor = _FrameLightColor(base, flags); 2381 rgb_color frameShadowColor = _FrameShadowColor(base, flags); 2382 2383 // indicator background color 2384 rgb_color indicatorBase; 2385 if ((borders & B_LEFT_BORDER) != 0) 2386 indicatorBase = base; 2387 else { 2388 if ((flags & B_DISABLED) != 0) 2389 indicatorBase = tint_color(base, 1.05); 2390 else 2391 indicatorBase = tint_color(base, 1.12); 2392 } 2393 2394 // bevel colors 2395 rgb_color cornerColor = tint_color(indicatorBase, 0.85); 2396 rgb_color bevelColor1 = tint_color(indicatorBase, 0.3); 2397 rgb_color bevelColor2 = tint_color(indicatorBase, 0.5); 2398 rgb_color bevelColor3 = tint_color(indicatorBase, 1.03); 2399 2400 if ((flags & B_DISABLED) != 0) { 2401 cornerColor = tint_color(indicatorBase, 0.8); 2402 bevelColor1 = tint_color(indicatorBase, 0.7); 2403 bevelColor2 = tint_color(indicatorBase, 0.8); 2404 bevelColor3 = tint_color(indicatorBase, 1.01); 2405 } else { 2406 cornerColor = tint_color(indicatorBase, 0.85); 2407 bevelColor1 = tint_color(indicatorBase, 0.3); 2408 bevelColor2 = tint_color(indicatorBase, 0.5); 2409 bevelColor3 = tint_color(indicatorBase, 1.03); 2410 } 2411 2412 // surface top gradient 2413 BGradientLinear fillGradient; 2414 _MakeButtonGradient(fillGradient, rect, indicatorBase, flags); 2415 2416 // rounded corners 2417 2418 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 2419 && leftTopRadius > 0) { 2420 // draw left top rounded corner 2421 BRect leftTopCorner(floorf(rect.left), floorf(rect.top), 2422 floorf(rect.left + leftTopRadius - 2.0), 2423 floorf(rect.top + leftTopRadius - 2.0)); 2424 clipping.Exclude(leftTopCorner); 2425 2426 BRegion cornerClipping(leftTopCorner); 2427 view->ConstrainClippingRegion(&cornerClipping); 2428 2429 BRect ellipseRect(leftTopCorner); 2430 ellipseRect.InsetBy(-1.0, -1.0); 2431 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2432 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2433 2434 // draw the frame (again) 2435 view->SetHighColor(frameLightColor); 2436 view->FillEllipse(ellipseRect); 2437 2438 // draw the bevel and background 2439 _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, 2440 bevelColor1, fillGradient); 2441 } 2442 2443 if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 2444 && rightTopRadius > 0) { 2445 // draw right top rounded corner 2446 BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), 2447 floorf(rect.top), floorf(rect.right), 2448 floorf(rect.top + rightTopRadius - 2.0)); 2449 clipping.Exclude(rightTopCorner); 2450 2451 BRegion cornerClipping(rightTopCorner); 2452 view->ConstrainClippingRegion(&cornerClipping); 2453 2454 BRect ellipseRect(rightTopCorner); 2455 ellipseRect.InsetBy(-1.0, -1.0); 2456 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2457 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2458 2459 // draw the frame (again) 2460 if (frameLightColor == frameShadowColor) { 2461 view->SetHighColor(frameLightColor); 2462 view->FillEllipse(ellipseRect); 2463 } else { 2464 BGradientLinear gradient; 2465 gradient.AddColor(frameLightColor, 0); 2466 gradient.AddColor(frameShadowColor, 255); 2467 gradient.SetStart(rightTopCorner.LeftTop()); 2468 gradient.SetEnd(rightTopCorner.RightBottom()); 2469 view->FillEllipse(ellipseRect, gradient); 2470 } 2471 2472 // draw the bevel and background 2473 _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect, 2474 bevelColor1, bevelColor3, fillGradient); 2475 } 2476 2477 if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2478 && leftBottomRadius > 0) { 2479 // draw left bottom rounded corner 2480 BRect leftBottomCorner(floorf(rect.left), 2481 floorf(rect.bottom - leftBottomRadius + 2.0), 2482 floorf(rect.left + leftBottomRadius - 2.0), 2483 floorf(rect.bottom)); 2484 clipping.Exclude(leftBottomCorner); 2485 2486 BRegion cornerClipping(leftBottomCorner); 2487 view->ConstrainClippingRegion(&cornerClipping); 2488 2489 BRect ellipseRect(leftBottomCorner); 2490 ellipseRect.InsetBy(-1.0, -1.0); 2491 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2492 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2493 2494 // draw the frame (again) 2495 if (frameLightColor == frameShadowColor) { 2496 view->SetHighColor(frameLightColor); 2497 view->FillEllipse(ellipseRect); 2498 } else { 2499 BGradientLinear gradient; 2500 gradient.AddColor(frameLightColor, 0); 2501 gradient.AddColor(frameShadowColor, 255); 2502 gradient.SetStart(leftBottomCorner.LeftTop()); 2503 gradient.SetEnd(leftBottomCorner.RightBottom()); 2504 view->FillEllipse(ellipseRect, gradient); 2505 } 2506 2507 // draw the bevel and background 2508 _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, 2509 updateRect, bevelColor2, bevelColor3, fillGradient); 2510 } 2511 2512 if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 2513 && rightBottomRadius > 0) { 2514 // draw right bottom rounded corner 2515 BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), 2516 floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), 2517 floorf(rect.bottom)); 2518 clipping.Exclude(rightBottomCorner); 2519 2520 BRegion cornerClipping(rightBottomCorner); 2521 view->ConstrainClippingRegion(&cornerClipping); 2522 2523 BRect ellipseRect(rightBottomCorner); 2524 ellipseRect.InsetBy(-1.0, -1.0); 2525 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2526 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2527 2528 // draw the frame (again) 2529 view->SetHighColor(frameShadowColor); 2530 view->FillEllipse(ellipseRect); 2531 2532 // draw the bevel and background 2533 _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, 2534 updateRect, bevelColor3, fillGradient); 2535 } 2536 2537 // clip out the corners 2538 view->ConstrainClippingRegion(&clipping); 2539 2540 // draw the bevel 2541 _DrawFrame(view, rect, 2542 bevelColor2, bevelColor1, 2543 bevelColor3, bevelColor3, 2544 cornerColor, cornerColor, 2545 borders); 2546 2547 // fill in the background 2548 view->FillRect(rect, fillGradient); 2549 2550 // reset clipping constraints 2551 view->ConstrainClippingRegion(NULL); 2552 } 2553 2554 2555 void 2556 BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& cornerRect, 2557 const BRect& updateRect, const rgb_color& background, 2558 const rgb_color& edgeColor, const rgb_color& frameColor, 2559 const rgb_color& bevelColor, const BGradientLinear& fillGradient) 2560 { 2561 _DrawRoundCornerFrameLeftTop(view, cornerRect, updateRect, 2562 background, edgeColor, frameColor); 2563 _DrawRoundCornerBackgroundLeftTop(view, cornerRect, updateRect, 2564 bevelColor, fillGradient); 2565 } 2566 2567 2568 void 2569 BControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect, 2570 const BRect& updateRect, const rgb_color& background, 2571 const rgb_color& edgeColor, const rgb_color& frameColor) 2572 { 2573 // constrain clipping region to corner 2574 BRegion clipping(cornerRect); 2575 view->ConstrainClippingRegion(&clipping); 2576 2577 // background 2578 view->SetHighColor(background); 2579 view->FillRect(cornerRect); 2580 2581 // outer edge 2582 BRect ellipseRect(cornerRect); 2583 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2584 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2585 2586 view->SetHighColor(edgeColor); 2587 view->FillEllipse(ellipseRect); 2588 2589 // frame 2590 ellipseRect.InsetBy(1, 1); 2591 cornerRect.left++; 2592 cornerRect.top++; 2593 view->SetHighColor(frameColor); 2594 view->FillEllipse(ellipseRect); 2595 2596 // prepare for bevel 2597 cornerRect.left++; 2598 cornerRect.top++; 2599 } 2600 2601 2602 void 2603 BControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRect, 2604 const BRect& updateRect, const rgb_color& bevelColor, 2605 const BGradientLinear& fillGradient) 2606 { 2607 // constrain clipping region to corner 2608 BRegion clipping(cornerRect); 2609 view->ConstrainClippingRegion(&clipping); 2610 2611 BRect ellipseRect(cornerRect); 2612 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2613 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2614 2615 // bevel 2616 view->SetHighColor(bevelColor); 2617 view->FillEllipse(ellipseRect); 2618 2619 // gradient 2620 ellipseRect.InsetBy(1, 1); 2621 view->FillEllipse(ellipseRect, fillGradient); 2622 } 2623 2624 2625 void 2626 BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& cornerRect, 2627 const BRect& updateRect, const rgb_color& background, 2628 const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, 2629 const rgb_color& frameTopColor, const rgb_color& frameRightColor, 2630 const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, 2631 const BGradientLinear& fillGradient) 2632 { 2633 _DrawRoundCornerFrameRightTop(view, cornerRect, updateRect, 2634 background, edgeTopColor, edgeRightColor, frameTopColor, 2635 frameRightColor); 2636 _DrawRoundCornerBackgroundRightTop(view, cornerRect, updateRect, 2637 bevelTopColor, bevelRightColor, fillGradient); 2638 } 2639 2640 2641 void 2642 BControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect, 2643 const BRect& updateRect, const rgb_color& background, 2644 const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, 2645 const rgb_color& frameTopColor, const rgb_color& frameRightColor) 2646 { 2647 // constrain clipping region to corner 2648 BRegion clipping(cornerRect); 2649 view->ConstrainClippingRegion(&clipping); 2650 2651 // background 2652 view->SetHighColor(background); 2653 view->FillRect(cornerRect); 2654 2655 // outer edge 2656 BRect ellipseRect(cornerRect); 2657 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2658 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2659 2660 BGradientLinear gradient; 2661 gradient.AddColor(edgeTopColor, 0); 2662 gradient.AddColor(edgeRightColor, 255); 2663 gradient.SetStart(cornerRect.LeftTop()); 2664 gradient.SetEnd(cornerRect.RightBottom()); 2665 view->FillEllipse(ellipseRect, gradient); 2666 2667 // frame 2668 ellipseRect.InsetBy(1, 1); 2669 cornerRect.right--; 2670 cornerRect.top++; 2671 if (frameTopColor == frameRightColor) { 2672 view->SetHighColor(frameTopColor); 2673 view->FillEllipse(ellipseRect); 2674 } else { 2675 gradient.SetColor(0, frameTopColor); 2676 gradient.SetColor(1, frameRightColor); 2677 gradient.SetStart(cornerRect.LeftTop()); 2678 gradient.SetEnd(cornerRect.RightBottom()); 2679 view->FillEllipse(ellipseRect, gradient); 2680 } 2681 2682 // prepare for bevel 2683 cornerRect.right--; 2684 cornerRect.top++; 2685 } 2686 2687 2688 void 2689 BControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerRect, 2690 const BRect& updateRect, const rgb_color& bevelTopColor, 2691 const rgb_color& bevelRightColor, const BGradientLinear& fillGradient) 2692 { 2693 // constrain clipping region to corner 2694 BRegion clipping(cornerRect); 2695 view->ConstrainClippingRegion(&clipping); 2696 2697 BRect ellipseRect(cornerRect); 2698 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2699 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2700 2701 // bevel 2702 BGradientLinear gradient; 2703 gradient.AddColor(bevelTopColor, 0); 2704 gradient.AddColor(bevelRightColor, 255); 2705 gradient.SetStart(cornerRect.LeftTop()); 2706 gradient.SetEnd(cornerRect.RightBottom()); 2707 view->FillEllipse(ellipseRect, gradient); 2708 2709 // gradient 2710 ellipseRect.InsetBy(1, 1); 2711 view->FillEllipse(ellipseRect, fillGradient); 2712 } 2713 2714 2715 void 2716 BControlLook::_DrawRoundCornerLeftBottom(BView* view, BRect& cornerRect, 2717 const BRect& updateRect, const rgb_color& background, 2718 const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, 2719 const rgb_color& frameLeftColor, const rgb_color& frameBottomColor, 2720 const rgb_color& bevelLeftColor, const rgb_color& bevelBottomColor, 2721 const BGradientLinear& fillGradient) 2722 { 2723 _DrawRoundCornerFrameLeftBottom(view, cornerRect, updateRect, 2724 background, edgeLeftColor, edgeBottomColor, frameLeftColor, 2725 frameBottomColor); 2726 _DrawRoundCornerBackgroundLeftBottom(view, cornerRect, updateRect, 2727 bevelLeftColor, bevelBottomColor, fillGradient); 2728 } 2729 2730 2731 void 2732 BControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect, 2733 const BRect& updateRect, const rgb_color& background, 2734 const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, 2735 const rgb_color& frameLeftColor, const rgb_color& frameBottomColor) 2736 { 2737 // constrain clipping region to corner 2738 BRegion clipping(cornerRect); 2739 view->ConstrainClippingRegion(&clipping); 2740 2741 // background 2742 view->SetHighColor(background); 2743 view->FillRect(cornerRect); 2744 2745 // outer edge 2746 BRect ellipseRect(cornerRect); 2747 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2748 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2749 2750 BGradientLinear gradient; 2751 gradient.AddColor(edgeLeftColor, 0); 2752 gradient.AddColor(edgeBottomColor, 255); 2753 gradient.SetStart(cornerRect.LeftTop()); 2754 gradient.SetEnd(cornerRect.RightBottom()); 2755 view->FillEllipse(ellipseRect, gradient); 2756 2757 // frame 2758 ellipseRect.InsetBy(1, 1); 2759 cornerRect.left++; 2760 cornerRect.bottom--; 2761 if (frameLeftColor == frameBottomColor) { 2762 view->SetHighColor(frameLeftColor); 2763 view->FillEllipse(ellipseRect); 2764 } else { 2765 gradient.SetColor(0, frameLeftColor); 2766 gradient.SetColor(1, frameBottomColor); 2767 gradient.SetStart(cornerRect.LeftTop()); 2768 gradient.SetEnd(cornerRect.RightBottom()); 2769 view->FillEllipse(ellipseRect, gradient); 2770 } 2771 2772 // prepare for bevel 2773 cornerRect.left++; 2774 cornerRect.bottom--; 2775 } 2776 2777 2778 void 2779 BControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& cornerRect, 2780 const BRect& updateRect, const rgb_color& bevelLeftColor, 2781 const rgb_color& bevelBottomColor, const BGradientLinear& fillGradient) 2782 { 2783 // constrain clipping region to corner 2784 BRegion clipping(cornerRect); 2785 view->ConstrainClippingRegion(&clipping); 2786 2787 BRect ellipseRect(cornerRect); 2788 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2789 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2790 2791 // bevel 2792 BGradientLinear gradient; 2793 gradient.AddColor(bevelLeftColor, 0); 2794 gradient.AddColor(bevelBottomColor, 255); 2795 gradient.SetStart(cornerRect.LeftTop()); 2796 gradient.SetEnd(cornerRect.RightBottom()); 2797 view->FillEllipse(ellipseRect, gradient); 2798 2799 // gradient 2800 ellipseRect.InsetBy(1, 1); 2801 view->FillEllipse(ellipseRect, fillGradient); 2802 2803 view->PopState(); 2804 } 2805 2806 2807 void 2808 BControlLook::_DrawRoundCornerRightBottom(BView* view, BRect& cornerRect, 2809 const BRect& updateRect, const rgb_color& background, 2810 const rgb_color& edgeColor, const rgb_color& frameColor, 2811 const rgb_color& bevelColor, const BGradientLinear& fillGradient) 2812 { 2813 _DrawRoundCornerFrameRightBottom(view, cornerRect, updateRect, 2814 background, edgeColor, frameColor); 2815 _DrawRoundCornerBackgroundRightBottom(view, cornerRect, updateRect, 2816 bevelColor, fillGradient); 2817 } 2818 2819 2820 void 2821 BControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRect, 2822 const BRect& updateRect, const rgb_color& background, 2823 const rgb_color& edgeColor, const rgb_color& frameColor) 2824 { 2825 // constrain clipping region to corner 2826 BRegion clipping(cornerRect); 2827 view->ConstrainClippingRegion(&clipping); 2828 2829 // background 2830 view->SetHighColor(background); 2831 view->FillRect(cornerRect); 2832 2833 // outer edge 2834 BRect ellipseRect(cornerRect); 2835 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2836 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2837 2838 view->SetHighColor(edgeColor); 2839 view->FillEllipse(ellipseRect); 2840 2841 // frame 2842 ellipseRect.InsetBy(1, 1); 2843 cornerRect.right--; 2844 cornerRect.bottom++; 2845 view->SetHighColor(frameColor); 2846 view->FillEllipse(ellipseRect); 2847 2848 // prepare for bevel 2849 cornerRect.left++; 2850 cornerRect.bottom--; 2851 } 2852 2853 2854 void 2855 BControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view, 2856 BRect& cornerRect, const BRect& updateRect, const rgb_color& bevelColor, 2857 const BGradientLinear& fillGradient) 2858 { 2859 // constrain clipping region to corner 2860 BRegion clipping(cornerRect); 2861 view->ConstrainClippingRegion(&clipping); 2862 2863 BRect ellipseRect(cornerRect); 2864 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2865 ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; 2866 2867 // bevel 2868 view->SetHighColor(bevelColor); 2869 view->FillEllipse(ellipseRect); 2870 2871 // gradient 2872 ellipseRect.InsetBy(1, 1); 2873 view->FillEllipse(ellipseRect, fillGradient); 2874 } 2875 2876 2877 void 2878 BControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, 2879 const BRect& updateRect, 2880 const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor, 2881 const rgb_color& frameLightColor, const rgb_color& frameShadowColor, 2882 const rgb_color& fillLightColor, const rgb_color& fillShadowColor, 2883 float leftInset, float topInset, float rightInset, float bottomInset, 2884 enum orientation orientation) 2885 { 2886 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2887 return; 2888 2889 BGradientLinear gradient; 2890 gradient.AddColor(edgeShadowColor, 0); 2891 gradient.AddColor(edgeLightColor, 255); 2892 gradient.SetStart(rect.LeftTop()); 2893 if (orientation == B_HORIZONTAL) 2894 gradient.SetEnd(rect.LeftBottom()); 2895 else 2896 gradient.SetEnd(rect.RightTop()); 2897 2898 view->FillEllipse(rect, gradient); 2899 2900 rect.left += leftInset; 2901 rect.top += topInset; 2902 rect.right += rightInset; 2903 rect.bottom += bottomInset; 2904 2905 gradient.MakeEmpty(); 2906 gradient.AddColor(frameShadowColor, 0); 2907 gradient.AddColor(frameLightColor, 255); 2908 gradient.SetStart(rect.LeftTop()); 2909 if (orientation == B_HORIZONTAL) 2910 gradient.SetEnd(rect.LeftBottom()); 2911 else 2912 gradient.SetEnd(rect.RightTop()); 2913 2914 view->FillEllipse(rect, gradient); 2915 2916 rect.left += leftInset; 2917 rect.top += topInset; 2918 rect.right += rightInset; 2919 rect.bottom += bottomInset; 2920 2921 gradient.MakeEmpty(); 2922 gradient.AddColor(fillShadowColor, 0); 2923 gradient.AddColor(fillLightColor, 255); 2924 gradient.SetStart(rect.LeftTop()); 2925 if (orientation == B_HORIZONTAL) 2926 gradient.SetEnd(rect.LeftBottom()); 2927 else 2928 gradient.SetEnd(rect.RightTop()); 2929 2930 view->FillEllipse(rect, gradient); 2931 } 2932 2933 2934 rgb_color 2935 BControlLook::_EdgeLightColor(const rgb_color& base, float contrast, 2936 float brightness, uint32 flags) 2937 { 2938 rgb_color edgeLightColor; 2939 2940 if ((flags & B_BLEND_FRAME) != 0) { 2941 uint8 alpha = uint8(20 * contrast); 2942 uint32 white = uint8(255 * brightness); 2943 2944 edgeLightColor = (rgb_color){ white, white, white, alpha }; 2945 } else { 2946 // colors 2947 float tintLight = kEdgeBevelLightTint; 2948 2949 if (contrast == 0.0) 2950 tintLight = B_NO_TINT; 2951 else if (contrast != 1.0) 2952 tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; 2953 2954 edgeLightColor = tint_color(base, tintLight); 2955 2956 if (brightness < 1.0) { 2957 edgeLightColor.red = uint8(edgeLightColor.red * brightness); 2958 edgeLightColor.green = uint8(edgeLightColor.green * brightness); 2959 edgeLightColor.blue = uint8(edgeLightColor.blue * brightness); 2960 } 2961 } 2962 2963 return edgeLightColor; 2964 } 2965 2966 2967 rgb_color 2968 BControlLook::_EdgeShadowColor(const rgb_color& base, float contrast, 2969 float brightness, uint32 flags) 2970 { 2971 rgb_color edgeShadowColor; 2972 2973 if ((flags & B_BLEND_FRAME) != 0) { 2974 uint8 alpha = uint8(20 * contrast); 2975 edgeShadowColor = (rgb_color){ 0, 0, 0, alpha }; 2976 } else { 2977 float tintShadow = kEdgeBevelShadowTint; 2978 2979 if (contrast == 0.0) 2980 tintShadow = B_NO_TINT; 2981 else if (contrast != 1.0) 2982 tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; 2983 2984 edgeShadowColor = tint_color(base, tintShadow); 2985 2986 if (brightness < 1.0) { 2987 edgeShadowColor.red = uint8(edgeShadowColor.red * brightness); 2988 edgeShadowColor.green = uint8(edgeShadowColor.green * brightness); 2989 edgeShadowColor.blue = uint8(edgeShadowColor.blue * brightness); 2990 } 2991 } 2992 2993 return edgeShadowColor; 2994 } 2995 2996 2997 rgb_color 2998 BControlLook::_FrameLightColor(const rgb_color& base, uint32 flags) 2999 { 3000 if ((flags & B_FOCUSED) != 0) 3001 return ui_color(B_KEYBOARD_NAVIGATION_COLOR); 3002 3003 if ((flags & B_ACTIVATED) != 0) 3004 return _FrameShadowColor(base, flags & ~B_ACTIVATED); 3005 3006 rgb_color frameLightColor; 3007 3008 if ((flags & B_DISABLED) != 0) { 3009 // TODO: B_BLEND_FRAME 3010 frameLightColor = tint_color(base, 1.145); 3011 3012 if ((flags & B_DEFAULT_BUTTON) != 0) 3013 frameLightColor = tint_color(frameLightColor, 1.14); 3014 } else { 3015 if ((flags & B_BLEND_FRAME) != 0) 3016 frameLightColor = (rgb_color){ 0, 0, 0, 75 }; 3017 else 3018 frameLightColor = tint_color(base, 1.33); 3019 3020 if ((flags & B_DEFAULT_BUTTON) != 0) 3021 frameLightColor = tint_color(frameLightColor, 1.35); 3022 } 3023 3024 return frameLightColor; 3025 } 3026 3027 3028 rgb_color 3029 BControlLook::_FrameShadowColor(const rgb_color& base, uint32 flags) 3030 { 3031 if ((flags & B_FOCUSED) != 0) 3032 return ui_color(B_KEYBOARD_NAVIGATION_COLOR); 3033 3034 if ((flags & B_ACTIVATED) != 0) 3035 return _FrameLightColor(base, flags & ~B_ACTIVATED); 3036 3037 rgb_color frameShadowColor; 3038 3039 if ((flags & B_DISABLED) != 0) { 3040 // TODO: B_BLEND_FRAME 3041 frameShadowColor = tint_color(base, 1.24); 3042 3043 if ((flags & B_DEFAULT_BUTTON) != 0) { 3044 frameShadowColor = tint_color(base, 1.145); 3045 frameShadowColor = tint_color(frameShadowColor, 1.12); 3046 } 3047 } else { 3048 if ((flags & B_DEFAULT_BUTTON) != 0) { 3049 if ((flags & B_BLEND_FRAME) != 0) 3050 frameShadowColor = (rgb_color){ 0, 0, 0, 75 }; 3051 else 3052 frameShadowColor = tint_color(base, 1.33); 3053 3054 frameShadowColor = tint_color(frameShadowColor, 1.5); 3055 } else { 3056 if ((flags & B_BLEND_FRAME) != 0) 3057 frameShadowColor = (rgb_color){ 0, 0, 0, 95 }; 3058 else 3059 frameShadowColor = tint_color(base, 1.47); 3060 } 3061 } 3062 3063 return frameShadowColor; 3064 } 3065 3066 3067 rgb_color 3068 BControlLook::_BevelLightColor(const rgb_color& base, uint32 flags) 3069 { 3070 rgb_color bevelLightColor = tint_color(base, 0.2); 3071 3072 if ((flags & B_DISABLED) != 0) 3073 bevelLightColor = tint_color(base, B_LIGHTEN_1_TINT); 3074 3075 if ((flags & B_ACTIVATED) != 0) 3076 bevelLightColor = tint_color(base, B_DARKEN_1_TINT); 3077 3078 return bevelLightColor; 3079 } 3080 3081 3082 rgb_color 3083 BControlLook::_BevelShadowColor(const rgb_color& base, uint32 flags) 3084 { 3085 rgb_color bevelShadowColor = tint_color(base, 1.08); 3086 3087 if ((flags & B_DISABLED) != 0) 3088 bevelShadowColor = base; 3089 3090 if ((flags & B_ACTIVATED) != 0) 3091 bevelShadowColor = tint_color(base, B_DARKEN_1_TINT); 3092 3093 return bevelShadowColor; 3094 } 3095 3096 3097 void 3098 BControlLook::_FillGradient(BView* view, const BRect& rect, 3099 const rgb_color& base, float topTint, float bottomTint, 3100 enum orientation orientation) 3101 { 3102 BGradientLinear gradient; 3103 _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); 3104 view->FillRect(rect, gradient); 3105 } 3106 3107 3108 void 3109 BControlLook::_FillGlossyGradient(BView* view, const BRect& rect, 3110 const rgb_color& base, float topTint, float middle1Tint, 3111 float middle2Tint, float bottomTint, enum orientation orientation) 3112 { 3113 BGradientLinear gradient; 3114 _MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint, 3115 middle2Tint, bottomTint, orientation); 3116 view->FillRect(rect, gradient); 3117 } 3118 3119 3120 void 3121 BControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect, 3122 const rgb_color& base, float topTint, float bottomTint, 3123 enum orientation orientation) const 3124 { 3125 gradient.AddColor(tint_color(base, topTint), 0); 3126 gradient.AddColor(tint_color(base, bottomTint), 255); 3127 gradient.SetStart(rect.LeftTop()); 3128 if (orientation == B_HORIZONTAL) 3129 gradient.SetEnd(rect.LeftBottom()); 3130 else 3131 gradient.SetEnd(rect.RightTop()); 3132 } 3133 3134 3135 void 3136 BControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect, 3137 const rgb_color& base, float topTint, float middle1Tint, 3138 float middle2Tint, float bottomTint, 3139 enum orientation orientation) const 3140 { 3141 gradient.AddColor(tint_color(base, topTint), 0); 3142 gradient.AddColor(tint_color(base, middle1Tint), 132); 3143 gradient.AddColor(tint_color(base, middle2Tint), 136); 3144 gradient.AddColor(tint_color(base, bottomTint), 255); 3145 gradient.SetStart(rect.LeftTop()); 3146 if (orientation == B_HORIZONTAL) 3147 gradient.SetEnd(rect.LeftBottom()); 3148 else 3149 gradient.SetEnd(rect.RightTop()); 3150 } 3151 3152 3153 void 3154 BControlLook::_MakeButtonGradient(BGradientLinear& gradient, BRect& rect, 3155 const rgb_color& base, uint32 flags, enum orientation orientation) const 3156 { 3157 float topTint = 0.49; 3158 float middleTint1 = 0.62; 3159 float middleTint2 = 0.76; 3160 float bottomTint = 0.90; 3161 3162 if ((flags & B_ACTIVATED) != 0) { 3163 topTint = 1.11; 3164 bottomTint = 1.08; 3165 } 3166 3167 if ((flags & B_DISABLED) != 0) { 3168 topTint = (topTint + B_NO_TINT) / 2; 3169 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 3170 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 3171 bottomTint = (bottomTint + B_NO_TINT) / 2; 3172 } else if ((flags & B_HOVER) != 0) { 3173 static const float kHoverTintFactor = 0.85; 3174 topTint *= kHoverTintFactor; 3175 middleTint1 *= kHoverTintFactor; 3176 middleTint2 *= kHoverTintFactor; 3177 bottomTint *= kHoverTintFactor; 3178 } 3179 3180 if ((flags & B_ACTIVATED) != 0) { 3181 _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); 3182 } else { 3183 _MakeGlossyGradient(gradient, rect, base, topTint, middleTint1, 3184 middleTint2, bottomTint, orientation); 3185 } 3186 } 3187 3188 3189 3190 bool 3191 BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, 3192 rgb_color& color, uint32 flags) const 3193 { 3194 if ((flags & (B_ACTIVATED | B_CLICKED)) == 0) { 3195 // no mark to be drawn at all 3196 return false; 3197 } 3198 3199 color = ui_color(B_CONTROL_MARK_COLOR); 3200 3201 float mix = 1.0; 3202 3203 if ((flags & B_DISABLED) != 0) { 3204 // activated, but disabled 3205 mix = 0.4; 3206 } else if ((flags & B_CLICKED) != 0) { 3207 if ((flags & B_ACTIVATED) != 0) { 3208 // loosing activation 3209 mix = 0.7; 3210 } else { 3211 // becoming activated 3212 mix = 0.3; 3213 } 3214 } else { 3215 // simply activated 3216 } 3217 3218 color.red = uint8(color.red * mix + base.red * (1.0 - mix)); 3219 color.green = uint8(color.green * mix + base.green * (1.0 - mix)); 3220 color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix)); 3221 3222 return true; 3223 } 3224 3225 3226 // NOTE: May come from a add-on in the future. Initialized in 3227 // InterfaceDefs.cpp 3228 BControlLook* be_control_look = NULL; 3229 3230 3231 } // namespace BPrivate 3232