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 // calculate scroll corner rect before messing with the "rect" 700 BRect scrollCornerFillRect(rect.right, rect.bottom, 701 rect.right, rect.bottom); 702 if (horizontalScrollBarFrame.IsValid()) 703 scrollCornerFillRect.left = horizontalScrollBarFrame.right + 1; 704 if (verticalScrollBarFrame.IsValid()) 705 scrollCornerFillRect.top = verticalScrollBarFrame.bottom + 1; 706 707 if (border == B_NO_BORDER) { 708 if (scrollCornerFillRect.IsValid()) { 709 view->SetHighColor(base); 710 view->FillRect(scrollCornerFillRect); 711 } 712 return; 713 } 714 715 bool excludeScrollCorner = border == B_FANCY_BORDER 716 && horizontalScrollBarFrame.IsValid() 717 && verticalScrollBarFrame.IsValid(); 718 719 uint32 borders = _borders; 720 if (excludeScrollCorner) { 721 rect.bottom = horizontalScrollBarFrame.top; 722 rect.right = verticalScrollBarFrame.left; 723 borders &= ~(B_RIGHT_BORDER | B_BOTTOM_BORDER); 724 } 725 726 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 727 728 if (border == B_FANCY_BORDER) 729 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 730 731 if (flags & B_FOCUSED) { 732 rgb_color focusColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 733 _DrawFrame(view, rect, focusColor, focusColor, focusColor, focusColor, 734 borders); 735 } else { 736 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 737 scrollbarFrameColor, scrollbarFrameColor, borders); 738 } 739 740 if (excludeScrollCorner) { 741 horizontalScrollBarFrame.InsetBy(-1, -1); 742 // do not overdraw the top edge 743 horizontalScrollBarFrame.top += 2; 744 borders = _borders; 745 borders &= ~B_TOP_BORDER; 746 _DrawOuterResessedFrame(view, horizontalScrollBarFrame, base, 747 1.0, 1.0, flags, borders); 748 _DrawFrame(view, horizontalScrollBarFrame, scrollbarFrameColor, 749 scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, 750 borders); 751 752 753 verticalScrollBarFrame.InsetBy(-1, -1); 754 // do not overdraw the left edge 755 verticalScrollBarFrame.left += 2; 756 borders = _borders; 757 borders &= ~B_LEFT_BORDER; 758 _DrawOuterResessedFrame(view, verticalScrollBarFrame, base, 759 1.0, 1.0, flags, borders); 760 _DrawFrame(view, verticalScrollBarFrame, scrollbarFrameColor, 761 scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, 762 borders); 763 764 // exclude recessed frame 765 scrollCornerFillRect.top++; 766 scrollCornerFillRect.left++; 767 } 768 769 if (scrollCornerFillRect.IsValid()) { 770 view->SetHighColor(base); 771 view->FillRect(scrollCornerFillRect); 772 } 773 } 774 775 776 void 777 BControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, 778 const rgb_color& base, uint32 direction, uint32 flags, float tint) 779 { 780 BPoint tri1, tri2, tri3; 781 float hInset = rect.Width() / 3; 782 float vInset = rect.Height() / 3; 783 rect.InsetBy(hInset, vInset); 784 785 switch (direction) { 786 case B_LEFT_ARROW: 787 tri1.Set(rect.right, rect.top); 788 tri2.Set(rect.right - rect.Width() / 1.33, 789 (rect.top + rect.bottom + 1) /2 ); 790 tri3.Set(rect.right, rect.bottom + 1); 791 break; 792 case B_RIGHT_ARROW: 793 tri1.Set(rect.left, rect.bottom + 1); 794 tri2.Set(rect.left + rect.Width() / 1.33, 795 (rect.top + rect.bottom + 1) / 2); 796 tri3.Set(rect.left, rect.top); 797 break; 798 case B_UP_ARROW: 799 tri1.Set(rect.left, rect.bottom); 800 tri2.Set((rect.left + rect.right + 1) / 2, 801 rect.bottom - rect.Height() / 1.33); 802 tri3.Set(rect.right + 1, rect.bottom); 803 break; 804 case B_DOWN_ARROW: 805 default: 806 tri1.Set(rect.left, rect.top); 807 tri2.Set((rect.left + rect.right + 1) / 2, 808 rect.top + rect.Height() / 1.33); 809 tri3.Set(rect.right + 1, rect.top); 810 break; 811 } 812 // offset triangle if down 813 if (flags & B_ACTIVATED) 814 view->MovePenTo(BPoint(1, 1)); 815 else 816 view->MovePenTo(BPoint(0, 0)); 817 818 BShape arrowShape; 819 arrowShape.MoveTo(tri1); 820 arrowShape.LineTo(tri2); 821 arrowShape.LineTo(tri3); 822 823 if (flags & B_DISABLED) 824 tint = (tint + B_NO_TINT + B_NO_TINT) / 3; 825 826 view->SetHighColor(tint_color(base, tint)); 827 828 float penSize = view->PenSize(); 829 drawing_mode mode = view->DrawingMode(); 830 831 view->SetPenSize(ceilf(hInset / 2.0)); 832 view->SetDrawingMode(B_OP_OVER); 833 view->StrokeShape(&arrowShape); 834 835 view->SetPenSize(penSize); 836 view->SetDrawingMode(mode); 837 } 838 839 840 rgb_color 841 BControlLook::SliderBarColor(const rgb_color& base) 842 { 843 return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT); 844 } 845 846 847 void 848 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 849 const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, 850 float sliderScale, uint32 flags, enum orientation orientation) 851 { 852 if (!rect.IsValid() || !rect.Intersects(updateRect)) 853 return; 854 855 // separate the bar in two sides 856 float sliderPosition; 857 BRect leftBarSide = rect; 858 BRect rightBarSide = rect; 859 860 if (orientation == B_HORIZONTAL) { 861 sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) 862 * sliderScale); 863 leftBarSide.right = sliderPosition - 1; 864 rightBarSide.left = sliderPosition; 865 } else { 866 sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) 867 * sliderScale); 868 leftBarSide.bottom = sliderPosition - 1; 869 rightBarSide.top = sliderPosition; 870 } 871 872 // fill the background for the corners, exclude the middle bar for now 873 BRegion region(rect); 874 region.Exclude(rightBarSide); 875 view->ConstrainClippingRegion(®ion); 876 877 view->PushState(); 878 879 DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, 880 orientation); 881 882 view->PopState(); 883 884 region.Set(rect); 885 region.Exclude(leftBarSide); 886 view->ConstrainClippingRegion(®ion); 887 888 view->PushState(); 889 890 DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, 891 orientation); 892 893 view->PopState(); 894 895 view->ConstrainClippingRegion(NULL); 896 } 897 898 899 void 900 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 901 const rgb_color& base, rgb_color fillColor, uint32 flags, 902 enum orientation orientation) 903 { 904 if (!rect.IsValid() || !rect.Intersects(updateRect)) 905 return; 906 907 // separate the rect into corners 908 BRect leftCorner(rect); 909 BRect rightCorner(rect); 910 BRect barRect(rect); 911 912 if (orientation == B_HORIZONTAL) { 913 leftCorner.right = leftCorner.left + leftCorner.Height(); 914 rightCorner.left = rightCorner.right - rightCorner.Height(); 915 barRect.left += ceilf(barRect.Height() / 2); 916 barRect.right -= ceilf(barRect.Height() / 2); 917 } else { 918 leftCorner.bottom = leftCorner.top + leftCorner.Width(); 919 rightCorner.top = rightCorner.bottom - rightCorner.Width(); 920 barRect.top += ceilf(barRect.Width() / 2); 921 barRect.bottom -= ceilf(barRect.Width() / 2); 922 } 923 924 // fill the background for the corners, exclude the middle bar for now 925 BRegion region(rect); 926 region.Exclude(barRect); 927 view->ConstrainClippingRegion(®ion); 928 929 view->SetHighColor(base); 930 view->FillRect(rect); 931 932 // figure out the tints to be used 933 float edgeLightTint; 934 float edgeShadowTint; 935 float frameLightTint; 936 float frameShadowTint; 937 float fillLightTint; 938 float fillShadowTint; 939 940 if (flags & B_DISABLED) { 941 edgeLightTint = 1.0; 942 edgeShadowTint = 1.0; 943 frameLightTint = 1.20; 944 frameShadowTint = 1.25; 945 fillLightTint = 0.9; 946 fillShadowTint = 1.05; 947 948 fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6); 949 fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6); 950 fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6); 951 } else { 952 edgeLightTint = 0.65; 953 edgeShadowTint = 1.07; 954 frameLightTint = 1.40; 955 frameShadowTint = 1.50; 956 fillLightTint = 0.8; 957 fillShadowTint = 1.1; 958 } 959 960 rgb_color edgeLightColor = tint_color(base, edgeLightTint); 961 rgb_color edgeShadowColor = tint_color(base, edgeShadowTint); 962 rgb_color frameLightColor = tint_color(fillColor, frameLightTint); 963 rgb_color frameShadowColor = tint_color(fillColor, frameShadowTint); 964 rgb_color fillLightColor = tint_color(fillColor, fillLightTint); 965 rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); 966 967 if (orientation == B_HORIZONTAL) { 968 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 969 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 970 fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); 971 972 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 973 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 974 fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); 975 } else { 976 _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, 977 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 978 fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); 979 980 _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, 981 edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, 982 fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); 983 } 984 985 view->ConstrainClippingRegion(NULL); 986 987 view->BeginLineArray(4); 988 if (orientation == B_HORIZONTAL) { 989 view->AddLine(barRect.LeftTop(), barRect.RightTop(), edgeShadowColor); 990 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 991 edgeLightColor); 992 barRect.InsetBy(0, 1); 993 view->AddLine(barRect.LeftTop(), barRect.RightTop(), frameShadowColor); 994 view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), 995 frameLightColor); 996 barRect.InsetBy(0, 1); 997 } else { 998 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), edgeShadowColor); 999 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 1000 edgeLightColor); 1001 barRect.InsetBy(1, 0); 1002 view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), frameShadowColor); 1003 view->AddLine(barRect.RightTop(), barRect.RightBottom(), 1004 frameLightColor); 1005 barRect.InsetBy(1, 0); 1006 } 1007 view->EndLineArray(); 1008 1009 _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, 1010 orientation); 1011 } 1012 1013 1014 void 1015 BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, 1016 const rgb_color& base, uint32 flags, enum orientation orientation) 1017 { 1018 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1019 return; 1020 1021 // figure out frame color 1022 rgb_color frameLightColor; 1023 rgb_color frameShadowColor; 1024 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1025 1026 if (flags & B_FOCUSED) { 1027 // focused 1028 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1029 frameShadowColor = frameLightColor; 1030 } else { 1031 // figure out the tints to be used 1032 float frameLightTint; 1033 float frameShadowTint; 1034 1035 if (flags & B_DISABLED) { 1036 frameLightTint = 1.30; 1037 frameShadowTint = 1.35; 1038 shadowColor.alpha = 30; 1039 } else { 1040 frameLightTint = 1.6; 1041 frameShadowTint = 1.65; 1042 } 1043 1044 frameLightColor = tint_color(base, frameLightTint); 1045 frameShadowColor = tint_color(base, frameShadowTint); 1046 } 1047 1048 BRect originalRect(rect); 1049 rect.right--; 1050 rect.bottom--; 1051 1052 _DrawFrame(view, rect, frameLightColor, frameLightColor, 1053 frameShadowColor, frameShadowColor); 1054 1055 flags &= ~B_ACTIVATED; 1056 DrawButtonBackground(view, rect, updateRect, base, flags); 1057 1058 // thumb shadow 1059 view->SetDrawingMode(B_OP_ALPHA); 1060 view->SetHighColor(shadowColor); 1061 originalRect.left++; 1062 originalRect.top++; 1063 view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom()); 1064 originalRect.bottom--; 1065 view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom()); 1066 1067 // thumb edge 1068 if (orientation == B_HORIZONTAL) { 1069 rect.InsetBy(0, floorf(rect.Height() / 4)); 1070 rect.left = floorf((rect.left + rect.right) / 2); 1071 rect.right = rect.left + 1; 1072 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1073 shadowColor.alpha = 128; 1074 view->SetHighColor(shadowColor); 1075 view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); 1076 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1077 lightColor.alpha = 128; 1078 view->SetHighColor(lightColor); 1079 view->StrokeLine(rect.RightTop(), rect.RightBottom()); 1080 } else { 1081 rect.InsetBy(floorf(rect.Width() / 4), 0); 1082 rect.top = floorf((rect.top + rect.bottom) / 2); 1083 rect.bottom = rect.top + 1; 1084 shadowColor = tint_color(base, B_DARKEN_2_TINT); 1085 shadowColor.alpha = 128; 1086 view->SetHighColor(shadowColor); 1087 view->StrokeLine(rect.LeftTop(), rect.RightTop()); 1088 rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); 1089 lightColor.alpha = 128; 1090 view->SetHighColor(lightColor); 1091 view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); 1092 } 1093 1094 view->SetDrawingMode(B_OP_COPY); 1095 } 1096 1097 1098 void 1099 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1100 const BRect& updateRect, const rgb_color& base, uint32 flags, 1101 enum orientation orientation) 1102 { 1103 DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); 1104 } 1105 1106 1107 void 1108 BControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1109 const BRect& updateRect, const rgb_color& base, const rgb_color& fill, 1110 uint32 flags, enum orientation orientation) 1111 { 1112 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1113 return; 1114 1115 // figure out frame color 1116 rgb_color frameLightColor; 1117 rgb_color frameShadowColor; 1118 rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; 1119 1120 float topTint = 0.49; 1121 float middleTint1 = 0.62; 1122 float middleTint2 = 0.76; 1123 float bottomTint = 0.90; 1124 1125 if (flags & B_DISABLED) { 1126 topTint = (topTint + B_NO_TINT) / 2; 1127 middleTint1 = (middleTint1 + B_NO_TINT) / 2; 1128 middleTint2 = (middleTint2 + B_NO_TINT) / 2; 1129 bottomTint = (bottomTint + B_NO_TINT) / 2; 1130 } else if (flags & B_HOVER) { 1131 static const float kHoverTintFactor = 0.85; 1132 topTint *= kHoverTintFactor; 1133 middleTint1 *= kHoverTintFactor; 1134 middleTint2 *= kHoverTintFactor; 1135 bottomTint *= kHoverTintFactor; 1136 } 1137 1138 if (flags & B_FOCUSED) { 1139 // focused 1140 frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1141 frameShadowColor = frameLightColor; 1142 } else { 1143 // figure out the tints to be used 1144 float frameLightTint; 1145 float frameShadowTint; 1146 1147 if (flags & B_DISABLED) { 1148 frameLightTint = 1.30; 1149 frameShadowTint = 1.35; 1150 shadowColor.alpha = 30; 1151 } else { 1152 frameLightTint = 1.6; 1153 frameShadowTint = 1.65; 1154 } 1155 1156 frameLightColor = tint_color(base, frameLightTint); 1157 frameShadowColor = tint_color(base, frameShadowTint); 1158 } 1159 1160 // make room for the shadow 1161 rect.right--; 1162 rect.bottom--; 1163 1164 uint32 viewFlags = view->Flags(); 1165 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 1166 view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); 1167 1168 float center = (rect.left + rect.right) / 2; 1169 1170 BShape shape; 1171 shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5)); 1172 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); 1173 shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5)); 1174 shape.LineTo(BPoint(center + 0.5, rect.top + 0.5)); 1175 shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); 1176 shape.Close(); 1177 1178 view->MovePenTo(BPoint(1, 1)); 1179 1180 view->SetDrawingMode(B_OP_ALPHA); 1181 view->SetHighColor(shadowColor); 1182 view->StrokeShape(&shape); 1183 1184 view->MovePenTo(B_ORIGIN); 1185 1186 view->SetDrawingMode(B_OP_COPY); 1187 view->SetHighColor(frameLightColor); 1188 view->StrokeShape(&shape); 1189 1190 rect.InsetBy(1, 1); 1191 shape.Clear(); 1192 shape.MoveTo(BPoint(rect.left, rect.bottom + 1)); 1193 shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); 1194 shape.LineTo(BPoint(center + 0.5, rect.top)); 1195 shape.Close(); 1196 1197 BGradientLinear gradient; 1198 if (flags & B_DISABLED) { 1199 _MakeGradient(gradient, rect, fill, topTint, bottomTint); 1200 } else { 1201 _MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1, 1202 middleTint2, bottomTint); 1203 } 1204 1205 view->FillShape(&shape, gradient); 1206 1207 view->SetFlags(viewFlags); 1208 } 1209 1210 1211 void 1212 BControlLook::DrawSliderHashMarks(BView* view, BRect& rect, 1213 const BRect& updateRect, const rgb_color& base, int32 count, 1214 hash_mark_location location, uint32 flags, enum orientation orientation) 1215 { 1216 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1217 return; 1218 1219 rgb_color lightColor; 1220 rgb_color darkColor; 1221 1222 if (flags & B_DISABLED) { 1223 lightColor = tint_color(base, 0.9); 1224 darkColor = tint_color(base, 1.07); 1225 } else { 1226 lightColor = tint_color(base, 0.8); 1227 darkColor = tint_color(base, 1.14); 1228 } 1229 1230 int32 hashMarkCount = max_c(count, 2); 1231 // draw at least two hashmarks at min/max if 1232 // fHashMarks != B_HASH_MARKS_NONE 1233 float factor; 1234 float startPos; 1235 if (orientation == B_HORIZONTAL) { 1236 factor = (rect.Width() - 2) / (hashMarkCount - 1); 1237 startPos = rect.left + 1; 1238 } else { 1239 factor = (rect.Height() - 2) / (hashMarkCount - 1); 1240 startPos = rect.top + 1; 1241 } 1242 1243 if (location & B_HASH_MARKS_TOP) { 1244 view->BeginLineArray(hashMarkCount * 2); 1245 1246 if (orientation == B_HORIZONTAL) { 1247 float pos = startPos; 1248 for (int32 i = 0; i < hashMarkCount; i++) { 1249 view->AddLine(BPoint(pos, rect.top), 1250 BPoint(pos, rect.top + 4), darkColor); 1251 view->AddLine(BPoint(pos + 1, rect.top), 1252 BPoint(pos + 1, rect.top + 4), lightColor); 1253 1254 pos += factor; 1255 } 1256 } else { 1257 float pos = startPos; 1258 for (int32 i = 0; i < hashMarkCount; i++) { 1259 view->AddLine(BPoint(rect.left, pos), 1260 BPoint(rect.left + 4, pos), darkColor); 1261 view->AddLine(BPoint(rect.left, pos + 1), 1262 BPoint(rect.left + 4, pos + 1), lightColor); 1263 1264 pos += factor; 1265 } 1266 } 1267 1268 view->EndLineArray(); 1269 } 1270 1271 if (location & B_HASH_MARKS_BOTTOM) { 1272 1273 view->BeginLineArray(hashMarkCount * 2); 1274 1275 if (orientation == B_HORIZONTAL) { 1276 float pos = startPos; 1277 for (int32 i = 0; i < hashMarkCount; i++) { 1278 view->AddLine(BPoint(pos, rect.bottom - 4), 1279 BPoint(pos, rect.bottom), darkColor); 1280 view->AddLine(BPoint(pos + 1, rect.bottom - 4), 1281 BPoint(pos + 1, rect.bottom), lightColor); 1282 1283 pos += factor; 1284 } 1285 } else { 1286 float pos = startPos; 1287 for (int32 i = 0; i < hashMarkCount; i++) { 1288 view->AddLine(BPoint(rect.right - 4, pos), 1289 BPoint(rect.right, pos), darkColor); 1290 view->AddLine(BPoint(rect.right - 4, pos + 1), 1291 BPoint(rect.right, pos + 1), lightColor); 1292 1293 pos += factor; 1294 } 1295 } 1296 1297 view->EndLineArray(); 1298 } 1299 } 1300 1301 1302 void 1303 BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, 1304 const rgb_color& base, uint32 flags, uint32 borders) 1305 { 1306 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1307 return; 1308 1309 rgb_color edgeShadowColor; 1310 rgb_color edgeLightColor; 1311 rgb_color frameShadowColor; 1312 rgb_color frameLightColor; 1313 rgb_color bevelShadowColor; 1314 rgb_color bevelLightColor; 1315 BGradientLinear fillGradient; 1316 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1317 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1318 1319 if (flags & B_DISABLED) { 1320 edgeShadowColor = base; 1321 edgeLightColor = base; 1322 frameShadowColor = tint_color(base, 1.30); 1323 frameLightColor = tint_color(base, 1.25); 1324 bevelShadowColor = tint_color(base, 1.07); 1325 bevelLightColor = tint_color(base, 0.8); 1326 fillGradient.AddColor(tint_color(base, 0.85), 0); 1327 fillGradient.AddColor(base, 255); 1328 } else { 1329 edgeShadowColor = tint_color(base, 1.03); 1330 edgeLightColor = tint_color(base, 0.80); 1331 frameShadowColor = tint_color(base, 1.30); 1332 frameLightColor = tint_color(base, 1.30); 1333 bevelShadowColor = tint_color(base, 1.07); 1334 bevelLightColor = tint_color(base, 0.6); 1335 fillGradient.AddColor(tint_color(base, 0.75), 0); 1336 fillGradient.AddColor(tint_color(base, 1.03), 255); 1337 } 1338 1339 static const float kRoundCornerRadius = 4; 1340 1341 // left/top corner 1342 BRect cornerRect(rect); 1343 cornerRect.right = cornerRect.left + kRoundCornerRadius; 1344 cornerRect.bottom = cornerRect.top + kRoundCornerRadius; 1345 1346 BRegion clipping(rect); 1347 clipping.Exclude(cornerRect); 1348 1349 _DrawRoundCornerLeftTop(view, cornerRect, updateRect, base, edgeShadowColor, 1350 frameLightColor, bevelLightColor, fillGradient); 1351 1352 // left/top corner 1353 cornerRect.right = rect.right; 1354 cornerRect.left = cornerRect.right - kRoundCornerRadius; 1355 1356 clipping.Exclude(cornerRect); 1357 1358 _DrawRoundCornerRightTop(view, cornerRect, updateRect, base, edgeShadowColor, 1359 edgeLightColor, frameLightColor, frameShadowColor, bevelLightColor, 1360 bevelShadowColor, fillGradient); 1361 1362 // rest of frame and fill 1363 view->ConstrainClippingRegion(&clipping); 1364 1365 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1366 edgeLightColor, 1367 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1368 if ((borders & B_LEFT_BORDER) == 0) 1369 rect.left++; 1370 if ((borders & B_RIGHT_BORDER) == 0) 1371 rect.right--; 1372 1373 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1374 frameShadowColor, B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); 1375 1376 _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, 1377 bevelShadowColor); 1378 1379 view->FillRect(rect, fillGradient); 1380 1381 view->ConstrainClippingRegion(NULL); 1382 } 1383 1384 1385 void 1386 BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, 1387 const rgb_color& base, uint32 flags, uint32 borders) 1388 { 1389 if (!rect.IsValid() || !rect.Intersects(updateRect)) 1390 return; 1391 1392 rgb_color edgeShadowColor; 1393 rgb_color edgeLightColor; 1394 rgb_color frameShadowColor; 1395 rgb_color frameLightColor; 1396 rgb_color bevelShadowColor; 1397 rgb_color bevelLightColor; 1398 BGradientLinear fillGradient; 1399 fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); 1400 fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); 1401 1402 if (flags & B_DISABLED) { 1403 edgeShadowColor = base; 1404 edgeLightColor = base; 1405 frameShadowColor = tint_color(base, 1.30); 1406 frameLightColor = tint_color(base, 1.25); 1407 bevelShadowColor = tint_color(base, 1.07); 1408 bevelLightColor = tint_color(base, 0.8); 1409 fillGradient.AddColor(tint_color(base, 0.85), 0); 1410 fillGradient.AddColor(base, 255); 1411 } else { 1412 edgeShadowColor = tint_color(base, 1.03); 1413 edgeLightColor = tint_color(base, 0.80); 1414 frameShadowColor = tint_color(base, 1.30); 1415 frameLightColor = tint_color(base, 1.30); 1416 bevelShadowColor = tint_color(base, 1.17); 1417 bevelLightColor = tint_color(base, 1.10); 1418 fillGradient.AddColor(tint_color(base, 1.12), 0); 1419 fillGradient.AddColor(tint_color(base, 1.08), 255); 1420 } 1421 1422 // active tabs stand out at the top, but this is an inactive tab 1423 view->SetHighColor(base); 1424 view->FillRect(BRect(rect.left, rect.top, rect.right, rect.top + 4)); 1425 rect.top += 4; 1426 1427 // frame and fill 1428 _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, 1429 edgeLightColor, 1430 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1431 1432 _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, 1433 frameShadowColor, 1434 borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); 1435 1436 _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, bevelLightColor, 1437 bevelLightColor, B_LEFT_BORDER & ~borders); 1438 1439 view->FillRect(rect, fillGradient); 1440 } 1441 1442 1443 // #pragma mark - 1444 1445 1446 void 1447 BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, 1448 const rgb_color& base, border_style border, uint32 flags, uint32 borders) 1449 { 1450 if (border == B_NO_BORDER) 1451 return; 1452 1453 rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); 1454 if (flags & B_FOCUSED) 1455 scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1456 1457 if (border == B_FANCY_BORDER) 1458 _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); 1459 1460 _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, 1461 scrollbarFrameColor, scrollbarFrameColor, borders); 1462 } 1463 1464 1465 void 1466 BControlLook::DrawRaisedBorder(BView* view, BRect& rect, 1467 const BRect& updateRect, const rgb_color& base, uint32 flags, 1468 uint32 borders) 1469 { 1470 rgb_color lightColor; 1471 rgb_color shadowColor; 1472 1473 if (flags & B_DISABLED) { 1474 lightColor = base; 1475 shadowColor = base; 1476 } else { 1477 lightColor = tint_color(base, 0.85); 1478 shadowColor = tint_color(base, 1.07); 1479 } 1480 1481 _DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor, 1482 borders); 1483 } 1484 1485 1486 void 1487 BControlLook::DrawTextControlBorder(BView* view, BRect& rect, 1488 const BRect& updateRect, const rgb_color& base, uint32 flags, 1489 uint32 borders) 1490 { 1491 if (!rect.Intersects(updateRect)) 1492 return; 1493 1494 rgb_color dark1BorderColor; 1495 rgb_color dark2BorderColor; 1496 rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1497 1498 if (flags & B_DISABLED) { 1499 _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders); 1500 1501 if (flags & B_BLEND_FRAME) 1502 dark1BorderColor = (rgb_color){ 0, 0, 0, 40 }; 1503 else 1504 dark1BorderColor = tint_color(base, 1.15); 1505 dark2BorderColor = dark1BorderColor; 1506 } else if (flags & B_CLICKED) { 1507 dark1BorderColor = tint_color(base, 1.50); 1508 dark2BorderColor = tint_color(base, 1.49); 1509 1510 // BCheckBox uses this to indicate the clicked state... 1511 _DrawFrame(view, rect, 1512 dark1BorderColor, dark1BorderColor, 1513 dark2BorderColor, dark2BorderColor); 1514 1515 dark2BorderColor = dark1BorderColor; 1516 } else { 1517 _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders); 1518 1519 if (flags & B_BLEND_FRAME) { 1520 dark1BorderColor = (rgb_color){ 0, 0, 0, 102 }; 1521 dark2BorderColor = (rgb_color){ 0, 0, 0, 97 }; 1522 } else { 1523 dark1BorderColor = tint_color(base, 1.40); 1524 dark2BorderColor = tint_color(base, 1.38); 1525 } 1526 } 1527 1528 if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED)) { 1529 dark1BorderColor = navigationColor; 1530 dark2BorderColor = navigationColor; 1531 } 1532 1533 if (flags & B_BLEND_FRAME) { 1534 drawing_mode oldMode = view->DrawingMode(); 1535 view->SetDrawingMode(B_OP_ALPHA); 1536 1537 _DrawFrame(view, rect, 1538 dark1BorderColor, dark1BorderColor, 1539 dark2BorderColor, dark2BorderColor, borders); 1540 1541 view->SetDrawingMode(oldMode); 1542 } else { 1543 _DrawFrame(view, rect, 1544 dark1BorderColor, dark1BorderColor, 1545 dark2BorderColor, dark2BorderColor, borders); 1546 } 1547 } 1548 1549 1550 void 1551 BControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, 1552 const rgb_color& base, uint32 borders) 1553 { 1554 rgb_color frameColor = tint_color(base, 1.30); 1555 rgb_color bevelLight = tint_color(base, 0.8); 1556 rgb_color bevelShadow = tint_color(base, 1.03); 1557 1558 _DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight, 1559 borders); 1560 1561 _DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor, 1562 borders); 1563 1564 _DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow, 1565 borders); 1566 } 1567 1568 1569 void 1570 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1571 const BRect& updateRect, const rgb_color& base, uint32 flags) 1572 { 1573 DrawLabel(view, label, rect, updateRect, base, flags, 1574 DefaultLabelAlignment()); 1575 } 1576 1577 1578 void 1579 BControlLook::DrawLabel(BView* view, const char* label, BRect rect, 1580 const BRect& updateRect, const rgb_color& base, uint32 flags, 1581 const BAlignment& alignment) 1582 { 1583 if (!rect.Intersects(updateRect)) 1584 return; 1585 1586 // setup the text color 1587 rgb_color color; 1588 if (base.red + base.green + base.blue > 128 * 3) 1589 color = tint_color(base, B_DARKEN_MAX_TINT); 1590 else 1591 color = tint_color(base, B_LIGHTEN_MAX_TINT); 1592 1593 if (flags & B_DISABLED) { 1594 color.red = (uint8)(((int32)base.red + color.red + 1) / 2); 1595 color.green = (uint8)(((int32)base.green + color.green + 1) / 2); 1596 color.blue = (uint8)(((int32)base.blue + color.blue + 1) / 2); 1597 } 1598 1599 view->SetHighColor(color); 1600 view->SetDrawingMode(B_OP_OVER); 1601 1602 // truncate the label if necessary and get the width and height 1603 BString truncatedLabel(label); 1604 1605 BFont font; 1606 view->GetFont(&font); 1607 1608 float width = rect.Width(); 1609 font.TruncateString(&truncatedLabel, B_TRUNCATE_END, width); 1610 width = font.StringWidth(truncatedLabel.String()); 1611 1612 font_height fontHeight; 1613 font.GetHeight(&fontHeight); 1614 float height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); 1615 1616 // handle alignment 1617 BPoint location; 1618 1619 switch (alignment.horizontal) { 1620 default: 1621 case B_ALIGN_LEFT: 1622 location.x = rect.left; 1623 break; 1624 case B_ALIGN_RIGHT: 1625 location.x = rect.right - width; 1626 break; 1627 case B_ALIGN_CENTER: 1628 location.x = (rect.left + rect.right - width) / 2.0f; 1629 break; 1630 } 1631 1632 switch (alignment.vertical) { 1633 case B_ALIGN_TOP: 1634 location.y = rect.top + ceilf(fontHeight.ascent); 1635 break; 1636 default: 1637 case B_ALIGN_MIDDLE: 1638 location.y = floorf((rect.top + rect.bottom - height) / 2.0f + 0.5f) 1639 + ceilf(fontHeight.ascent); 1640 break; 1641 case B_ALIGN_BOTTOM: 1642 location.y = rect.bottom - ceilf(fontHeight.descent); 1643 break; 1644 } 1645 1646 view->DrawString(truncatedLabel.String(), location); 1647 } 1648 1649 1650 // #pragma mark - 1651 1652 1653 void 1654 BControlLook::_DrawButtonFrame(BView* view, BRect& rect, 1655 const BRect& updateRect, const rgb_color& base, const rgb_color& background, 1656 float contrast, float brightness, uint32 flags, uint32 borders) 1657 { 1658 // colors 1659 rgb_color dark1BorderColor; 1660 rgb_color dark2BorderColor; 1661 1662 if ((flags & B_DISABLED) == 0) { 1663 if (flags & B_BLEND_FRAME) { 1664 dark1BorderColor = (rgb_color){ 0, 0, 0, 75 }; 1665 dark2BorderColor = (rgb_color){ 0, 0, 0, 95 }; 1666 } else { 1667 dark1BorderColor = tint_color(base, 1.33); 1668 dark2BorderColor = tint_color(base, 1.45); 1669 } 1670 1671 if (flags & B_DEFAULT_BUTTON) { 1672 // TODO: B_BLEND_FRAME 1673 dark2BorderColor = tint_color(dark1BorderColor, 1.5); 1674 dark1BorderColor = tint_color(dark1BorderColor, 1.35); 1675 } 1676 } else { 1677 // TODO: B_BLEND_FRAME 1678 dark1BorderColor = tint_color(base, 1.147); 1679 dark2BorderColor = tint_color(base, 1.24); 1680 1681 if (flags & B_DEFAULT_BUTTON) { 1682 dark1BorderColor = tint_color(dark1BorderColor, 1.14); 1683 dark2BorderColor = tint_color(dark1BorderColor, 1.12); 1684 } 1685 } 1686 1687 if (flags & B_ACTIVATED) { 1688 rgb_color temp = dark2BorderColor; 1689 dark2BorderColor = dark1BorderColor; 1690 dark1BorderColor = temp; 1691 } 1692 1693 // indicate focus by changing main button border 1694 if (flags & B_FOCUSED) { 1695 dark1BorderColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 1696 dark2BorderColor = dark1BorderColor; 1697 } 1698 1699 if (flags & B_DEFAULT_BUTTON) { 1700 // TODO: B_BLEND_FRAME 1701 float focusTint = 1.2; 1702 if (flags & B_DISABLED) 1703 focusTint = (B_NO_TINT + focusTint) / 2; 1704 1705 rgb_color focusColor = tint_color(base, focusTint); 1706 view->SetHighColor(base); 1707 1708 view->StrokeRect(rect); 1709 rect.InsetBy(1.0, 1.0); 1710 1711 view->SetHighColor(focusColor); 1712 view->StrokeRect(rect); 1713 rect.InsetBy(1.0, 1.0); 1714 view->StrokeRect(rect); 1715 rect.InsetBy(1.0, 1.0); 1716 1717 // bevel around external border 1718 _DrawOuterResessedFrame(view, rect, focusColor, 1719 contrast * (((flags & B_DISABLED) ? 0.3 : 0.8)), 1720 brightness * (((flags & B_DISABLED) ? 1.0 : 0.9)), 1721 flags, borders); 1722 } else { 1723 // bevel around external border 1724 _DrawOuterResessedFrame(view, rect, background, 1725 contrast * ((flags & B_DISABLED) ? 0.0 : 1.0), brightness * 1.0, 1726 flags, borders); 1727 } 1728 1729 if (flags & B_BLEND_FRAME) { 1730 drawing_mode oldDrawingMode = view->DrawingMode(); 1731 view->SetDrawingMode(B_OP_ALPHA); 1732 1733 _DrawFrame(view, rect, dark1BorderColor, dark1BorderColor, 1734 dark2BorderColor, dark2BorderColor, borders); 1735 1736 view->SetDrawingMode(oldDrawingMode); 1737 } else { 1738 _DrawFrame(view, rect, dark1BorderColor, dark1BorderColor, 1739 dark2BorderColor, dark2BorderColor, borders); 1740 } 1741 } 1742 1743 1744 void 1745 BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, 1746 const rgb_color& base, float contrast, float brightness, uint32 flags, 1747 uint32 borders) 1748 { 1749 if (flags & B_BLEND_FRAME) { 1750 // assumes the background has already been painted 1751 drawing_mode oldDrawingMode = view->DrawingMode(); 1752 view->SetDrawingMode(B_OP_ALPHA); 1753 1754 uint8 alpha = uint8(20 * contrast); 1755 uint32 white = uint8(255 * brightness); 1756 1757 rgb_color borderBevelShadow = (rgb_color){ 0, 0, 0, alpha }; 1758 rgb_color borderBevelLight = (rgb_color){ white, white, white, alpha }; 1759 1760 _DrawFrame(view, rect, borderBevelShadow, borderBevelShadow, 1761 borderBevelLight, borderBevelLight, borders); 1762 1763 view->SetDrawingMode(oldDrawingMode); 1764 } else { 1765 // colors 1766 float tintLight = kEdgeBevelLightTint; 1767 float tintShadow = kEdgeBevelShadowTint; 1768 1769 if (contrast == 0.0) { 1770 tintLight = B_NO_TINT; 1771 tintShadow = B_NO_TINT; 1772 } else if (contrast != 1.0) { 1773 tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; 1774 tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; 1775 } 1776 1777 rgb_color borderBevelShadow = tint_color(base, tintShadow); 1778 rgb_color borderBevelLight = tint_color(base, tintLight); 1779 1780 if (brightness < 1.0) { 1781 borderBevelShadow.red = uint8(borderBevelShadow.red * brightness); 1782 borderBevelShadow.green = uint8(borderBevelShadow.green * brightness); 1783 borderBevelShadow.blue = uint8(borderBevelShadow.blue * brightness); 1784 borderBevelLight.red = uint8(borderBevelLight.red * brightness); 1785 borderBevelLight.green = uint8(borderBevelLight.green * brightness); 1786 borderBevelLight.blue = uint8(borderBevelLight.blue * brightness); 1787 } 1788 1789 _DrawFrame(view, rect, borderBevelShadow, borderBevelShadow, 1790 borderBevelLight, borderBevelLight, borders); 1791 } 1792 } 1793 1794 1795 void 1796 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 1797 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 1798 uint32 borders) 1799 { 1800 view->BeginLineArray(4); 1801 1802 if (borders & B_LEFT_BORDER) { 1803 view->AddLine( 1804 BPoint(rect.left, rect.bottom), 1805 BPoint(rect.left, rect.top), left); 1806 rect.left++; 1807 } 1808 if (borders & B_TOP_BORDER) { 1809 view->AddLine( 1810 BPoint(rect.left, rect.top), 1811 BPoint(rect.right, rect.top), top); 1812 rect.top++; 1813 } 1814 if (borders & B_RIGHT_BORDER) { 1815 view->AddLine( 1816 BPoint(rect.right, rect.top), 1817 BPoint(rect.right, rect.bottom), right); 1818 rect.right--; 1819 } 1820 if (borders & B_BOTTOM_BORDER) { 1821 view->AddLine( 1822 BPoint(rect.left, rect.bottom), 1823 BPoint(rect.right, rect.bottom), bottom); 1824 rect.bottom--; 1825 } 1826 1827 view->EndLineArray(); 1828 } 1829 1830 1831 void 1832 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 1833 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 1834 const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders) 1835 { 1836 view->BeginLineArray(6); 1837 1838 if (borders & B_TOP_BORDER) { 1839 if (borders & B_RIGHT_BORDER) { 1840 view->AddLine( 1841 BPoint(rect.left, rect.top), 1842 BPoint(rect.right - 1, rect.top), top); 1843 view->AddLine( 1844 BPoint(rect.right, rect.top), 1845 BPoint(rect.right, rect.top), rightTop); 1846 } else { 1847 view->AddLine( 1848 BPoint(rect.left, rect.top), 1849 BPoint(rect.right, rect.top), top); 1850 } 1851 rect.top++; 1852 } 1853 1854 if (borders & B_LEFT_BORDER) { 1855 view->AddLine( 1856 BPoint(rect.left, rect.top), 1857 BPoint(rect.left, rect.bottom - 1), left); 1858 view->AddLine( 1859 BPoint(rect.left, rect.bottom), 1860 BPoint(rect.left, rect.bottom), leftBottom); 1861 rect.left++; 1862 } 1863 1864 if (borders & B_BOTTOM_BORDER) { 1865 view->AddLine( 1866 BPoint(rect.left, rect.bottom), 1867 BPoint(rect.right, rect.bottom), bottom); 1868 rect.bottom--; 1869 } 1870 1871 if (borders & B_RIGHT_BORDER) { 1872 view->AddLine( 1873 BPoint(rect.right, rect.bottom), 1874 BPoint(rect.right, rect.top), right); 1875 rect.right--; 1876 } 1877 1878 view->EndLineArray(); 1879 } 1880 1881 1882 //void 1883 //BControlLook::_DrawShadowFrame(BView* view, BRect& rect, const rgb_color& base, 1884 // uint32 borders) 1885 //{ 1886 // view->BeginLineArray(4); 1887 // 1888 // bevelColor1 = tint_color(base, 1.2); 1889 // bevelColor2 = tint_color(base, 1.1); 1890 // 1891 // // shadow along left/top borders 1892 // if (rect.Height() > 0 && borders & B_LEFT_BORDER) { 1893 // view->AddLine(BPoint(rect.left, rect.top), 1894 // BPoint(rect.left, rect.bottom), bevelColor1); 1895 // rect.left++; 1896 // } 1897 // if (rect.Width() > 0 && borders & B_TOP_BORDER) { 1898 // view->AddLine(BPoint(rect.left, rect.top), 1899 // BPoint(rect.right, rect.top), bevelColor1); 1900 // rect.top++; 1901 // } 1902 // 1903 // // softer shadow along left/top borders 1904 // if (rect.Height() > 0 && borders & B_LEFT_BORDER) { 1905 // view->AddLine(BPoint(rect.left, rect.top), 1906 // BPoint(rect.left, rect.bottom), bevelColor2); 1907 // rect.left++; 1908 // } 1909 // if (rect.Width() > 0 && borders & B_TOP_BORDER) { 1910 // view->AddLine(BPoint(rect.left, rect.top), 1911 // BPoint(rect.right, rect.top), bevelColor2); 1912 // rect.top++; 1913 // } 1914 // 1915 // view->EndLineArray(); 1916 //} 1917 1918 1919 void 1920 BControlLook::_FillGradient(BView* view, const BRect& rect, 1921 const rgb_color& base, float topTint, float bottomTint, 1922 enum orientation orientation) 1923 { 1924 BGradientLinear gradient; 1925 _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); 1926 view->FillRect(rect, gradient); 1927 } 1928 1929 1930 void 1931 BControlLook::_FillGlossyGradient(BView* view, const BRect& rect, 1932 const rgb_color& base, float topTint, float middle1Tint, 1933 float middle2Tint, float bottomTint, enum orientation orientation) 1934 { 1935 BGradientLinear gradient; 1936 _MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint, 1937 middle2Tint, bottomTint, orientation); 1938 view->FillRect(rect, gradient); 1939 } 1940 1941 1942 void 1943 BControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect, 1944 const rgb_color& base, float topTint, float bottomTint, 1945 enum orientation orientation) const 1946 { 1947 gradient.AddColor(tint_color(base, topTint), 0); 1948 gradient.AddColor(tint_color(base, bottomTint), 255); 1949 gradient.SetStart(rect.LeftTop()); 1950 if (orientation == B_HORIZONTAL) 1951 gradient.SetEnd(rect.LeftBottom()); 1952 else 1953 gradient.SetEnd(rect.RightTop()); 1954 } 1955 1956 1957 void 1958 BControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect, 1959 const rgb_color& base, float topTint, float middle1Tint, 1960 float middle2Tint, float bottomTint, 1961 enum orientation orientation) const 1962 { 1963 gradient.AddColor(tint_color(base, topTint), 0); 1964 gradient.AddColor(tint_color(base, middle1Tint), 132); 1965 gradient.AddColor(tint_color(base, middle2Tint), 136); 1966 gradient.AddColor(tint_color(base, bottomTint), 255); 1967 gradient.SetStart(rect.LeftTop()); 1968 if (orientation == B_HORIZONTAL) 1969 gradient.SetEnd(rect.LeftBottom()); 1970 else 1971 gradient.SetEnd(rect.RightTop()); 1972 } 1973 1974 1975 bool 1976 BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, 1977 rgb_color& color, uint32 flags) const 1978 { 1979 if ((flags & (B_ACTIVATED | B_CLICKED)) == 0) { 1980 // no mark to be drawn at all 1981 return false; 1982 } 1983 1984 // TODO: Get from UI settings 1985 color.red = 27; 1986 color.green = 82; 1987 color.blue = 140; 1988 1989 float mix = 1.0; 1990 1991 if (flags & B_DISABLED) { 1992 // activated, but disabled 1993 mix = 0.4; 1994 } else if (flags & B_CLICKED) { 1995 if (flags & B_ACTIVATED) { 1996 // loosing activation 1997 mix = 0.7; 1998 } else { 1999 // becoming activated 2000 mix = 0.3; 2001 } 2002 } else { 2003 // simply activated 2004 } 2005 2006 color.red = uint8(color.red * mix + base.red * (1.0 - mix)); 2007 color.green = uint8(color.green * mix + base.green * (1.0 - mix)); 2008 color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix)); 2009 2010 return true; 2011 } 2012 2013 2014 void 2015 BControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, 2016 const BRect& updateRect, 2017 const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor, 2018 const rgb_color& frameLightColor, const rgb_color& frameShadowColor, 2019 const rgb_color& fillLightColor, const rgb_color& fillShadowColor, 2020 float leftInset, float topInset, float rightInset, float bottomInset, 2021 enum orientation orientation) 2022 { 2023 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2024 return; 2025 2026 BGradientLinear gradient; 2027 gradient.AddColor(edgeShadowColor, 0); 2028 gradient.AddColor(edgeLightColor, 255); 2029 gradient.SetStart(rect.LeftTop()); 2030 if (orientation == B_HORIZONTAL) 2031 gradient.SetEnd(rect.LeftBottom()); 2032 else 2033 gradient.SetEnd(rect.RightTop()); 2034 2035 view->FillEllipse(rect, gradient); 2036 2037 rect.left += leftInset; 2038 rect.top += topInset; 2039 rect.right += rightInset; 2040 rect.bottom += bottomInset; 2041 2042 gradient.MakeEmpty(); 2043 gradient.AddColor(frameShadowColor, 0); 2044 gradient.AddColor(frameLightColor, 255); 2045 gradient.SetStart(rect.LeftTop()); 2046 if (orientation == B_HORIZONTAL) 2047 gradient.SetEnd(rect.LeftBottom()); 2048 else 2049 gradient.SetEnd(rect.RightTop()); 2050 2051 view->FillEllipse(rect, gradient); 2052 2053 rect.left += leftInset; 2054 rect.top += topInset; 2055 rect.right += rightInset; 2056 rect.bottom += bottomInset; 2057 2058 gradient.MakeEmpty(); 2059 gradient.AddColor(fillShadowColor, 0); 2060 gradient.AddColor(fillLightColor, 255); 2061 gradient.SetStart(rect.LeftTop()); 2062 if (orientation == B_HORIZONTAL) 2063 gradient.SetEnd(rect.LeftBottom()); 2064 else 2065 gradient.SetEnd(rect.RightTop()); 2066 2067 view->FillEllipse(rect, gradient); 2068 } 2069 2070 2071 void 2072 BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& rect, 2073 const BRect& updateRect, const rgb_color& base, const rgb_color& edgeColor, 2074 const rgb_color& frameColor, const rgb_color& bevelColor, 2075 const BGradientLinear& fillGradient) 2076 { 2077 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2078 return; 2079 2080 BRegion clipping(rect); 2081 view->ConstrainClippingRegion(&clipping); 2082 2083 // background 2084 view->SetHighColor(base); 2085 view->FillRect(rect); 2086 2087 // outer edge 2088 BRect ellipseRect(rect); 2089 ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; 2090 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2091 2092 view->SetHighColor(edgeColor); 2093 view->FillEllipse(ellipseRect); 2094 2095 // frame 2096 ellipseRect.InsetBy(1, 1); 2097 view->SetHighColor(frameColor); 2098 view->FillEllipse(ellipseRect); 2099 2100 // bevel 2101 ellipseRect.InsetBy(1, 1); 2102 view->SetHighColor(bevelColor); 2103 view->FillEllipse(ellipseRect); 2104 2105 // fill 2106 ellipseRect.InsetBy(1, 1); 2107 view->FillEllipse(ellipseRect, fillGradient); 2108 2109 view->ConstrainClippingRegion(NULL); 2110 } 2111 2112 void 2113 BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& rect, 2114 const BRect& updateRect, const rgb_color& base, 2115 const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, 2116 const rgb_color& frameTopColor, const rgb_color& frameRightColor, 2117 const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, 2118 const BGradientLinear& fillGradient) 2119 { 2120 if (!rect.IsValid() || !rect.Intersects(updateRect)) 2121 return; 2122 2123 BRegion clipping(rect); 2124 view->ConstrainClippingRegion(&clipping); 2125 2126 // background 2127 view->SetHighColor(base); 2128 view->FillRect(rect); 2129 2130 // outer edge 2131 BRect ellipseRect(rect); 2132 ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; 2133 ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; 2134 2135 BGradientLinear gradient; 2136 gradient.AddColor(edgeTopColor, 0); 2137 gradient.AddColor(edgeRightColor, 255); 2138 gradient.SetStart(rect.LeftTop()); 2139 gradient.SetEnd(rect.RightBottom()); 2140 view->FillEllipse(ellipseRect, gradient); 2141 2142 // frame 2143 ellipseRect.InsetBy(1, 1); 2144 rect.right--; 2145 rect.top++; 2146 if (frameTopColor == frameRightColor) { 2147 view->SetHighColor(frameTopColor); 2148 view->FillEllipse(ellipseRect); 2149 } else { 2150 gradient.SetColor(0, frameTopColor); 2151 gradient.SetColor(1, frameRightColor); 2152 gradient.SetStart(rect.LeftTop()); 2153 gradient.SetEnd(rect.RightBottom()); 2154 view->FillEllipse(ellipseRect, gradient); 2155 } 2156 2157 // bevel 2158 ellipseRect.InsetBy(1, 1); 2159 rect.right--; 2160 rect.top++; 2161 gradient.SetColor(0, bevelTopColor); 2162 gradient.SetColor(1, bevelRightColor); 2163 gradient.SetStart(rect.LeftTop()); 2164 gradient.SetEnd(rect.RightBottom()); 2165 view->FillEllipse(ellipseRect, gradient); 2166 2167 // fill 2168 ellipseRect.InsetBy(1, 1); 2169 view->FillEllipse(ellipseRect, fillGradient); 2170 2171 view->ConstrainClippingRegion(NULL); 2172 } 2173 2174 2175 // NOTE: May come from a add-on in the future. Initialized in 2176 // InterfaceDefs.cpp 2177 BControlLook* be_control_look = NULL; 2178 2179 } // namespace BPrivate 2180