1 /* 2 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de> 3 * Distributed under the terms of the MIT License. 4 */ 5 #include <ControlLook.h> 6 7 #include <stdio.h> 8 9 #include <Control.h> 10 #include <GradientLinear.h> 11 #include <Region.h> 12 #include <Shape.h> 13 #include <String.h> 14 #include <View.h> 15 16 namespace BPrivate { 17 18 static const float kEdgeBevelLightTint = 0.59; 19 static const float kEdgeBevelShadowTint = 1.0735; 20 21 22 BControlLook::BControlLook() 23 { 24 } 25 26 27 BControlLook::~BControlLook() 28 { 29 } 30 31 32 BAlignment 33 BControlLook::DefaultLabelAlignment() const 34 { 35 return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER); 36 } 37 38 39 float 40 BControlLook::DefaultLabelSpacing() const 41 { 42 return 4.0;//ceilf(be_plain_font->Size() / 4.0); 43 } 44 45 46 uint32 47 BControlLook::Flags(BControl* control) const 48 { 49 uint32 flags = 0; 50 51 if (!control->IsEnabled()) 52 flags |= B_DISABLED; 53 54 if (control->IsFocus()) 55 flags |= B_FOCUSED; 56 57 if (control->Value() == B_CONTROL_ON) 58 flags |= B_ACTIVATED; 59 60 return flags; 61 } 62 63 64 // #pragma mark - 65 66 67 void 68 BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, 69 const rgb_color& base, const rgb_color& background, uint32 flags, 70 uint32 borders) 71 { 72 _DrawButtonFrame(view, rect, updateRect, base, background, 1.0, 1.0, flags, 73 borders); 74 } 75 76 77 void 78 BControlLook::DrawButtonBackground(BView* view, BRect& rect, 79 const BRect& updateRect, const rgb_color& base, uint32 flags, 80 uint32 borders, enum orientation orientation) 81 { 82 if (!rect.IsValid() || !updateRect.Intersects(rect)) 83 return; 84 85 // the surface edges 86 87 // colors 88 rgb_color buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT); 89 rgb_color maxLightColor; 90 91 rgb_color bevelColor1; 92 rgb_color bevelColor2; 93 94 if ((flags & B_DISABLED) == 0) { 95 maxLightColor = tint_color(base, 0.2); 96 bevelColor1 = tint_color(base, 1.08); 97 bevelColor2 = base; 98 } else { 99 maxLightColor = tint_color(base, 0.7); 100 bevelColor1 = base; 101 bevelColor2 = buttonBgColor; 102 buttonBgColor = maxLightColor; 103 } 104 105 if (flags & B_ACTIVATED) { 106 view->BeginLineArray(4); 107 108 bevelColor1 = tint_color(bevelColor1, B_DARKEN_1_TINT); 109 bevelColor2 = tint_color(bevelColor2, B_DARKEN_1_TINT); 110 111 // shadow along left/top borders 112 if (borders & B_LEFT_BORDER) { 113 view->AddLine(BPoint(rect.left, rect.top), 114 BPoint(rect.left, rect.bottom), bevelColor1); 115 rect.left++; 116 } 117 if (borders & B_TOP_BORDER) { 118 view->AddLine(BPoint(rect.left, rect.top), 119 BPoint(rect.right, rect.top), bevelColor1); 120 rect.top++; 121 } 122 123 // softer shadow along left/top borders 124 if (borders & B_LEFT_BORDER) { 125 view->AddLine(BPoint(rect.left, rect.top), 126 BPoint(rect.left, rect.bottom), bevelColor2); 127 rect.left++; 128 } 129 if (borders & B_TOP_BORDER) { 130 view->AddLine(BPoint(rect.left, rect.top), 131 BPoint(rect.right, rect.top), bevelColor2); 132 rect.top++; 133 } 134 135 view->EndLineArray(); 136 } else { 137 _DrawFrame(view, rect, 138 maxLightColor, maxLightColor, 139 bevelColor1, bevelColor1, 140 buttonBgColor, buttonBgColor, borders); 141 } 142 143 // the actual surface top 144 145 float topTint = 0.49; 146 float middleTint1 = 0.62; 147 float middleTint2 = 0.76; 148 float bottomTint = 0.90; 149 150 if (flags & B_ACTIVATED) { 151 topTint = 1.11; 152 bottomTint = 1.08; 153 } 154 155 if (flags & B_DISABLED) { 156 topTint = (topTint + B_NO_TINT) / 2; 157 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 158 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 159 bottomTint = (bottomTint + B_NO_TINT) / 2; 160 } else if (flags & B_HOVER) { 161 static const float kHoverTintFactor = 0.85; 162 topTint *= kHoverTintFactor; 163 middleTint1 *= kHoverTintFactor; 164 middleTint2 *= kHoverTintFactor; 165 bottomTint *= kHoverTintFactor; 166 } 167 168 if (flags & B_ACTIVATED) { 169 _FillGradient(view, rect, base, topTint, bottomTint, orientation); 170 } else { 171 _FillGlossyGradient(view, rect, base, topTint, middleTint1, 172 middleTint2, bottomTint, orientation); 173 } 174 } 175 176 177 void 178 BControlLook::DrawMenuBarBackground(BView* view, BRect& rect, 179 const BRect& updateRect, const rgb_color& base, uint32 flags, 180 uint32 borders) 181 { 182 if (!rect.IsValid() || !updateRect.Intersects(rect)) 183 return; 184 185 // the surface edges 186 187 // colors 188 float topTint; 189 float bottomTint; 190 191 if (flags & B_ACTIVATED) { 192 rgb_color bevelColor1 = tint_color(base, 1.40); 193 rgb_color bevelColor2 = tint_color(base, 1.25); 194 195 topTint = 1.25; 196 bottomTint = 1.20; 197 198 _DrawFrame(view, rect, 199 bevelColor1, bevelColor1, 200 bevelColor2, bevelColor2, 201 borders & B_TOP_BORDER); 202 } else { 203 rgb_color cornerColor = tint_color(base, 0.9); 204 rgb_color bevelColorTop = tint_color(base, 0.5); 205 rgb_color bevelColorLeft = tint_color(base, 0.7); 206 rgb_color bevelColorRightBottom = tint_color(base, 1.08); 207 208 topTint = 0.69; 209 bottomTint = 1.03; 210 211 _DrawFrame(view, rect, 212 bevelColorLeft, bevelColorTop, 213 bevelColorRightBottom, bevelColorRightBottom, 214 cornerColor, cornerColor, 215 borders); 216 } 217 218 // the actual surface top 219 220 _FillGradient(view, rect, base, topTint, bottomTint); 221 } 222 223 224 void 225 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 226 const BRect& updateRect, const rgb_color& base, 227 const rgb_color& background, uint32 flags, uint32 borders) 228 { 229 _DrawButtonFrame(view, rect, updateRect, base, background, 0.6, 1.0, flags, 230 borders); 231 } 232 233 234 void 235 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 236 const BRect& updateRect, const rgb_color& base, bool popupIndicator, 237 uint32 flags) 238 { 239 if (popupIndicator) { 240 BRect leftRect(rect); 241 leftRect.right -= 10; 242 243 BRect rightRect(rect); 244 rightRect.left = rightRect.right - 9; 245 246 DrawMenuFieldBackground(view, leftRect, updateRect, base, flags, 247 B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); 248 249 rgb_color indicatorBase; 250 rgb_color markColor; 251 if (flags & B_DISABLED) { 252 indicatorBase = tint_color(base, 1.05); 253 markColor = tint_color(base, 1.35); 254 } else { 255 indicatorBase = tint_color(base, 1.12); 256 markColor = tint_color(base, 1.65); 257 } 258 259 DrawMenuFieldBackground(view, rightRect, updateRect, indicatorBase, 260 flags, B_RIGHT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); 261 262 // popup marker 263 BPoint center(roundf((rightRect.left + rightRect.right) / 2.0), 264 roundf((rightRect.top + rightRect.bottom) / 2.0)); 265 BPoint triangle[3]; 266 triangle[0] = center + BPoint(-2.5, -0.5); 267 triangle[1] = center + BPoint(2.5, -0.5); 268 triangle[2] = center + BPoint(0.0, 2.0); 269 270 uint32 viewFlags = view->Flags(); 271 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 272 273 view->SetHighColor(markColor); 274 view->FillTriangle(triangle[0], triangle[1], triangle[2]); 275 276 view->SetFlags(viewFlags); 277 278 rect = leftRect; 279 } else { 280 DrawMenuFieldBackground(view, rect, updateRect, base, flags); 281 } 282 } 283 284 void 285 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 286 const BRect& updateRect, const rgb_color& base, uint32 flags, 287 uint32 borders) 288 { 289 if (!rect.IsValid() || !updateRect.Intersects(rect)) 290 return; 291 292 // the surface edges 293 294 // colors 295 rgb_color cornerColor = tint_color(base, 0.85); 296 rgb_color bevelColor1 = tint_color(base, 0.3); 297 rgb_color bevelColor2 = tint_color(base, 0.5); 298 rgb_color bevelColor3 = tint_color(base, 1.03); 299 300 if (flags & B_DISABLED) { 301 cornerColor = tint_color(base, 0.8); 302 bevelColor1 = tint_color(base, 0.7); 303 bevelColor2 = tint_color(base, 0.8); 304 bevelColor3 = tint_color(base, 1.01); 305 } else { 306 cornerColor = tint_color(base, 0.85); 307 bevelColor1 = tint_color(base, 0.3); 308 bevelColor2 = tint_color(base, 0.5); 309 bevelColor3 = tint_color(base, 1.03); 310 } 311 312 _DrawFrame(view, rect, 313 bevelColor2, bevelColor1, 314 bevelColor3, bevelColor3, 315 cornerColor, cornerColor, 316 borders); 317 318 // the actual surface top 319 320 float topTint = 0.49; 321 float middleTint1 = 0.62; 322 float middleTint2 = 0.76; 323 float bottomTint = 0.90; 324 325 if (flags & B_DISABLED) { 326 topTint = (topTint + B_NO_TINT) / 2; 327 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 328 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 329 bottomTint = (bottomTint + B_NO_TINT) / 2; 330 } else if (flags & B_HOVER) { 331 static const float kHoverTintFactor = 0.85; 332 topTint *= kHoverTintFactor; 333 middleTint1 *= kHoverTintFactor; 334 middleTint2 *= kHoverTintFactor; 335 bottomTint *= kHoverTintFactor; 336 } 337 338 _FillGlossyGradient(view, rect, base, topTint, middleTint1, 339 middleTint2, bottomTint); 340 } 341 342 void 343 BControlLook::DrawMenuBackground(BView* view, BRect& rect, 344 const BRect& updateRect, const rgb_color& base, uint32 flags, 345 uint32 borders) 346 { 347 if (!rect.IsValid() || !updateRect.Intersects(rect)) 348 return; 349 350 // the surface edges 351 352 rgb_color bevelLightColor; 353 rgb_color bevelShadowColor; 354 rgb_color background = tint_color(base, 0.75); 355 356 if (flags & B_DISABLED) { 357 bevelLightColor = tint_color(background, 0.80); 358 bevelShadowColor = tint_color(background, 1.07); 359 } else { 360 bevelLightColor = tint_color(background, 0.6); 361 bevelShadowColor = tint_color(background, 1.12); 362 } 363 364 _DrawFrame(view, rect, 365 bevelLightColor, bevelLightColor, 366 bevelShadowColor, bevelShadowColor, 367 borders); 368 369 // the actual surface top 370 371 view->SetHighColor(background); 372 view->FillRect(rect); 373 } 374 375 376 void 377 BControlLook::DrawMenuItemBackground(BView* view, BRect& rect, 378 const BRect& updateRect, const rgb_color& base, uint32 flags, 379 uint32 borders) 380 { 381 if (!rect.IsValid() || !updateRect.Intersects(rect)) 382 return; 383 384 // the surface edges 385 386 float topTint; 387 float bottomTint; 388 rgb_color selectedColor = base; 389 390 if (flags & B_ACTIVATED) { 391 topTint = 0.9; 392 bottomTint = 1.05; 393 selectedColor = tint_color(base, 1.26); 394 } else if (flags & B_DISABLED) { 395 topTint = 0.80; 396 bottomTint = 1.07; 397 } else { 398 topTint = 0.6; 399 bottomTint = 1.12; 400 } 401 402 rgb_color bevelLightColor = tint_color(selectedColor, topTint); 403 rgb_color bevelShadowColor = tint_color(selectedColor, bottomTint); 404 405 _DrawFrame(view, rect, 406 bevelLightColor, bevelLightColor, 407 bevelShadowColor, bevelShadowColor, 408 borders); 409 410 // the actual surface top 411 412 view->SetLowColor(selectedColor); 413 // _FillGradient(view, rect, selectedColor, topTint, bottomTint); 414 _FillGradient(view, rect, selectedColor, bottomTint, topTint); 415 } 416 417 418 void 419 BControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, 420 const rgb_color& base, const rgb_color& barColor, float progressPosition) 421 { 422 if (!rect.Intersects(updateRect)) 423 return; 424 425 _DrawOuterResessedFrame(view, rect, base, 0.6); 426 427 // colors 428 rgb_color dark1BorderColor = tint_color(base, 1.3); 429 rgb_color dark2BorderColor = tint_color(base, 1.2); 430 rgb_color dark1FilledBorderColor = tint_color(barColor, 1.20); 431 rgb_color dark2FilledBorderColor = tint_color(barColor, 1.45); 432 433 BRect filledRect(rect); 434 filledRect.right = progressPosition - 1; 435 436 BRect nonfilledRect(rect); 437 nonfilledRect.left = progressPosition; 438 439 bool filledSurface = filledRect.Width() > 0; 440 bool nonfilledSurface = nonfilledRect.Width() > 0; 441 442 if (filledSurface) { 443 _DrawFrame(view, filledRect, 444 dark1FilledBorderColor, dark1FilledBorderColor, 445 dark2FilledBorderColor, dark2FilledBorderColor); 446 447 _FillGlossyGradient(view, filledRect, barColor, 0.55, 0.68, 0.76, 0.90); 448 } 449 450 if (nonfilledSurface) { 451 _DrawFrame(view, nonfilledRect, dark1BorderColor, dark1BorderColor, 452 dark2BorderColor, dark2BorderColor, 453 B_TOP_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER); 454 455 if (nonfilledRect.left < nonfilledRect.right) { 456 // shadow from fill bar, or left border 457 rgb_color leftBorder = dark1BorderColor; 458 if (filledSurface) 459 leftBorder = tint_color(base, 0.50); 460 view->SetHighColor(leftBorder); 461 view->StrokeLine(nonfilledRect.LeftTop(), 462 nonfilledRect.LeftBottom()); 463 nonfilledRect.left++; 464 } 465 466 _FillGradient(view, nonfilledRect, base, 0.25, 0.06); 467 } 468 } 469 470 471 void 472 BControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, 473 const rgb_color& base, uint32 flags) 474 { 475 if (!rect.Intersects(updateRect)) 476 return; 477 478 rgb_color dark1BorderColor; 479 rgb_color dark2BorderColor; 480 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 481 482 if (flags & B_DISABLED) { 483 _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags); 484 485 dark1BorderColor = tint_color(base, 1.15); 486 dark2BorderColor = tint_color(base, 1.15); 487 } else if (flags & B_CLICKED) { 488 dark1BorderColor = tint_color(base, 1.50); 489 dark2BorderColor = tint_color(base, 1.48); 490 491 _DrawFrame(view, rect, 492 dark1BorderColor, dark1BorderColor, 493 dark2BorderColor, dark2BorderColor); 494 495 dark2BorderColor = dark1BorderColor; 496 } else { 497 _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags); 498 499 dark1BorderColor = tint_color(base, 1.40); 500 dark2BorderColor = tint_color(base, 1.38); 501 } 502 503 if (flags & B_FOCUSED) { 504 dark1BorderColor = navigationColor; 505 dark2BorderColor = navigationColor; 506 } 507 508 _DrawFrame(view, rect, 509 dark1BorderColor, dark1BorderColor, 510 dark2BorderColor, dark2BorderColor); 511 512 if (flags & B_DISABLED) { 513 _FillGradient(view, rect, base, 0.4, 0.2); 514 } else { 515 _FillGradient(view, rect, base, 0.15, 0.0); 516 } 517 518 rgb_color markColor; 519 if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { 520 view->SetHighColor(markColor); 521 522 rect.InsetBy(2, 2); 523 view->SetPenSize(max_c(1.0, ceilf(rect.Width() / 3.5))); 524 view->SetDrawingMode(B_OP_OVER); 525 526 view->StrokeLine(rect.LeftTop(), rect.RightBottom()); 527 view->StrokeLine(rect.LeftBottom(), rect.RightTop()); 528 } 529 } 530 531 532 void 533 BControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect, 534 const rgb_color& base, uint32 flags) 535 { 536 if (!rect.Intersects(updateRect)) 537 return; 538 539 rgb_color borderColor; 540 rgb_color bevelLight; 541 rgb_color bevelShadow; 542 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 543 544 if (flags & B_DISABLED) { 545 borderColor = tint_color(base, 1.15); 546 bevelLight = base; 547 bevelShadow = base; 548 } else if (flags & B_CLICKED) { 549 borderColor = tint_color(base, 1.50); 550 bevelLight = borderColor; 551 bevelShadow = borderColor; 552 } else { 553 borderColor = tint_color(base, 1.45); 554 bevelLight = tint_color(base, 0.55); 555 bevelShadow = tint_color(base, 1.11); 556 } 557 558 if (flags & B_FOCUSED) { 559 borderColor = navigationColor; 560 } 561 562 BGradientLinear bevelGradient; 563 bevelGradient.AddColor(bevelShadow, 0); 564 bevelGradient.AddColor(bevelLight, 255); 565 bevelGradient.SetStart(rect.LeftTop()); 566 bevelGradient.SetEnd(rect.RightBottom()); 567 568 view->FillEllipse(rect, bevelGradient); 569 rect.InsetBy(1, 1); 570 571 bevelGradient.MakeEmpty(); 572 bevelGradient.AddColor(borderColor, 0); 573 bevelGradient.AddColor(tint_color(borderColor, 0.8), 255); 574 view->FillEllipse(rect, bevelGradient); 575 rect.InsetBy(1, 1); 576 577 float topTint; 578 float bottomTint; 579 if (flags & B_DISABLED) { 580 topTint = 0.4; 581 bottomTint = 0.2; 582 } else { 583 topTint = 0.15; 584 bottomTint = 0.0; 585 } 586 587 BGradientLinear gradient; 588 _MakeGradient(gradient, rect, base, topTint, bottomTint); 589 view->FillEllipse(rect, gradient); 590 591 rgb_color markColor; 592 if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { 593 view->SetHighColor(markColor); 594 rect.InsetBy(3, 3); 595 view->FillEllipse(rect); 596 } 597 } 598 599 600 void 601 BControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, 602 const BRect& updateRect, const rgb_color& base, uint32 flags, 603 enum orientation orientation) 604 { 605 DrawScrollBarBackground(view, rect1, updateRect, base, flags, orientation); 606 DrawScrollBarBackground(view, rect2, updateRect, base, flags, orientation); 607 } 608 609 void 610 BControlLook::DrawScrollBarBackground(BView* view, BRect& rect, 611 const BRect& updateRect, const rgb_color& base, uint32 flags, 612 enum orientation orientation) 613 { 614 if (!rect.IsValid() || !rect.Intersects(updateRect)) 615 return; 616 617 float gradient1Tint; 618 float gradient2Tint; 619 float darkEdge1Tint; 620 float darkEdge2Tint; 621 float shadowTint; 622 623 if (flags & B_DISABLED) { 624 gradient1Tint = 0.9; 625 gradient2Tint = 0.8; 626 darkEdge1Tint = B_DARKEN_2_TINT; 627 darkEdge2Tint = B_DARKEN_2_TINT; 628 shadowTint = gradient1Tint; 629 } else { 630 gradient1Tint = 1.10; 631 gradient2Tint = 1.05; 632 darkEdge1Tint = B_DARKEN_3_TINT; 633 darkEdge2Tint = B_DARKEN_2_TINT; 634 shadowTint = gradient1Tint; 635 } 636 637 rgb_color darkEdge1 = tint_color(base, darkEdge1Tint); 638 rgb_color darkEdge2 = tint_color(base, darkEdge2Tint); 639 rgb_color shadow = tint_color(base, shadowTint); 640 641 if (orientation == B_HORIZONTAL) { 642 // dark vertical line on left edge 643 if (rect.Width() > 0) { 644 view->SetHighColor(darkEdge1); 645 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 646 rect.left++; 647 } 648 // dark vertical line on right edge 649 if (rect.Width() >= 0) { 650 view->SetHighColor(darkEdge2); 651 view->StrokeLine(rect.RightTop(), rect.RightBottom()); 652 rect.right--; 653 } 654 // vertical shadow line after left edge 655 if (rect.Width() >= 0) { 656 view->SetHighColor(shadow); 657 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 658 rect.left++; 659 } 660 // fill 661 if (rect.Width() >= 0) { 662 _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, 663 orientation); 664 } 665 } else { 666 // dark vertical line on top edge 667 if (rect.Height() > 0) { 668 view->SetHighColor(darkEdge1); 669 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 670 rect.top++; 671 } 672 // dark vertical line on bottom edge 673 if (rect.Height() >= 0) { 674 view->SetHighColor(darkEdge2); 675 view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); 676 rect.bottom--; 677 } 678 // horizontal shadow line after top edge 679 if (rect.Height() >= 0) { 680 view->SetHighColor(shadow); 681 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 682 rect.top++; 683 } 684 // fill 685 if (rect.Height() >= 0) { 686 _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, 687 orientation); 688 } 689 } 690 } 691 692 693 void 694 BControlLook::DrawScrollViewFrame(BView* view, BRect& rect, 695 const BRect& updateRect, BRect verticalScrollBarFrame, 696 BRect horizontalScrollBarFrame, const rgb_color& base, 697 border_style border, uint32 flags, uint32 _borders) 698 { 699 if (border == B_NO_BORDER) 700 return; 701 702 bool excludeScrollCorner = border == B_FANCY_BORDER 703 && horizontalScrollBarFrame.IsValid() 704 && verticalScrollBarFrame.IsValid(); 705 706 uint32 borders = _borders; 707 if (excludeScrollCorner) { 708 rect.bottom = horizontalScrollBarFrame.top; 709 rect.right = verticalScrollBarFrame.left; 710 borders &= ~(B_RIGHT_BORDER | B_BOTTOM_BORDER); 711 } 712 713 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 714 715 if (border == B_FANCY_BORDER) 716 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 717 718 if (flags & B_FOCUSED) { 719 rgb_color focusColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 720 _DrawFrame(view, rect, focusColor, focusColor, focusColor, focusColor, 721 borders); 722 } else { 723 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 724 scrollbarFrameColor, scrollbarFrameColor, borders); 725 } 726 727 if (excludeScrollCorner) { 728 horizontalScrollBarFrame.InsetBy(-1, -1); 729 // do not overdraw the top edge 730 horizontalScrollBarFrame.top += 2; 731 borders = _borders; 732 borders &= ~B_TOP_BORDER; 733 _DrawOuterResessedFrame(view, horizontalScrollBarFrame, base, 734 1.0, 1.0, flags, borders); 735 _DrawFrame(view, horizontalScrollBarFrame, scrollbarFrameColor, 736 scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, 737 borders); 738 739 740 verticalScrollBarFrame.InsetBy(-1, -1); 741 // do not overdraw the left edge 742 verticalScrollBarFrame.left += 2; 743 borders = _borders; 744 borders &= ~B_LEFT_BORDER; 745 _DrawOuterResessedFrame(view, verticalScrollBarFrame, base, 746 1.0, 1.0, flags, borders); 747 _DrawFrame(view, verticalScrollBarFrame, scrollbarFrameColor, 748 scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, 749 borders); 750 } 751 } 752 753 754 void 755 BControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, 756 const rgb_color& base, uint32 direction, uint32 flags, float tint) 757 { 758 BPoint tri1, tri2, tri3; 759 float hInset = rect.Width() / 3; 760 float vInset = rect.Height() / 3; 761 rect.InsetBy(hInset, vInset); 762 763 switch (direction) { 764 case B_LEFT_ARROW: 765 tri1.Set(rect.right, rect.top); 766 tri2.Set(rect.right - rect.Width() / 1.33, 767 (rect.top + rect.bottom + 1) /2 ); 768 tri3.Set(rect.right, rect.bottom + 1); 769 break; 770 case B_RIGHT_ARROW: 771 tri1.Set(rect.left, rect.bottom + 1); 772 tri2.Set(rect.left + rect.Width() / 1.33, 773 (rect.top + rect.bottom + 1) / 2); 774 tri3.Set(rect.left, rect.top); 775 break; 776 case B_UP_ARROW: 777 tri1.Set(rect.left, rect.bottom); 778 tri2.Set((rect.left + rect.right + 1) / 2, 779 rect.bottom - rect.Height() / 1.33); 780 tri3.Set(rect.right + 1, rect.bottom); 781 break; 782 case B_DOWN_ARROW: 783 default: 784 tri1.Set(rect.left, rect.top); 785 tri2.Set((rect.left + rect.right + 1) / 2, 786 rect.top + rect.Height() / 1.33); 787 tri3.Set(rect.right + 1, rect.top); 788 break; 789 } 790 // offset triangle if down 791 if (flags & B_ACTIVATED) 792 view->MovePenTo(BPoint(1, 1)); 793 else 794 view->MovePenTo(BPoint(0, 0)); 795 796 BShape arrowShape; 797 arrowShape.MoveTo(tri1); 798 arrowShape.LineTo(tri2); 799 arrowShape.LineTo(tri3); 800 801 if (flags & B_DISABLED) 802 tint = (tint + B_NO_TINT + B_NO_TINT) / 3; 803 804 view->SetHighColor(tint_color(base, tint)); 805 806 float penSize = view->PenSize(); 807 drawing_mode mode = view->DrawingMode(); 808 809 view->SetPenSize(ceilf(hInset / 2.0)); 810 view->SetDrawingMode(B_OP_OVER); 811 view->StrokeShape(&arrowShape); 812 813 view->SetPenSize(penSize); 814 view->SetDrawingMode(mode); 815 } 816 817 818 rgb_color 819 BControlLook::SliderBarColor(const rgb_color& base) 820 { 821 return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT); 822 } 823 824 825 void 826 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 827 const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, 828 float sliderScale, uint32 flags, enum orientation orientation) 829 { 830 if (!rect.IsValid() || !rect.Intersects(updateRect)) 831 return; 832 833 // separate the bar in two sides 834 float sliderPosition; 835 BRect leftBarSide = rect; 836 BRect rightBarSide = rect; 837 838 if (orientation == B_HORIZONTAL) { 839 sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) 840 * sliderScale); 841 leftBarSide.right = sliderPosition - 1; 842 rightBarSide.left = sliderPosition; 843 } else { 844 sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) 845 * sliderScale); 846 leftBarSide.bottom = sliderPosition - 1; 847 rightBarSide.top = sliderPosition; 848 } 849 850 // fill the background for the corners, exclude the middle bar for now 851 BRegion region(rect); 852 region.Exclude(rightBarSide); 853 view->ConstrainClippingRegion(®ion); 854 855 view->PushState(); 856 857 DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, 858 orientation); 859 860 view->PopState(); 861 862 region.Set(rect); 863 region.Exclude(leftBarSide); 864 view->ConstrainClippingRegion(®ion); 865 866 view->PushState(); 867 868 DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, 869 orientation); 870 871 view->PopState(); 872 873 view->ConstrainClippingRegion(NULL); 874 } 875 876 877 void 878 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 879 const rgb_color& base, rgb_color fillColor, uint32 flags, 880 enum orientation orientation) 881 { 882 if (!rect.IsValid() || !rect.Intersects(updateRect)) 883 return; 884 885 // separate the rect into corners 886 BRect leftCorner(rect); 887 BRect rightCorner(rect); 888 BRect barRect(rect); 889 890 if (orientation == B_HORIZONTAL) { 891 leftCorner.right = leftCorner.left + leftCorner.Height(); 892 rightCorner.left = rightCorner.right - rightCorner.Height(); 893 barRect.left += ceilf(barRect.Height() / 2); 894 barRect.right -= ceilf(barRect.Height() / 2); 895 } else { 896 leftCorner.bottom = leftCorner.top + leftCorner.Width(); 897 rightCorner.top = rightCorner.bottom - rightCorner.Width(); 898 barRect.top += ceilf(barRect.Width() / 2); 899 barRect.bottom -= ceilf(barRect.Width() / 2); 900 } 901 902 // fill the background for the corners, exclude the middle bar for now 903 BRegion region(rect); 904 region.Exclude(barRect); 905 view->ConstrainClippingRegion(®ion); 906 907 view->SetHighColor(base); 908 view->FillRect(rect); 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 918 if (flags & B_DISABLED) { 919 edgeLightTint = 1.0; 920 edgeShadowTint = 1.0; 921 frameLightTint = 1.20; 922 frameShadowTint = 1.25; 923 fillLightTint = 0.9; 924 fillShadowTint = 1.05; 925 926 fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6); 927 fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6); 928 fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6); 929 } else { 930 edgeLightTint = 0.65; 931 edgeShadowTint = 1.07; 932 frameLightTint = 1.40; 933 frameShadowTint = 1.50; 934 fillLightTint = 0.8; 935 fillShadowTint = 1.1; 936 } 937 938 rgb_color edgeLightColor = tint_color(base, edgeLightTint); 939 rgb_color edgeShadowColor = tint_color(base, edgeShadowTint); 940 rgb_color frameLightColor = tint_color(fillColor, frameLightTint); 941 rgb_color frameShadowColor = tint_color(fillColor, frameShadowTint); 942 rgb_color fillLightColor = tint_color(fillColor, fillLightTint); 943 rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); 944 945 if (orientation == B_HORIZONTAL) { 946 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 947 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 948 fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); 949 950 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 951 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 952 fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); 953 } else { 954 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 955 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 956 fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); 957 958 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 959 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 960 fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); 961 } 962 963 view->ConstrainClippingRegion(NULL); 964 965 view->BeginLineArray(4); 966 if (orientation == B_HORIZONTAL) { 967 view->AddLine(barRect.LeftTop(), barRect.RightTop(), edgeShadowColor); 968 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 969 edgeLightColor); 970 barRect.InsetBy(0, 1); 971 view->AddLine(barRect.LeftTop(), barRect.RightTop(), frameShadowColor); 972 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 973 frameLightColor); 974 barRect.InsetBy(0, 1); 975 } else { 976 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), edgeShadowColor); 977 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 978 edgeLightColor); 979 barRect.InsetBy(1, 0); 980 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), frameShadowColor); 981 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 982 frameLightColor); 983 barRect.InsetBy(1, 0); 984 } 985 view->EndLineArray(); 986 987 _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, 988 orientation); 989 } 990 991 992 void 993 BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, 994 const rgb_color& base, uint32 flags, enum orientation orientation) 995 { 996 if (!rect.IsValid() || !rect.Intersects(updateRect)) 997 return; 998 999 // figure out frame color 1000 rgb_color frameLightColor; 1001 rgb_color frameShadowColor; 1002 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1003 1004 if (flags & B_FOCUSED) { 1005 // focused 1006 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1007 frameShadowColor = frameLightColor; 1008 } else { 1009 // figure out the tints to be used 1010 float frameLightTint; 1011 float frameShadowTint; 1012 1013 if (flags & B_DISABLED) { 1014 frameLightTint = 1.30; 1015 frameShadowTint = 1.35; 1016 shadowColor.alpha = 30; 1017 } else { 1018 frameLightTint = 1.6; 1019 frameShadowTint = 1.65; 1020 } 1021 1022 frameLightColor = tint_color(base, frameLightTint); 1023 frameShadowColor = tint_color(base, frameShadowTint); 1024 } 1025 1026 BRect originalRect(rect); 1027 rect.right--; 1028 rect.bottom--; 1029 1030 _DrawFrame(view, rect, frameLightColor, frameLightColor, 1031 frameShadowColor, frameShadowColor); 1032 1033 flags &= ~B_ACTIVATED; 1034 DrawButtonBackground(view, rect, updateRect, base, flags); 1035 1036 // thumb shadow 1037 view->SetDrawingMode(B_OP_ALPHA); 1038 view->SetHighColor(shadowColor); 1039 originalRect.left++; 1040 originalRect.top++; 1041 view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom()); 1042 originalRect.bottom--; 1043 view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom()); 1044 1045 // thumb edge 1046 if (orientation == B_HORIZONTAL) { 1047 rect.InsetBy(0, floorf(rect.Height() / 4)); 1048 rect.left = floorf((rect.left + rect.right) / 2); 1049 rect.right = rect.left + 1; 1050 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1051 shadowColor.alpha = 128; 1052 view->SetHighColor(shadowColor); 1053 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 1054 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1055 lightColor.alpha = 128; 1056 view->SetHighColor(lightColor); 1057 view->StrokeLine(rect.RightTop(), rect.RightBottom()); 1058 } else { 1059 rect.InsetBy(floorf(rect.Width() / 4), 0); 1060 rect.top = floorf((rect.top + rect.bottom) / 2); 1061 rect.bottom = rect.top + 1; 1062 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1063 shadowColor.alpha = 128; 1064 view->SetHighColor(shadowColor); 1065 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 1066 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1067 lightColor.alpha = 128; 1068 view->SetHighColor(lightColor); 1069 view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); 1070 } 1071 1072 view->SetDrawingMode(B_OP_COPY); 1073 } 1074 1075 1076 void 1077 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1078 const BRect& updateRect, const rgb_color& base, uint32 flags, 1079 enum orientation orientation) 1080 { 1081 DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); 1082 } 1083 1084 1085 void 1086 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1087 const BRect& updateRect, const rgb_color& base, const rgb_color& fill, 1088 uint32 flags, enum orientation orientation) 1089 { 1090 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1091 return; 1092 1093 // figure out frame color 1094 rgb_color frameLightColor; 1095 rgb_color frameShadowColor; 1096 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1097 1098 float topTint = 0.49; 1099 float middleTint1 = 0.62; 1100 float middleTint2 = 0.76; 1101 float bottomTint = 0.90; 1102 1103 if (flags & B_DISABLED) { 1104 topTint = (topTint + B_NO_TINT) / 2; 1105 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 1106 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 1107 bottomTint = (bottomTint + B_NO_TINT) / 2; 1108 } else if (flags & B_HOVER) { 1109 static const float kHoverTintFactor = 0.85; 1110 topTint *= kHoverTintFactor; 1111 middleTint1 *= kHoverTintFactor; 1112 middleTint2 *= kHoverTintFactor; 1113 bottomTint *= kHoverTintFactor; 1114 } 1115 1116 if (flags & B_FOCUSED) { 1117 // focused 1118 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1119 frameShadowColor = frameLightColor; 1120 } else { 1121 // figure out the tints to be used 1122 float frameLightTint; 1123 float frameShadowTint; 1124 1125 if (flags & B_DISABLED) { 1126 frameLightTint = 1.30; 1127 frameShadowTint = 1.35; 1128 shadowColor.alpha = 30; 1129 } else { 1130 frameLightTint = 1.6; 1131 frameShadowTint = 1.65; 1132 } 1133 1134 frameLightColor = tint_color(base, frameLightTint); 1135 frameShadowColor = tint_color(base, frameShadowTint); 1136 } 1137 1138 // make room for the shadow 1139 rect.right--; 1140 rect.bottom--; 1141 1142 uint32 viewFlags = view->Flags(); 1143 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 1144 view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); 1145 1146 float center = (rect.left + rect.right) / 2; 1147 1148 BShape shape; 1149 shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5)); 1150 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); 1151 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5)); 1152 shape.LineTo(BPoint(center + 0.5, rect.top + 0.5)); 1153 shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); 1154 shape.Close(); 1155 1156 view->MovePenTo(BPoint(1, 1)); 1157 1158 view->SetDrawingMode(B_OP_ALPHA); 1159 view->SetHighColor(shadowColor); 1160 view->StrokeShape(&shape); 1161 1162 view->MovePenTo(B_ORIGIN); 1163 1164 view->SetDrawingMode(B_OP_COPY); 1165 view->SetHighColor(frameLightColor); 1166 view->StrokeShape(&shape); 1167 1168 rect.InsetBy(1, 1); 1169 shape.Clear(); 1170 shape.MoveTo(BPoint(rect.left, rect.bottom + 1)); 1171 shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); 1172 shape.LineTo(BPoint(center + 0.5, rect.top)); 1173 shape.Close(); 1174 1175 BGradientLinear gradient; 1176 if (flags & B_DISABLED) { 1177 _MakeGradient(gradient, rect, fill, topTint, bottomTint); 1178 } else { 1179 _MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1, 1180 middleTint2, bottomTint); 1181 } 1182 1183 view->FillShape(&shape, gradient); 1184 1185 view->SetFlags(viewFlags); 1186 } 1187 1188 1189 void 1190 BControlLook::DrawSliderHashMarks(BView* view, BRect& rect, 1191 const BRect& updateRect, const rgb_color& base, int32 count, 1192 hash_mark_location location, uint32 flags, enum orientation orientation) 1193 { 1194 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1195 return; 1196 1197 rgb_color lightColor; 1198 rgb_color darkColor; 1199 1200 if (flags & B_DISABLED) { 1201 lightColor = tint_color(base, 0.9); 1202 darkColor = tint_color(base, 1.07); 1203 } else { 1204 lightColor = tint_color(base, 0.8); 1205 darkColor = tint_color(base, 1.14); 1206 } 1207 1208 int32 hashMarkCount = max_c(count, 2); 1209 // draw at least two hashmarks at min/max if 1210 // fHashMarks != B_HASH_MARKS_NONE 1211 float factor; 1212 float startPos; 1213 if (orientation == B_HORIZONTAL) { 1214 factor = (rect.Width() - 2) / (hashMarkCount - 1); 1215 startPos = rect.left + 1; 1216 } else { 1217 factor = (rect.Height() - 2) / (hashMarkCount - 1); 1218 startPos = rect.top + 1; 1219 } 1220 1221 if (location & B_HASH_MARKS_TOP) { 1222 view->BeginLineArray(hashMarkCount * 2); 1223 1224 if (orientation == B_HORIZONTAL) { 1225 float pos = startPos; 1226 for (int32 i = 0; i < hashMarkCount; i++) { 1227 view->AddLine(BPoint(pos, rect.top), 1228 BPoint(pos, rect.top + 4), darkColor); 1229 view->AddLine(BPoint(pos + 1, rect.top), 1230 BPoint(pos + 1, rect.top + 4), lightColor); 1231 1232 pos += factor; 1233 } 1234 } else { 1235 float pos = startPos; 1236 for (int32 i = 0; i < hashMarkCount; i++) { 1237 view->AddLine(BPoint(rect.left, pos), 1238 BPoint(rect.left + 4, pos), darkColor); 1239 view->AddLine(BPoint(rect.left, pos + 1), 1240 BPoint(rect.left + 4, pos + 1), lightColor); 1241 1242 pos += factor; 1243 } 1244 } 1245 1246 view->EndLineArray(); 1247 } 1248 1249 if (location & B_HASH_MARKS_BOTTOM) { 1250 1251 view->BeginLineArray(hashMarkCount * 2); 1252 1253 if (orientation == B_HORIZONTAL) { 1254 float pos = startPos; 1255 for (int32 i = 0; i < hashMarkCount; i++) { 1256 view->AddLine(BPoint(pos, rect.bottom - 4), 1257 BPoint(pos, rect.bottom), darkColor); 1258 view->AddLine(BPoint(pos + 1, rect.bottom - 4), 1259 BPoint(pos + 1, rect.bottom), lightColor); 1260 1261 pos += factor; 1262 } 1263 } else { 1264 float pos = startPos; 1265 for (int32 i = 0; i < hashMarkCount; i++) { 1266 view->AddLine(BPoint(rect.right - 4, pos), 1267 BPoint(rect.right, pos), darkColor); 1268 view->AddLine(BPoint(rect.right - 4, pos + 1), 1269 BPoint(rect.right, pos + 1), lightColor); 1270 1271 pos += factor; 1272 } 1273 } 1274 1275 view->EndLineArray(); 1276 } 1277 } 1278 1279 1280 void 1281 BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, 1282 const rgb_color& base, uint32 flags, uint32 borders) 1283 { 1284 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1285 return; 1286 1287 rgb_color edgeShadowColor; 1288 rgb_color edgeLightColor; 1289 rgb_color frameShadowColor; 1290 rgb_color frameLightColor; 1291 rgb_color bevelShadowColor; 1292 rgb_color bevelLightColor; 1293 BGradientLinear fillGradient; 1294 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1295 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1296 1297 if (flags & B_DISABLED) { 1298 edgeShadowColor = base; 1299 edgeLightColor = base; 1300 frameShadowColor = tint_color(base, 1.30); 1301 frameLightColor = tint_color(base, 1.25); 1302 bevelShadowColor = tint_color(base, 1.07); 1303 bevelLightColor = tint_color(base, 0.8); 1304 fillGradient.AddColor(tint_color(base, 0.85), 0); 1305 fillGradient.AddColor(base, 255); 1306 } else { 1307 edgeShadowColor = tint_color(base, 1.03); 1308 edgeLightColor = tint_color(base, 0.80); 1309 frameShadowColor = tint_color(base, 1.30); 1310 frameLightColor = tint_color(base, 1.30); 1311 bevelShadowColor = tint_color(base, 1.07); 1312 bevelLightColor = tint_color(base, 0.6); 1313 fillGradient.AddColor(tint_color(base, 0.75), 0); 1314 fillGradient.AddColor(tint_color(base, 1.03), 255); 1315 } 1316 1317 static const float kRoundCornerRadius = 4; 1318 1319 // left/top corner 1320 BRect cornerRect(rect); 1321 cornerRect.right = cornerRect.left + kRoundCornerRadius; 1322 cornerRect.bottom = cornerRect.top + kRoundCornerRadius; 1323 1324 BRegion clipping(rect); 1325 clipping.Exclude(cornerRect); 1326 1327 _DrawRoundCornerLeftTop(view, cornerRect, updateRect, base, edgeShadowColor, 1328 frameLightColor, bevelLightColor, fillGradient); 1329 1330 // left/top corner 1331 cornerRect.right = rect.right; 1332 cornerRect.left = cornerRect.right - kRoundCornerRadius; 1333 1334 clipping.Exclude(cornerRect); 1335 1336 _DrawRoundCornerRightTop(view, cornerRect, updateRect, base, edgeShadowColor, 1337 edgeLightColor, frameLightColor, frameShadowColor, bevelLightColor, 1338 bevelShadowColor, fillGradient); 1339 1340 // rest of frame and fill 1341 view->ConstrainClippingRegion(&clipping); 1342 1343 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1344 edgeLightColor, 1345 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1346 if ((borders & B_LEFT_BORDER) == 0) 1347 rect.left++; 1348 if ((borders & B_RIGHT_BORDER) == 0) 1349 rect.right--; 1350 1351 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1352 frameShadowColor, B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); 1353 1354 _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, 1355 bevelShadowColor); 1356 1357 view->FillRect(rect, fillGradient); 1358 1359 view->ConstrainClippingRegion(NULL); 1360 } 1361 1362 1363 void 1364 BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, 1365 const rgb_color& base, uint32 flags, uint32 borders) 1366 { 1367 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1368 return; 1369 1370 rgb_color edgeShadowColor; 1371 rgb_color edgeLightColor; 1372 rgb_color frameShadowColor; 1373 rgb_color frameLightColor; 1374 rgb_color bevelShadowColor; 1375 rgb_color bevelLightColor; 1376 BGradientLinear fillGradient; 1377 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1378 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1379 1380 if (flags & B_DISABLED) { 1381 edgeShadowColor = base; 1382 edgeLightColor = base; 1383 frameShadowColor = tint_color(base, 1.30); 1384 frameLightColor = tint_color(base, 1.25); 1385 bevelShadowColor = tint_color(base, 1.07); 1386 bevelLightColor = tint_color(base, 0.8); 1387 fillGradient.AddColor(tint_color(base, 0.85), 0); 1388 fillGradient.AddColor(base, 255); 1389 } else { 1390 edgeShadowColor = tint_color(base, 1.03); 1391 edgeLightColor = tint_color(base, 0.80); 1392 frameShadowColor = tint_color(base, 1.30); 1393 frameLightColor = tint_color(base, 1.30); 1394 bevelShadowColor = tint_color(base, 1.17); 1395 bevelLightColor = tint_color(base, 1.10); 1396 fillGradient.AddColor(tint_color(base, 1.12), 0); 1397 fillGradient.AddColor(tint_color(base, 1.08), 255); 1398 } 1399 1400 // active tabs stand out at the top, but this is an inactive tab 1401 view->SetHighColor(base); 1402 view->FillRect(BRect(rect.left, rect.top, rect.right, rect.top + 4)); 1403 rect.top += 4; 1404 1405 // frame and fill 1406 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1407 edgeLightColor, 1408 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1409 1410 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1411 frameShadowColor, 1412 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1413 1414 _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, bevelLightColor, 1415 bevelLightColor, B_LEFT_BORDER & ~borders); 1416 1417 view->FillRect(rect, fillGradient); 1418 } 1419 1420 1421 // #pragma mark - 1422 1423 1424 void 1425 BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, 1426 const rgb_color& base, border_style border, uint32 flags, uint32 borders) 1427 { 1428 if (border == B_NO_BORDER) 1429 return; 1430 1431 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 1432 if (flags & B_FOCUSED) 1433 scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1434 1435 if (border == B_FANCY_BORDER) 1436 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 1437 1438 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 1439 scrollbarFrameColor, scrollbarFrameColor, borders); 1440 } 1441 1442 1443 void 1444 BControlLook::DrawRaisedBorder(BView* view, BRect& rect, 1445 const BRect& updateRect, const rgb_color& base, uint32 flags, 1446 uint32 borders) 1447 { 1448 rgb_color lightColor; 1449 rgb_color shadowColor; 1450 1451 if (flags & B_DISABLED) { 1452 lightColor = base; 1453 shadowColor = base; 1454 } else { 1455 lightColor = tint_color(base, 0.85); 1456 shadowColor = tint_color(base, 1.07); 1457 } 1458 1459 _DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor, 1460 borders); 1461 } 1462 1463 1464 void 1465 BControlLook::DrawTextControlBorder(BView* view, BRect& rect, 1466 const BRect& updateRect, const rgb_color& base, uint32 flags, 1467 uint32 borders) 1468 { 1469 if (!rect.Intersects(updateRect)) 1470 return; 1471 1472 rgb_color dark1BorderColor; 1473 rgb_color dark2BorderColor; 1474 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1475 1476 if (flags & B_DISABLED) { 1477 _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders); 1478 1479 if (flags & B_BLEND_FRAME) 1480 dark1BorderColor = (rgb_color){ 0, 0, 0, 40 }; 1481 else 1482 dark1BorderColor = tint_color(base, 1.15); 1483 dark2BorderColor = dark1BorderColor; 1484 } else if (flags & B_CLICKED) { 1485 dark1BorderColor = tint_color(base, 1.50); 1486 dark2BorderColor = tint_color(base, 1.49); 1487 1488 // BCheckBox uses this to indicate the clicked state... 1489 _DrawFrame(view, rect, 1490 dark1BorderColor, dark1BorderColor, 1491 dark2BorderColor, dark2BorderColor); 1492 1493 dark2BorderColor = dark1BorderColor; 1494 } else { 1495 _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders); 1496 1497 if (flags & B_BLEND_FRAME) { 1498 dark1BorderColor = (rgb_color){ 0, 0, 0, 102 }; 1499 dark2BorderColor = (rgb_color){ 0, 0, 0, 97 }; 1500 } else { 1501 dark1BorderColor = tint_color(base, 1.40); 1502 dark2BorderColor = tint_color(base, 1.38); 1503 } 1504 } 1505 1506 if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED)) { 1507 dark1BorderColor = navigationColor; 1508 dark2BorderColor = navigationColor; 1509 } 1510 1511 if (flags & B_BLEND_FRAME) { 1512 drawing_mode oldMode = view->DrawingMode(); 1513 view->SetDrawingMode(B_OP_ALPHA); 1514 1515 _DrawFrame(view, rect, 1516 dark1BorderColor, dark1BorderColor, 1517 dark2BorderColor, dark2BorderColor, borders); 1518 1519 view->SetDrawingMode(oldMode); 1520 } else { 1521 _DrawFrame(view, rect, 1522 dark1BorderColor, dark1BorderColor, 1523 dark2BorderColor, dark2BorderColor, borders); 1524 } 1525 } 1526 1527 1528 void 1529 BControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, 1530 const rgb_color& base, uint32 borders) 1531 { 1532 rgb_color frameColor = tint_color(base, 1.30); 1533 rgb_color bevelLight = tint_color(base, 0.8); 1534 rgb_color bevelShadow = tint_color(base, 1.03); 1535 1536 _DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight, 1537 borders); 1538 1539 _DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor, 1540 borders); 1541 1542 _DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow, 1543 borders); 1544 } 1545 1546 1547 void 1548 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1549 const BRect& updateRect, const rgb_color& base, uint32 flags) 1550 { 1551 DrawLabel(view, label, rect, updateRect, base, flags, 1552 DefaultLabelAlignment()); 1553 } 1554 1555 1556 void 1557 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1558 const BRect& updateRect, const rgb_color& base, uint32 flags, 1559 const BAlignment& alignment) 1560 { 1561 if (!rect.Intersects(updateRect)) 1562 return; 1563 1564 // setup the text color 1565 rgb_color color; 1566 if (base.red + base.green + base.blue > 128 * 3) 1567 color = tint_color(base, B_DARKEN_MAX_TINT); 1568 else 1569 color = tint_color(base, B_LIGHTEN_MAX_TINT); 1570 1571 if (flags & B_DISABLED) { 1572 color.red = (uint8)(((int32)base.red + color.red + 1) / 2); 1573 color.green = (uint8)(((int32)base.green + color.green + 1) / 2); 1574 color.blue = (uint8)(((int32)base.blue + color.blue + 1) / 2); 1575 } 1576 1577 view->SetHighColor(color); 1578 view->SetDrawingMode(B_OP_OVER); 1579 1580 // truncate the label if necessary and get the width and height 1581 BString truncatedLabel(label); 1582 1583 BFont font; 1584 view->GetFont(&font); 1585 1586 float width = rect.Width(); 1587 font.TruncateString(&truncatedLabel, B_TRUNCATE_END, width); 1588 width = font.StringWidth(truncatedLabel.String()); 1589 1590 font_height fontHeight; 1591 font.GetHeight(&fontHeight); 1592 float height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); 1593 1594 // handle alignment 1595 BPoint location; 1596 1597 switch (alignment.horizontal) { 1598 default: 1599 case B_ALIGN_LEFT: 1600 location.x = rect.left; 1601 break; 1602 case B_ALIGN_RIGHT: 1603 location.x = rect.right - width; 1604 break; 1605 case B_ALIGN_CENTER: 1606 location.x = (rect.left + rect.right - width) / 2.0f; 1607 break; 1608 } 1609 1610 switch (alignment.vertical) { 1611 case B_ALIGN_TOP: 1612 location.y = rect.top + ceilf(fontHeight.ascent); 1613 break; 1614 default: 1615 case B_ALIGN_MIDDLE: 1616 location.y = floorf((rect.top + rect.bottom - height) / 2.0f + 0.5f) 1617 + ceilf(fontHeight.ascent); 1618 break; 1619 case B_ALIGN_BOTTOM: 1620 location.y = rect.bottom - ceilf(fontHeight.descent); 1621 break; 1622 } 1623 1624 view->DrawString(truncatedLabel.String(), location); 1625 } 1626 1627 1628 // #pragma mark - 1629 1630 1631 void 1632 BControlLook::_DrawButtonFrame(BView* view, BRect& rect, 1633 const BRect& updateRect, const rgb_color& base, const rgb_color& background, 1634 float contrast, float brightness, uint32 flags, uint32 borders) 1635 { 1636 // colors 1637 rgb_color dark1BorderColor; 1638 rgb_color dark2BorderColor; 1639 1640 if ((flags & B_DISABLED) == 0) { 1641 if (flags & B_BLEND_FRAME) { 1642 dark1BorderColor = (rgb_color){ 0, 0, 0, 75 }; 1643 dark2BorderColor = (rgb_color){ 0, 0, 0, 95 }; 1644 } else { 1645 dark1BorderColor = tint_color(base, 1.33); 1646 dark2BorderColor = tint_color(base, 1.45); 1647 } 1648 1649 if (flags & B_DEFAULT_BUTTON) { 1650 // TODO: B_BLEND_FRAME 1651 dark2BorderColor = tint_color(dark1BorderColor, 1.5); 1652 dark1BorderColor = tint_color(dark1BorderColor, 1.35); 1653 } 1654 } else { 1655 // TODO: B_BLEND_FRAME 1656 dark1BorderColor = tint_color(base, 1.147); 1657 dark2BorderColor = tint_color(base, 1.24); 1658 1659 if (flags & B_DEFAULT_BUTTON) { 1660 dark1BorderColor = tint_color(dark1BorderColor, 1.14); 1661 dark2BorderColor = tint_color(dark1BorderColor, 1.12); 1662 } 1663 } 1664 1665 if (flags & B_ACTIVATED) { 1666 rgb_color temp = dark2BorderColor; 1667 dark2BorderColor = dark1BorderColor; 1668 dark1BorderColor = temp; 1669 } 1670 1671 // indicate focus by changing main button border 1672 if (flags & B_FOCUSED) { 1673 dark1BorderColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1674 dark2BorderColor = dark1BorderColor; 1675 } 1676 1677 if (flags & B_DEFAULT_BUTTON) { 1678 // TODO: B_BLEND_FRAME 1679 float focusTint = 1.2; 1680 if (flags & B_DISABLED) 1681 focusTint = (B_NO_TINT + focusTint) / 2; 1682 1683 rgb_color focusColor = tint_color(base, focusTint); 1684 view->SetHighColor(base); 1685 1686 view->StrokeRect(rect); 1687 rect.InsetBy(1.0, 1.0); 1688 1689 view->SetHighColor(focusColor); 1690 view->StrokeRect(rect); 1691 rect.InsetBy(1.0, 1.0); 1692 view->StrokeRect(rect); 1693 rect.InsetBy(1.0, 1.0); 1694 1695 // bevel around external border 1696 _DrawOuterResessedFrame(view, rect, focusColor, 1697 contrast * (((flags & B_DISABLED) ? 0.3 : 0.8)), 1698 brightness * (((flags & B_DISABLED) ? 1.0 : 0.9)), 1699 flags, borders); 1700 } else { 1701 // bevel around external border 1702 _DrawOuterResessedFrame(view, rect, background, 1703 contrast * ((flags & B_DISABLED) ? 0.0 : 1.0), brightness * 1.0, 1704 flags, borders); 1705 } 1706 1707 if (flags & B_BLEND_FRAME) { 1708 drawing_mode oldDrawingMode = view->DrawingMode(); 1709 view->SetDrawingMode(B_OP_ALPHA); 1710 1711 _DrawFrame(view, rect, dark1BorderColor, dark1BorderColor, 1712 dark2BorderColor, dark2BorderColor, borders); 1713 1714 view->SetDrawingMode(oldDrawingMode); 1715 } else { 1716 _DrawFrame(view, rect, dark1BorderColor, dark1BorderColor, 1717 dark2BorderColor, dark2BorderColor, borders); 1718 } 1719 } 1720 1721 1722 void 1723 BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, 1724 const rgb_color& base, float contrast, float brightness, uint32 flags, 1725 uint32 borders) 1726 { 1727 if (flags & B_BLEND_FRAME) { 1728 // assumes the background has already been painted 1729 drawing_mode oldDrawingMode = view->DrawingMode(); 1730 view->SetDrawingMode(B_OP_ALPHA); 1731 1732 uint8 alpha = uint8(20 * contrast); 1733 uint32 white = uint8(255 * brightness); 1734 1735 rgb_color borderBevelShadow = (rgb_color){ 0, 0, 0, alpha }; 1736 rgb_color borderBevelLight = (rgb_color){ white, white, white, alpha }; 1737 1738 _DrawFrame(view, rect, borderBevelShadow, borderBevelShadow, 1739 borderBevelLight, borderBevelLight, borders); 1740 1741 view->SetDrawingMode(oldDrawingMode); 1742 } else { 1743 // colors 1744 float tintLight = kEdgeBevelLightTint; 1745 float tintShadow = kEdgeBevelShadowTint; 1746 1747 if (contrast == 0.0) { 1748 tintLight = B_NO_TINT; 1749 tintShadow = B_NO_TINT; 1750 } else if (contrast != 1.0) { 1751 tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; 1752 tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; 1753 } 1754 1755 rgb_color borderBevelShadow = tint_color(base, tintShadow); 1756 rgb_color borderBevelLight = tint_color(base, tintLight); 1757 1758 if (brightness < 1.0) { 1759 borderBevelShadow.red = uint8(borderBevelShadow.red * brightness); 1760 borderBevelShadow.green = uint8(borderBevelShadow.green * brightness); 1761 borderBevelShadow.blue = uint8(borderBevelShadow.blue * brightness); 1762 borderBevelLight.red = uint8(borderBevelLight.red * brightness); 1763 borderBevelLight.green = uint8(borderBevelLight.green * brightness); 1764 borderBevelLight.blue = uint8(borderBevelLight.blue * brightness); 1765 } 1766 1767 _DrawFrame(view, rect, borderBevelShadow, borderBevelShadow, 1768 borderBevelLight, borderBevelLight, borders); 1769 } 1770 } 1771 1772 1773 void 1774 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 1775 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 1776 uint32 borders) 1777 { 1778 view->BeginLineArray(4); 1779 1780 if (borders & B_LEFT_BORDER) { 1781 view->AddLine( 1782 BPoint(rect.left, rect.bottom), 1783 BPoint(rect.left, rect.top), left); 1784 rect.left++; 1785 } 1786 if (borders & B_TOP_BORDER) { 1787 view->AddLine( 1788 BPoint(rect.left, rect.top), 1789 BPoint(rect.right, rect.top), top); 1790 rect.top++; 1791 } 1792 if (borders & B_RIGHT_BORDER) { 1793 view->AddLine( 1794 BPoint(rect.right, rect.top), 1795 BPoint(rect.right, rect.bottom), right); 1796 rect.right--; 1797 } 1798 if (borders & B_BOTTOM_BORDER) { 1799 view->AddLine( 1800 BPoint(rect.left, rect.bottom), 1801 BPoint(rect.right, rect.bottom), bottom); 1802 rect.bottom--; 1803 } 1804 1805 view->EndLineArray(); 1806 } 1807 1808 1809 void 1810 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 1811 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 1812 const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders) 1813 { 1814 view->BeginLineArray(6); 1815 1816 if (borders & B_TOP_BORDER) { 1817 if (borders & B_RIGHT_BORDER) { 1818 view->AddLine( 1819 BPoint(rect.left, rect.top), 1820 BPoint(rect.right - 1, rect.top), top); 1821 view->AddLine( 1822 BPoint(rect.right, rect.top), 1823 BPoint(rect.right, rect.top), rightTop); 1824 } else { 1825 view->AddLine( 1826 BPoint(rect.left, rect.top), 1827 BPoint(rect.right, rect.top), top); 1828 } 1829 rect.top++; 1830 } 1831 1832 if (borders & B_LEFT_BORDER) { 1833 view->AddLine( 1834 BPoint(rect.left, rect.top), 1835 BPoint(rect.left, rect.bottom - 1), left); 1836 view->AddLine( 1837 BPoint(rect.left, rect.bottom), 1838 BPoint(rect.left, rect.bottom), leftBottom); 1839 rect.left++; 1840 } 1841 1842 if (borders & B_BOTTOM_BORDER) { 1843 view->AddLine( 1844 BPoint(rect.left, rect.bottom), 1845 BPoint(rect.right, rect.bottom), bottom); 1846 rect.bottom--; 1847 } 1848 1849 if (borders & B_RIGHT_BORDER) { 1850 view->AddLine( 1851 BPoint(rect.right, rect.bottom), 1852 BPoint(rect.right, rect.top), right); 1853 rect.right--; 1854 } 1855 1856 view->EndLineArray(); 1857 } 1858 1859 1860 //void 1861 //BControlLook::_DrawShadowFrame(BView* view, BRect& rect, const rgb_color& base, 1862 // uint32 borders) 1863 //{ 1864 // view->BeginLineArray(4); 1865 // 1866 // bevelColor1 = tint_color(base, 1.2); 1867 // bevelColor2 = tint_color(base, 1.1); 1868 // 1869 // // shadow along left/top borders 1870 // if (rect.Height() > 0 && borders & B_LEFT_BORDER) { 1871 // view->AddLine(BPoint(rect.left, rect.top), 1872 // BPoint(rect.left, rect.bottom), bevelColor1); 1873 // rect.left++; 1874 // } 1875 // if (rect.Width() > 0 && borders & B_TOP_BORDER) { 1876 // view->AddLine(BPoint(rect.left, rect.top), 1877 // BPoint(rect.right, rect.top), bevelColor1); 1878 // rect.top++; 1879 // } 1880 // 1881 // // softer shadow along left/top borders 1882 // if (rect.Height() > 0 && borders & B_LEFT_BORDER) { 1883 // view->AddLine(BPoint(rect.left, rect.top), 1884 // BPoint(rect.left, rect.bottom), bevelColor2); 1885 // rect.left++; 1886 // } 1887 // if (rect.Width() > 0 && borders & B_TOP_BORDER) { 1888 // view->AddLine(BPoint(rect.left, rect.top), 1889 // BPoint(rect.right, rect.top), bevelColor2); 1890 // rect.top++; 1891 // } 1892 // 1893 // view->EndLineArray(); 1894 //} 1895 1896 1897 void 1898 BControlLook::_FillGradient(BView* view, const BRect& rect, 1899 const rgb_color& base, float topTint, float bottomTint, 1900 enum orientation orientation) 1901 { 1902 BGradientLinear gradient; 1903 _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); 1904 view->FillRect(rect, gradient); 1905 } 1906 1907 1908 void 1909 BControlLook::_FillGlossyGradient(BView* view, const BRect& rect, 1910 const rgb_color& base, float topTint, float middle1Tint, 1911 float middle2Tint, float bottomTint, enum orientation orientation) 1912 { 1913 BGradientLinear gradient; 1914 _MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint, 1915 middle2Tint, bottomTint, orientation); 1916 view->FillRect(rect, gradient); 1917 } 1918 1919 1920 void 1921 BControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect, 1922 const rgb_color& base, float topTint, float bottomTint, 1923 enum orientation orientation) const 1924 { 1925 gradient.AddColor(tint_color(base, topTint), 0); 1926 gradient.AddColor(tint_color(base, bottomTint), 255); 1927 gradient.SetStart(rect.LeftTop()); 1928 if (orientation == B_HORIZONTAL) 1929 gradient.SetEnd(rect.LeftBottom()); 1930 else 1931 gradient.SetEnd(rect.RightTop()); 1932 } 1933 1934 1935 void 1936 BControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect, 1937 const rgb_color& base, float topTint, float middle1Tint, 1938 float middle2Tint, float bottomTint, 1939 enum orientation orientation) const 1940 { 1941 gradient.AddColor(tint_color(base, topTint), 0); 1942 gradient.AddColor(tint_color(base, middle1Tint), 132); 1943 gradient.AddColor(tint_color(base, middle2Tint), 136); 1944 gradient.AddColor(tint_color(base, bottomTint), 255); 1945 gradient.SetStart(rect.LeftTop()); 1946 if (orientation == B_HORIZONTAL) 1947 gradient.SetEnd(rect.LeftBottom()); 1948 else 1949 gradient.SetEnd(rect.RightTop()); 1950 } 1951 1952 1953 bool 1954 BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, 1955 rgb_color& color, uint32 flags) const 1956 { 1957 if ((flags & (B_ACTIVATED | B_CLICKED)) == 0) { 1958 // no mark to be drawn at all 1959 return false; 1960 } 1961 1962 // TODO: Get from UI settings 1963 color.red = 27; 1964 color.green = 82; 1965 color.blue = 140; 1966 1967 float mix = 1.0; 1968 1969 if (flags & B_DISABLED) { 1970 // activated, but disabled 1971 mix = 0.4; 1972 } else if (flags & B_CLICKED) { 1973 if (flags & B_ACTIVATED) { 1974 // loosing activation 1975 mix = 0.7; 1976 } else { 1977 // becoming activated 1978 mix = 0.3; 1979 } 1980 } else { 1981 // simply activated 1982 } 1983 1984 color.red = uint8(color.red * mix + base.red * (1.0 - mix)); 1985 color.green = uint8(color.green * mix + base.green * (1.0 - mix)); 1986 color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix)); 1987 1988 return true; 1989 } 1990 1991 1992 void 1993 BControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, 1994 const BRect& updateRect, 1995 const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor, 1996 const rgb_color& frameLightColor, const rgb_color& frameShadowColor, 1997 const rgb_color& fillLightColor, const rgb_color& fillShadowColor, 1998 float leftInset, float topInset, float rightInset, float bottomInset, 1999 enum orientation orientation) 2000 { 2001 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2002 return; 2003 2004 BGradientLinear gradient; 2005 gradient.AddColor(edgeShadowColor, 0); 2006 gradient.AddColor(edgeLightColor, 255); 2007 gradient.SetStart(rect.LeftTop()); 2008 if (orientation == B_HORIZONTAL) 2009 gradient.SetEnd(rect.LeftBottom()); 2010 else 2011 gradient.SetEnd(rect.RightTop()); 2012 2013 view->FillEllipse(rect, gradient); 2014 2015 rect.left += leftInset; 2016 rect.top += topInset; 2017 rect.right += rightInset; 2018 rect.bottom += bottomInset; 2019 2020 gradient.MakeEmpty(); 2021 gradient.AddColor(frameShadowColor, 0); 2022 gradient.AddColor(frameLightColor, 255); 2023 gradient.SetStart(rect.LeftTop()); 2024 if (orientation == B_HORIZONTAL) 2025 gradient.SetEnd(rect.LeftBottom()); 2026 else 2027 gradient.SetEnd(rect.RightTop()); 2028 2029 view->FillEllipse(rect, gradient); 2030 2031 rect.left += leftInset; 2032 rect.top += topInset; 2033 rect.right += rightInset; 2034 rect.bottom += bottomInset; 2035 2036 gradient.MakeEmpty(); 2037 gradient.AddColor(fillShadowColor, 0); 2038 gradient.AddColor(fillLightColor, 255); 2039 gradient.SetStart(rect.LeftTop()); 2040 if (orientation == B_HORIZONTAL) 2041 gradient.SetEnd(rect.LeftBottom()); 2042 else 2043 gradient.SetEnd(rect.RightTop()); 2044 2045 view->FillEllipse(rect, gradient); 2046 } 2047 2048 2049 void 2050 BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& rect, 2051 const BRect& updateRect, const rgb_color& base, const rgb_color& edgeColor, 2052 const rgb_color& frameColor, const rgb_color& bevelColor, 2053 const BGradientLinear& fillGradient) 2054 { 2055 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2056 return; 2057 2058 BRegion clipping(rect); 2059 view->ConstrainClippingRegion(&clipping); 2060 2061 // background 2062 view->SetHighColor(base); 2063 view->FillRect(rect); 2064 2065 // outer edge 2066 BRect ellipseRect(rect); 2067 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2068 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2069 2070 view->SetHighColor(edgeColor); 2071 view->FillEllipse(ellipseRect); 2072 2073 // frame 2074 ellipseRect.InsetBy(1, 1); 2075 view->SetHighColor(frameColor); 2076 view->FillEllipse(ellipseRect); 2077 2078 // bevel 2079 ellipseRect.InsetBy(1, 1); 2080 view->SetHighColor(bevelColor); 2081 view->FillEllipse(ellipseRect); 2082 2083 // fill 2084 ellipseRect.InsetBy(1, 1); 2085 view->FillEllipse(ellipseRect, fillGradient); 2086 2087 view->ConstrainClippingRegion(NULL); 2088 } 2089 2090 void 2091 BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& rect, 2092 const BRect& updateRect, const rgb_color& base, 2093 const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, 2094 const rgb_color& frameTopColor, const rgb_color& frameRightColor, 2095 const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, 2096 const BGradientLinear& fillGradient) 2097 { 2098 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2099 return; 2100 2101 BRegion clipping(rect); 2102 view->ConstrainClippingRegion(&clipping); 2103 2104 // background 2105 view->SetHighColor(base); 2106 view->FillRect(rect); 2107 2108 // outer edge 2109 BRect ellipseRect(rect); 2110 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2111 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2112 2113 BGradientLinear gradient; 2114 gradient.AddColor(edgeTopColor, 0); 2115 gradient.AddColor(edgeRightColor, 255); 2116 gradient.SetStart(rect.LeftTop()); 2117 gradient.SetEnd(rect.RightBottom()); 2118 view->FillEllipse(ellipseRect, gradient); 2119 2120 // frame 2121 ellipseRect.InsetBy(1, 1); 2122 rect.right--; 2123 rect.top++; 2124 if (frameTopColor == frameRightColor) { 2125 view->SetHighColor(frameTopColor); 2126 view->FillEllipse(ellipseRect); 2127 } else { 2128 gradient.SetColor(0, frameTopColor); 2129 gradient.SetColor(1, frameRightColor); 2130 gradient.SetStart(rect.LeftTop()); 2131 gradient.SetEnd(rect.RightBottom()); 2132 view->FillEllipse(ellipseRect, gradient); 2133 } 2134 2135 // bevel 2136 ellipseRect.InsetBy(1, 1); 2137 rect.right--; 2138 rect.top++; 2139 gradient.SetColor(0, bevelTopColor); 2140 gradient.SetColor(1, bevelRightColor); 2141 gradient.SetStart(rect.LeftTop()); 2142 gradient.SetEnd(rect.RightBottom()); 2143 view->FillEllipse(ellipseRect, gradient); 2144 2145 // fill 2146 ellipseRect.InsetBy(1, 1); 2147 view->FillEllipse(ellipseRect, fillGradient); 2148 2149 view->ConstrainClippingRegion(NULL); 2150 } 2151 2152 2153 // NOTE: May come from a add-on in the future. Initialized in 2154 // InterfaceDefs.cpp 2155 BControlLook* be_control_look = NULL; 2156 2157 } // namespace BPrivate 2158