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