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