1 /* 2 * Copyright 2003-2023 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus, superstippi@gmx.de 7 * DarkWyrm, bpmagic@columbus.rr.com 8 * Marc Flerackers, mflerackers@androme.be 9 * François Revol, revol@free.fr 10 * John Scipione, jscipione@gmail.com 11 * Clemens Zeidler, haiku@clemens-zeidler.de 12 */ 13 14 15 /*! BControlLook resembling BeOS R5 */ 16 17 18 #include "BeControlLook.h" 19 20 #include <algorithm> 21 22 #include <Alignment.h> 23 #include <Bitmap.h> 24 #include <Button.h> 25 #include <Control.h> 26 #include <LayoutUtils.h> 27 #include <Region.h> 28 #include <Shape.h> 29 #include <String.h> 30 #include <TabView.h> 31 #include <View.h> 32 #include <Window.h> 33 #include <WindowPrivate.h> 34 35 //#define DEBUG_CONTROL_LOOK 36 #ifdef DEBUG_CONTROL_LOOK 37 # define STRACE(x) printf x 38 #else 39 # define STRACE(x) ; 40 #endif 41 42 43 namespace BPrivate { 44 45 static const float kButtonPopUpIndicatorWidth = 11; 46 47 48 BeControlLook::BeControlLook(image_id id) 49 : 50 fCachedOutline(false) 51 { 52 } 53 54 55 BeControlLook::~BeControlLook() 56 { 57 } 58 59 60 BAlignment 61 BeControlLook::DefaultLabelAlignment() const 62 { 63 return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER); 64 } 65 66 67 float 68 BeControlLook::DefaultLabelSpacing() const 69 { 70 return ceilf(be_plain_font->Size() / 2.0); 71 } 72 73 74 float 75 BeControlLook::DefaultItemSpacing() const 76 { 77 return ceilf(be_plain_font->Size() * 0.85); 78 } 79 80 81 uint32 82 BeControlLook::Flags(BControl* control) const 83 { 84 uint32 flags = B_IS_CONTROL; 85 86 if (!control->IsEnabled()) 87 flags |= B_DISABLED; 88 89 if (control->IsFocus() && control->Window() != NULL 90 && control->Window()->IsActive()) { 91 flags |= B_FOCUSED; 92 } 93 94 switch (control->Value()) { 95 case B_CONTROL_ON: 96 flags |= B_ACTIVATED; 97 break; 98 case B_CONTROL_PARTIALLY_ON: 99 flags |= B_PARTIALLY_ACTIVATED; 100 break; 101 } 102 103 if (control->Parent() != NULL 104 && (control->Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0) { 105 // In this constellation, assume we want to render the control 106 // against the already existing view contents of the parent view. 107 flags |= B_BLEND_FRAME; 108 } 109 110 return flags; 111 } 112 113 114 void 115 BeControlLook::DrawButtonFrame(BView* view, BRect& rect, 116 const BRect& updateRect, const rgb_color& base, 117 const rgb_color& background, uint32 flags, uint32 borders) 118 { 119 _DrawButtonFrame(view, rect, updateRect, 0, 0, 0, 0, base, 120 background, 1.0, 1.0, flags, borders); 121 } 122 123 124 void 125 BeControlLook::DrawButtonFrame(BView* view, BRect& rect, 126 const BRect& updateRect, float, const rgb_color& base, 127 const rgb_color& background, uint32 flags, uint32 borders) 128 { 129 _DrawButtonFrame(view, rect, updateRect, 0, 0, 0, 0, base, 130 background, 1.0, 1.0, flags, borders); 131 } 132 133 134 void 135 BeControlLook::DrawButtonFrame(BView* view, BRect& rect, 136 const BRect& updateRect, float, float, float, float, const rgb_color& base, 137 const rgb_color& background, uint32 flags, uint32 borders) 138 { 139 _DrawButtonFrame(view, rect, updateRect, 0, 0, 0, 0, base, 140 background, 1.0, 1.0, flags, borders); 141 } 142 143 144 void 145 BeControlLook::DrawButtonBackground(BView* view, BRect& rect, 146 const BRect& updateRect, const rgb_color& base, uint32 flags, 147 uint32 borders, orientation orientation) 148 { 149 _DrawButtonBackground(view, rect, updateRect, 0, 0, 0, 0, 150 base, false, flags, borders, orientation); 151 } 152 153 154 void 155 BeControlLook::DrawButtonBackground(BView* view, BRect& rect, 156 const BRect& updateRect, float, const rgb_color& base, uint32 flags, 157 uint32 borders, orientation orientation) 158 { 159 _DrawButtonBackground(view, rect, updateRect, 0, 0, 0, 0, 160 base, false, flags, borders, orientation); 161 } 162 163 164 void 165 BeControlLook::DrawButtonBackground(BView* view, BRect& rect, 166 const BRect& updateRect, float, float, float, float, const rgb_color& base, 167 uint32 flags, uint32 borders, orientation orientation) 168 { 169 _DrawButtonBackground(view, rect, updateRect, 0, 0, 0, 0, 170 base, false, flags, borders, orientation); 171 } 172 173 174 void 175 BeControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, 176 const rgb_color& base, uint32 flags) 177 { 178 if (!rect.Intersects(updateRect)) 179 return; 180 181 bool isEnabled = (flags & B_DISABLED) == 0; 182 bool isActivated = (flags & B_ACTIVATED) != 0; 183 bool isFocused = (flags & B_FOCUSED) != 0; 184 bool isClicked = (flags & B_CLICKED) != 0; 185 186 rgb_color lighten1 = tint_color(base, B_LIGHTEN_1_TINT); 187 rgb_color lightenMax = tint_color(base, B_LIGHTEN_MAX_TINT); 188 rgb_color darken1 = tint_color(base, B_DARKEN_1_TINT); 189 rgb_color darken2 = tint_color(base, B_DARKEN_2_TINT); 190 rgb_color darken3 = tint_color(base, B_DARKEN_3_TINT); 191 rgb_color darken4 = tint_color(base, B_DARKEN_4_TINT); 192 193 view->SetLowColor(base); 194 195 if (isEnabled) { 196 // Filling 197 view->SetHighColor(lightenMax); 198 view->FillRect(rect); 199 200 // Box 201 if (isClicked) { 202 view->SetHighColor(darken3); 203 view->StrokeRect(rect); 204 205 rect.InsetBy(1, 1); 206 207 view->BeginLineArray(6); 208 209 view->AddLine(BPoint(rect.left, rect.bottom), 210 BPoint(rect.left, rect.top), darken2); 211 view->AddLine(BPoint(rect.left, rect.top), 212 BPoint(rect.right, rect.top), darken2); 213 view->AddLine(BPoint(rect.left, rect.bottom), 214 BPoint(rect.right, rect.bottom), darken4); 215 view->AddLine(BPoint(rect.right, rect.bottom), 216 BPoint(rect.right, rect.top), darken4); 217 218 view->EndLineArray(); 219 } else { 220 view->BeginLineArray(6); 221 222 view->AddLine(BPoint(rect.left, rect.bottom), 223 BPoint(rect.left, rect.top), darken1); 224 view->AddLine(BPoint(rect.left, rect.top), 225 BPoint(rect.right, rect.top), darken1); 226 227 rect.InsetBy(1, 1); 228 view->AddLine(BPoint(rect.left, rect.bottom), 229 BPoint(rect.left, rect.top), darken4); 230 view->AddLine(BPoint(rect.left, rect.top), 231 BPoint(rect.right, rect.top), darken4); 232 view->AddLine(BPoint(rect.left + 1, rect.bottom), 233 BPoint(rect.right, rect.bottom), base); 234 view->AddLine(BPoint(rect.right, rect.bottom), 235 BPoint(rect.right, rect.top + 1), base); 236 237 view->EndLineArray(); 238 } 239 240 // Focus 241 if (isFocused) { 242 view->SetDrawingMode(B_OP_OVER); 243 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 244 view->StrokeRect(rect); 245 view->SetDrawingMode(B_OP_COPY); 246 } 247 } else { 248 // Filling 249 view->SetHighColor(lighten1); 250 view->FillRect(rect); 251 252 // Box 253 view->BeginLineArray(6); 254 255 view->AddLine(BPoint(rect.left, rect.bottom), 256 BPoint(rect.left, rect.top), base); 257 view->AddLine(BPoint(rect.left, rect.top), 258 BPoint(rect.right, rect.top), base); 259 260 rect.InsetBy(1, 1); 261 view->AddLine(BPoint(rect.left, rect.bottom), 262 BPoint(rect.left, rect.top), darken2); 263 view->AddLine(BPoint(rect.left, rect.top), 264 BPoint(rect.right, rect.top), darken2); 265 view->AddLine(BPoint(rect.left + 1, rect.bottom), 266 BPoint(rect.right, rect.bottom), darken1); 267 view->AddLine(BPoint(rect.right, rect.bottom), 268 BPoint(rect.right, rect.top + 1), darken1); 269 270 view->EndLineArray(); 271 } 272 273 // Checkmark 274 if (isActivated) { 275 rect.InsetBy(4, 4); 276 277 float penSize = std::max(1, 2); 278 if (penSize > 1 && fmodf(penSize, 2) == 0) { 279 // Tweak ends to "include" the pixel at the index, 280 // we need to do this in order to produce results like R5, 281 // where coordinates were inclusive 282 rect.right++; 283 rect.bottom++; 284 } 285 286 view->SetPenSize(penSize); 287 view->SetDrawingMode(B_OP_OVER); 288 if (isEnabled) 289 view->SetHighColor(ui_color(B_CONTROL_MARK_COLOR)); 290 else { 291 view->SetHighColor(tint_color(ui_color(B_CONTROL_MARK_COLOR), 292 B_DISABLED_MARK_TINT)); 293 } 294 view->StrokeLine(rect.LeftTop(), rect.RightBottom()); 295 view->StrokeLine(rect.LeftBottom(), rect.RightTop()); 296 } 297 } 298 299 300 void 301 BeControlLook::DrawRadioButton(BView* view, BRect& rect, 302 const BRect& updateRect, const rgb_color& base, uint32 flags) 303 { 304 if (!ShouldDraw(view, rect, updateRect)) 305 return; 306 307 bool isEnabled = (flags & B_DISABLED) == 0; 308 bool isActivated = (flags & B_ACTIVATED) != 0; 309 bool isFocused = (flags & B_FOCUSED) != 0; 310 311 // colors 312 rgb_color bg = ui_color(B_PANEL_BACKGROUND_COLOR); 313 rgb_color lightenmax; 314 rgb_color lighten1; 315 rgb_color darken1; 316 rgb_color darken2; 317 rgb_color darken3; 318 319 rgb_color markColor = ui_color(B_CONTROL_MARK_COLOR); 320 rgb_color knob; 321 rgb_color knobDark; 322 rgb_color knobLight; 323 324 if (isEnabled) { 325 lightenmax = tint_color(bg, B_LIGHTEN_MAX_TINT); 326 lighten1 = tint_color(bg, B_LIGHTEN_1_TINT); 327 darken1 = tint_color(bg, B_DARKEN_1_TINT); 328 darken2 = tint_color(bg, B_DARKEN_2_TINT); 329 darken3 = tint_color(bg, B_DARKEN_3_TINT); 330 331 knob = markColor; 332 knobDark = tint_color(markColor, B_DARKEN_3_TINT); 333 knobLight = tint_color(markColor, 0.15); 334 } else { 335 lightenmax = tint_color(bg, B_LIGHTEN_2_TINT); 336 lighten1 = bg; 337 darken1 = bg; 338 darken2 = tint_color(bg, B_DARKEN_1_TINT); 339 darken3 = tint_color(bg, B_DARKEN_2_TINT); 340 341 knob = tint_color(markColor, B_LIGHTEN_2_TINT); 342 knobDark = tint_color(markColor, B_LIGHTEN_1_TINT); 343 knobLight = tint_color(markColor, 344 (B_LIGHTEN_2_TINT + B_LIGHTEN_MAX_TINT) / 2.0); 345 } 346 347 rect.InsetBy(2, 2); 348 349 view->SetLowColor(bg); 350 351 // dot 352 if (isActivated) { 353 // full 354 view->SetHighColor(knobDark); 355 view->FillEllipse(rect); 356 357 view->SetHighColor(knob); 358 view->FillEllipse(BRect(rect.left + 2, rect.top + 2, rect.right - 3, 359 rect.bottom - 3)); 360 361 view->SetHighColor(knobLight); 362 view->FillEllipse(BRect(rect.left + 3, rect.top + 3, rect.right - 5, 363 rect.bottom - 5)); 364 } else { 365 // empty 366 view->SetHighColor(lightenmax); 367 view->FillEllipse(rect); 368 } 369 370 rect.InsetBy(-1, -1); 371 372 // outer circle 373 if (isFocused) { 374 // indicating "about to change value" 375 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 376 view->SetPenSize(2); 377 view->SetDrawingMode(B_OP_OVER); 378 view->StrokeEllipse(rect.InsetByCopy(1, 1)); 379 view->SetDrawingMode(B_OP_COPY); 380 view->SetPenSize(1); 381 } else { 382 view->SetHighColor(darken1); 383 view->StrokeArc(rect, 45.0, 180.0); 384 view->SetHighColor(lightenmax); 385 view->StrokeArc(rect, 45.0, -180.0); 386 } 387 388 // inner circle 389 view->SetHighColor(darken3); 390 view->StrokeArc(rect, 45.0, 180.0); 391 view->SetHighColor(bg); 392 view->StrokeArc(rect, 45.0, -180.0); 393 394 // for faster font rendering, we restore B_OP_COPY 395 view->SetDrawingMode(B_OP_COPY); 396 } 397 398 399 void 400 BeControlLook::DrawScrollBarBorder(BView* view, BRect rect, 401 const BRect& updateRect, const rgb_color& base, uint32 flags, 402 orientation orientation) 403 { 404 if (!ShouldDraw(view, rect, updateRect)) 405 return; 406 407 view->PushState(); 408 409 view->ClipToRect(rect); 410 411 bool isEnabled = (flags & B_DISABLED) == 0; 412 bool isFocused = (flags & B_FOCUSED) != 0; 413 414 if (isEnabled && isFocused) 415 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 416 else 417 view->SetHighColor(tint_color(base, B_DARKEN_2_TINT)); 418 419 view->StrokeRect(rect); 420 421 view->PopState(); 422 } 423 424 425 void 426 BeControlLook::DrawScrollBarButton(BView* view, BRect rect, 427 const BRect& updateRect, const rgb_color& base, uint32 flags, 428 int32 direction, orientation orientation, bool down) 429 { 430 view->PushState(); 431 432 bool isEnabled = (flags & B_DISABLED) == 0; 433 434 // border = 152, shine = 144/255, shadow = 208/184/192 435 rgb_color shine = down ? tint_color(base, 1.333) 436 : tint_color(base, B_LIGHTEN_MAX_TINT); 437 rgb_color shadow; 438 if (isEnabled && down) 439 shadow = tint_color(base, 1.037); 440 else if (isEnabled) 441 shadow = tint_color(base, B_DARKEN_1_TINT); 442 else 443 shadow = tint_color(base, 1.111); 444 445 view->BeginLineArray(4); 446 view->AddLine(rect.LeftTop(), rect.LeftBottom() - BPoint(0, 1), shine); 447 view->AddLine(rect.LeftTop(), rect.RightTop() - BPoint(1, 0), shine); 448 view->AddLine(rect.RightTop(), rect.RightBottom() - BPoint(0, 1), shadow); 449 view->AddLine(rect.LeftBottom(), rect.RightBottom(), shadow); 450 view->EndLineArray(); 451 452 rgb_color bg; 453 if (isEnabled) { 454 // bg = 176/216 455 bg = down ? tint_color(base, 1.185) : base; 456 } else { 457 // bg = 240 458 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 459 lighten2.red++; lighten2.green++; lighten2.blue++; 460 // lighten2 = 239, 240 = 239 + 1 461 bg = lighten2; 462 } 463 view->SetHighColor(bg); 464 rect.InsetBy(1, 1); 465 view->FillRect(rect); 466 467 // draw button triangle 468 // don't use DrawArrowShape because we use that to draw arrows differently 469 // in menus and outline list view 470 471 rect.InsetBy(1, 1); 472 rect.OffsetBy(-3, -3); 473 474 BPoint tri1, tri2, tri3; 475 BPoint off1, off2, off3; 476 BRect r(rect.left, rect.top, rect.left + 14, rect.top + 14); 477 rgb_color lightenmax = tint_color(base, B_LIGHTEN_MAX_TINT); 478 rgb_color light, dark, arrow, arrow2; 479 480 switch(direction) { 481 case B_LEFT_ARROW: 482 tri1.Set(r.left + 3, floorf((r.top + r.bottom) / 2)); 483 tri2.Set(r.right - 4, r.top + 4); 484 tri3.Set(r.right - 4, r.bottom - 4); 485 break; 486 487 default: 488 case B_RIGHT_ARROW: 489 tri1.Set(r.left + 4, r.bottom - 4); 490 tri2.Set(r.left + 4, r.top + 4); 491 tri3.Set(r.right - 3, floorf((r.top + r.bottom) / 2)); 492 break; 493 494 case B_UP_ARROW: 495 tri1.Set(r.left + 4, r.bottom - 4); 496 tri2.Set(floorf((r.left + r.right) / 2), r.top + 3); 497 tri3.Set(r.right - 4, r.bottom - 4); 498 break; 499 500 case B_DOWN_ARROW: 501 tri1.Set(r.left + 4, r.top + 4); 502 tri2.Set(r.right - 4, r.top + 4); 503 tri3.Set(floorf((r.left + r.right) / 2), r.bottom - 3); 504 break; 505 } 506 507 r.InsetBy(1, 1); 508 509 float tint = B_NO_TINT; 510 if (!isEnabled) 511 tint = (tint + B_NO_TINT + B_NO_TINT) / 3; 512 513 view->SetHighColor(tint_color(base, tint)); 514 view->MovePenTo(B_ORIGIN); 515 view->SetDrawingMode(B_OP_OVER); 516 517 view->SetHighColor(tint_color(base, tint)); 518 519 if (isEnabled) { 520 arrow2 = light = tint_color(base, B_DARKEN_2_TINT); 521 dark = tint_color(base, B_DARKEN_3_TINT); 522 arrow = tint_color(base, B_DARKEN_MAX_TINT); 523 } else 524 arrow = arrow2 = light = dark = tint_color(base, B_DARKEN_1_TINT); 525 526 // white triangle offset by 1px 527 off1.Set(tri1.x + 1, tri1.y + 1); 528 off2.Set(tri2.x + 1, tri2.y + 1); 529 off3.Set(tri3.x + 1, tri3.y + 1); 530 531 // draw white triangle 532 view->BeginLineArray(3); 533 view->AddLine(off2, off3, lightenmax); 534 view->AddLine(off1, off3, lightenmax); 535 view->AddLine(off1, off2, lightenmax); 536 view->EndLineArray(); 537 538 // draw triangle on top 539 view->BeginLineArray(3); 540 view->AddLine(tri2, tri3, dark); 541 view->AddLine(tri1, tri3, dark); 542 view->AddLine(tri1, tri2, arrow2); 543 view->EndLineArray(); 544 545 view->PopState(); 546 } 547 548 549 void 550 BeControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, 551 const BRect& updateRect, const rgb_color& base, uint32 flags, 552 orientation orientation) 553 { 554 _DrawScrollBarBackgroundFirst(view, rect1, updateRect, base, flags, 555 orientation); 556 _DrawScrollBarBackgroundSecond(view, rect2, updateRect, base, flags, 557 orientation); 558 } 559 560 561 void 562 BeControlLook::DrawScrollBarBackground(BView* view, BRect& rect, 563 const BRect& updateRect, const rgb_color& base, uint32 flags, 564 orientation orientation) 565 { 566 _DrawScrollBarBackgroundFirst(view, rect, updateRect, base, flags, 567 orientation); 568 } 569 570 571 void 572 BeControlLook::DrawScrollBarThumb(BView* view, BRect& rect, 573 const BRect& updateRect, const rgb_color& base, uint32 flags, 574 orientation orientation, uint32 knobStyle) 575 { 576 if (!ShouldDraw(view, rect, updateRect)) 577 return; 578 579 view->PushState(); 580 581 view->ClipToRect(rect); 582 583 bool isEnabled = (flags & B_DISABLED) == 0; 584 585 BRect orig(rect); 586 587 // shine = 255 588 rgb_color shine = tint_color(base, B_LIGHTEN_MAX_TINT); 589 rgb_color bg; 590 if (isEnabled) { 591 // bg = 216 592 bg = base; 593 } else { 594 // bg = 240 595 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 596 lighten2.red++; lighten2.green++; lighten2.blue++; 597 // lighten2 = 239, 240 = 239 + 1 598 bg = lighten2; 599 } 600 601 // draw thumb over background 602 view->SetDrawingMode(B_OP_OVER); 603 604 view->BeginLineArray(2); 605 if (orientation == B_VERTICAL) { 606 // shine 607 view->AddLine(rect.LeftTop(), rect.LeftBottom(), shine); 608 rect.left++; 609 view->AddLine(rect.LeftTop(), rect.RightTop(), shine); 610 rect.top++; 611 } else { 612 // shine 613 view->AddLine(rect.LeftTop(), rect.LeftBottom(), shine); 614 rect.left++; 615 view->AddLine(rect.LeftTop(), rect.RightTop(), shine); 616 rect.top++; 617 } 618 view->EndLineArray(); 619 620 // fill bg 621 view->SetHighColor(bg); 622 view->FillRect(rect); 623 624 // undraw right top or left bottom point 625 view->BeginLineArray(1); 626 if (orientation == B_VERTICAL) { 627 rect.right--; 628 view->AddLine(rect.RightTop(), rect.RightTop(), base); 629 } else { 630 rect.bottom--; 631 view->AddLine(rect.LeftBottom(), rect.LeftBottom(), base); 632 } 633 view->EndLineArray(); 634 635 // restore rect 636 rect = orig; 637 638 // knobs 639 640 if (knobStyle != B_KNOB_NONE) { 641 float hcenter = rect.left + rect.Width() / 2; 642 float vmiddle = rect.top + rect.Height() / 2; 643 rgb_color knobDark = tint_color(base, B_DARKEN_1_TINT); 644 rgb_color knobLight = tint_color(base, B_LIGHTEN_MAX_TINT); 645 646 if (knobStyle == B_KNOB_DOTS) { 647 // center/middle dot 648 _DrawScrollBarKnobDot(view, hcenter, vmiddle, knobDark, knobLight, 649 orientation); 650 if (orientation == B_HORIZONTAL) { 651 float spacer = rect.Height(); 652 // left dot 653 if (rect.left + 7 < hcenter - spacer) { 654 _DrawScrollBarKnobDot(view, hcenter - 7, vmiddle, knobDark, 655 knobLight, orientation); 656 } 657 // right dot 658 if (rect.right - 7 > hcenter + spacer) { 659 _DrawScrollBarKnobDot(view, hcenter + 7, vmiddle, knobDark, 660 knobLight, orientation); 661 } 662 } else { 663 float spacer = rect.Width(); 664 // top dot 665 if (rect.top + 7 < vmiddle - spacer) { 666 _DrawScrollBarKnobDot(view, hcenter, vmiddle - 7, knobDark, 667 knobLight, orientation); 668 } 669 // bottom dot 670 if (rect.bottom - 7 > vmiddle + spacer) { 671 _DrawScrollBarKnobDot(view, hcenter, vmiddle + 7, knobDark, 672 knobLight, orientation); 673 } 674 } 675 } else if (knobStyle == B_KNOB_LINES) { 676 // center/middle line 677 _DrawScrollBarKnobLine(view, hcenter, vmiddle, knobDark, knobLight, 678 orientation); 679 if (orientation == B_HORIZONTAL) { 680 float spacer = rect.Height(); 681 // left line 682 if (rect.left + 4 < hcenter - spacer) { 683 _DrawScrollBarKnobLine(view, hcenter - 4, vmiddle, knobDark, 684 knobLight, orientation); 685 } 686 // right line 687 if (rect.right - 4 > hcenter + spacer) { 688 _DrawScrollBarKnobLine(view, hcenter + 4, vmiddle, knobDark, 689 knobLight, orientation); 690 } 691 } else { 692 float spacer = rect.Width(); 693 // top line 694 if (rect.top + 4 < vmiddle - spacer) { 695 _DrawScrollBarKnobLine(view, hcenter, vmiddle - 4, knobDark, 696 knobLight, orientation); 697 } 698 // bottom line 699 if (rect.bottom - 5 > vmiddle + spacer) { 700 _DrawScrollBarKnobLine(view, hcenter, vmiddle + 4, knobDark, 701 knobLight, orientation); 702 } 703 } 704 } 705 } 706 707 view->PopState(); 708 } 709 710 711 712 void 713 BeControlLook::DrawScrollViewFrame(BView* view, BRect& rect, 714 const BRect& updateRect, BRect verticalScrollBarFrame, 715 BRect horizontalScrollBarFrame, const rgb_color& base, 716 border_style borderStyle, uint32 flags, uint32 _borders) 717 { 718 rgb_color darken1 = tint_color(base, B_DARKEN_1_TINT); 719 rgb_color lightenmax = tint_color(base, B_LIGHTEN_MAX_TINT); 720 721 view->BeginLineArray(4); 722 view->AddLine(rect.LeftBottom(), rect.LeftTop(), darken1); 723 view->AddLine(rect.LeftTop(), rect.RightTop(), darken1); 724 view->AddLine(rect.RightTop(), rect.RightBottom(), lightenmax); 725 view->AddLine(rect.RightBottom(), rect.LeftBottom(), lightenmax); 726 view->EndLineArray(); 727 728 rect.InsetBy(1, 1); 729 730 bool isEnabled = (flags & B_DISABLED) == 0; 731 bool isFocused = (flags & B_FOCUSED) != 0; 732 733 if (isEnabled && isFocused) 734 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 735 else 736 view->SetHighColor(tint_color(base, B_DARKEN_2_TINT)); 737 738 view->StrokeRect(rect); 739 } 740 741 742 void 743 BeControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, 744 const rgb_color& base, uint32 direction, uint32 flags, float tint) 745 { 746 if (!ShouldDraw(view, rect, updateRect)) 747 return; 748 749 view->PushState(); 750 751 rgb_color fill = tint_color(base, 1.074); // 200 752 rgb_color stroke = tint_color(base, 1.629); // 80 753 754 switch(direction) { 755 case B_LEFT_ARROW: 756 view->SetHighColor(fill); 757 view->FillTriangle(rect.LeftTop() + BPoint(4, 6), 758 rect.LeftTop() + BPoint(8, 2), 759 rect.LeftTop() + BPoint(8, 10)); 760 view->SetHighColor(stroke); 761 view->StrokeTriangle(rect.LeftTop() + BPoint(4, 6), 762 rect.LeftTop() + BPoint(8, 2), 763 rect.LeftTop() + BPoint(8, 10)); 764 break; 765 766 default: 767 case B_RIGHT_ARROW: 768 view->SetHighColor(fill); 769 view->FillTriangle(rect.LeftTop() + BPoint(4, 2), 770 rect.LeftTop() + BPoint(4, 10), 771 rect.LeftTop() + BPoint(8, 6)); 772 view->SetHighColor(stroke); 773 view->StrokeTriangle(rect.LeftTop() + BPoint(4, 2), 774 rect.LeftTop() + BPoint(4, 10), 775 rect.LeftTop() + BPoint(8, 6)); 776 break; 777 778 case B_UP_ARROW: 779 view->SetHighColor(fill); 780 view->FillTriangle(rect.LeftTop() + BPoint(6, 4), 781 rect.LeftTop() + BPoint(2, 8), 782 rect.LeftTop() + BPoint(10, 8)); 783 view->SetHighColor(stroke); 784 view->StrokeTriangle(rect.LeftTop() + BPoint(6, 4), 785 rect.LeftTop() + BPoint(2, 8), 786 rect.LeftTop() + BPoint(10, 8)); 787 break; 788 789 case B_DOWN_ARROW: 790 view->SetHighColor(fill); 791 view->FillTriangle(rect.LeftTop() + BPoint(2, 4), 792 rect.LeftTop() + BPoint(10, 4), 793 rect.LeftTop() + BPoint(6, 8)); 794 view->SetHighColor(stroke); 795 view->StrokeTriangle(rect.LeftTop() + BPoint(2, 4), 796 rect.LeftTop() + BPoint(10, 4), 797 rect.LeftTop() + BPoint(6, 8)); 798 break; 799 } 800 801 view->PopState(); 802 } 803 804 805 void 806 BeControlLook::DrawMenuBarBackground(BView* view, BRect& rect, 807 const BRect& updateRect, const rgb_color& base, uint32 flags, 808 uint32 borders) 809 { 810 if (!ShouldDraw(view, rect, updateRect)) 811 return; 812 813 view->PushState(); 814 815 // restore the background color in case a menu item was selected 816 view->SetHighColor(base); 817 view->FillRect(rect); 818 819 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 820 rgb_color darken1 = tint_color(base, B_DARKEN_1_TINT); 821 822 view->BeginLineArray(3); 823 view->AddLine(rect.LeftTop(), rect.RightTop(), lighten2); 824 // left bottom pixel is base color 825 view->AddLine(rect.LeftTop(), rect.LeftBottom() - BPoint(0, 1), 826 lighten2); 827 view->AddLine(rect.LeftBottom() + BPoint(1, 0), rect.RightBottom(), 828 darken1); 829 view->EndLineArray(); 830 831 view->PopState(); 832 } 833 834 835 void 836 BeControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 837 const BRect& updateRect, const rgb_color& base, 838 const rgb_color& background, uint32 flags, uint32 borders) 839 { 840 // BeControlLook does not support rounded corners and it never will 841 DrawMenuFieldFrame(view, rect, updateRect, 0, base, background, flags, 842 borders); 843 } 844 845 846 void 847 BeControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 848 const BRect& updateRect, float, const rgb_color& base, 849 const rgb_color& background, uint32 flags, uint32 borders) 850 { 851 // BeControlLook does not support rounded corners and it never will 852 DrawMenuFieldFrame(view, rect, updateRect, 0, 0, 0, 0, base, 853 background, flags, borders); 854 } 855 856 857 void 858 BeControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, 859 const BRect& updateRect, float, float, float, float, const rgb_color& base, 860 const rgb_color& background, uint32 flags, uint32 borders) 861 { 862 if (!ShouldDraw(view, rect, updateRect)) 863 return; 864 865 bool isEnabled = (flags & B_DISABLED) == 0; 866 bool isFocused = (flags & B_FOCUSED) != 0; 867 868 // inset the frame by 2 and draw the outer border 869 rect.InsetBy(2, 2); 870 871 rgb_color darken2 = tint_color(base, B_DARKEN_2_TINT); 872 873 // draw left and top side and top right corner 874 view->BeginLineArray(3); 875 view->AddLine(BPoint(rect.left - 1, rect.top - 1), 876 BPoint(rect.left - 1, rect.bottom - 1), darken2); 877 view->AddLine(BPoint(rect.left - 1, rect.top - 1), 878 BPoint(rect.right - 1, rect.top - 1), darken2); 879 view->AddLine(BPoint(rect.right, rect.top - 1), 880 BPoint(rect.right, rect.top - 1), darken2); 881 view->EndLineArray(); 882 883 if (isEnabled && isFocused) { 884 // draw the focus ring on top of the frame 885 // Note that this is an intentional deviation from BeOS R5 886 // which draws the frame around the outside of the frame 887 // but that doesn't look as good. 888 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 889 view->StrokeRect(rect.InsetByCopy(-1, -1)); 890 } 891 } 892 893 894 void 895 BeControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 896 const BRect& updateRect, const rgb_color& base, bool popupIndicator, 897 uint32 flags) 898 { 899 _DrawMenuFieldBackgroundOutside(view, rect, updateRect, 900 0, 0, 0, 0, base, popupIndicator, flags); 901 } 902 903 904 void 905 BeControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 906 const BRect& updateRect, const rgb_color& base, uint32 flags, 907 uint32 borders) 908 { 909 _DrawMenuFieldBackgroundInside(view, rect, updateRect, 910 0, 0, 0, 0, base, flags, borders); 911 } 912 913 914 void 915 BeControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 916 const BRect& updateRect, float, const rgb_color& base, 917 bool popupIndicator, uint32 flags) 918 { 919 _DrawMenuFieldBackgroundOutside(view, rect, updateRect, 0, 0, 920 0, 0, base, popupIndicator, flags); 921 } 922 923 924 void 925 BeControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, 926 const BRect& updateRect, float, float, float, float, const rgb_color& base, 927 bool popupIndicator, uint32 flags) 928 { 929 _DrawMenuFieldBackgroundOutside(view, rect, updateRect, 0, 0, 930 0, 0, base, popupIndicator, flags); 931 } 932 933 934 void 935 BeControlLook::DrawMenuBackground(BView* view, BRect& rect, 936 const BRect& updateRect, const rgb_color& base, uint32 flags, 937 uint32 borders) 938 { 939 if (!ShouldDraw(view, rect, updateRect)) 940 return; 941 942 view->PushState(); 943 944 view->SetHighColor(base); 945 view->FillRect(rect); 946 947 view->PopState(); 948 } 949 950 951 void 952 BeControlLook::DrawMenuItemBackground(BView* view, BRect& rect, 953 const BRect& updateRect, const rgb_color& base, uint32 flags, 954 uint32 borders) 955 { 956 if (!ShouldDraw(view, rect, updateRect)) 957 return; 958 959 view->PushState(); 960 961 view->SetHighColor(base); 962 view->FillRect(rect); 963 964 view->PopState(); 965 } 966 967 968 void 969 BeControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, 970 const rgb_color& base, const rgb_color& barColor, float progressPosition) 971 { 972 if (!ShouldDraw(view, rect, updateRect)) 973 return; 974 975 view->PushState(); 976 977 // draw background 978 view->SetHighColor(base); 979 view->FillRect(rect); 980 981 // draw frame around bar 982 DrawTextControlBorder(view, rect, updateRect, tint_color(base, B_DARKEN_1_TINT)); 983 984 // filled and nonfilled rects 985 BRect filledRect(rect); 986 filledRect.right = progressPosition - 1; 987 BRect nonfilledRect(rect); 988 nonfilledRect.left = progressPosition; 989 990 bool drawFilled = filledRect.Width() > 0; 991 bool drawNonfilled = nonfilledRect.Width() > 0; 992 993 // filled 994 if (drawFilled) { 995 rgb_color light = tint_color(barColor, 0.6); 996 rgb_color dark = tint_color(barColor, 1.4); 997 _DrawFrame(view, filledRect, light, light, dark, dark); 998 999 view->SetHighColor(barColor); 1000 view->FillRect(filledRect); 1001 } 1002 1003 // nonfilled 1004 if (drawNonfilled) { 1005 view->SetHighColor(ui_color(B_CONTROL_BACKGROUND_COLOR)); 1006 view->FillRect(nonfilledRect); 1007 } 1008 1009 view->PopState(); 1010 } 1011 1012 1013 rgb_color 1014 BeControlLook::SliderBarColor(const rgb_color& base) 1015 { 1016 return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT); 1017 } 1018 1019 1020 void 1021 BeControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 1022 const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, 1023 float sliderScale, uint32 flags, orientation orientation) 1024 { 1025 if (!ShouldDraw(view, rect, updateRect)) 1026 return; 1027 1028 // separate the bar in two sides 1029 float sliderPosition; 1030 BRect leftBarSide = rect; 1031 BRect rightBarSide = rect; 1032 1033 if (orientation == B_HORIZONTAL) { 1034 sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) 1035 * sliderScale); 1036 leftBarSide.right = sliderPosition - 1; 1037 rightBarSide.left = sliderPosition; 1038 } else { 1039 // NOTE: position is reverse of coords 1040 sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) 1041 * (1.0 - sliderScale)); 1042 leftBarSide.top = sliderPosition; 1043 rightBarSide.bottom = sliderPosition - 1; 1044 } 1045 1046 view->PushState(); 1047 view->ClipToRect(leftBarSide); 1048 1049 DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, 1050 orientation); 1051 view->PopState(); 1052 1053 view->PushState(); 1054 view->ClipToRect(rightBarSide); 1055 1056 DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, 1057 orientation); 1058 view->PopState(); 1059 } 1060 1061 1062 void 1063 BeControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, 1064 const rgb_color& base, rgb_color fillColor, uint32 flags, 1065 orientation orientation) 1066 { 1067 if (!ShouldDraw(view, rect, updateRect)) 1068 return; 1069 1070 view->SetHighColor(fillColor); 1071 view->FillRect(rect); 1072 1073 rgb_color lightenmax = tint_color(base, B_LIGHTEN_MAX_TINT); 1074 rgb_color darken1 = tint_color(base, B_DARKEN_1_TINT); 1075 rgb_color darken2 = tint_color(base, B_DARKEN_2_TINT); 1076 rgb_color darkenmax = tint_color(base, B_DARKEN_MAX_TINT); 1077 1078 view->BeginLineArray(9); 1079 1080 view->AddLine(BPoint(rect.left, rect.top), 1081 BPoint(rect.left + 1, rect.top), darken1); 1082 view->AddLine(BPoint(rect.left, rect.bottom), 1083 BPoint(rect.left + 1, rect.bottom), darken1); 1084 view->AddLine(BPoint(rect.right - 1, rect.top), 1085 BPoint(rect.right, rect.top), darken1); 1086 1087 view->AddLine(BPoint(rect.left + 1, rect.top), 1088 BPoint(rect.right - 1, rect.top), darken2); 1089 view->AddLine(BPoint(rect.left, rect.bottom - 1), 1090 BPoint(rect.left, rect.top + 1), darken2); 1091 1092 view->AddLine(BPoint(rect.left + 1, rect.bottom), 1093 BPoint(rect.right, rect.bottom), lightenmax); 1094 view->AddLine(BPoint(rect.right, rect.top + 1), 1095 BPoint(rect.right, rect.bottom), lightenmax); 1096 1097 rect.InsetBy(1, 1); 1098 1099 view->AddLine(BPoint(rect.left, rect.top), 1100 BPoint(rect.left, rect.bottom), darkenmax); 1101 view->AddLine(BPoint(rect.left, rect.top), 1102 BPoint(rect.right, rect.top), darkenmax); 1103 1104 view->EndLineArray(); 1105 } 1106 1107 1108 void 1109 BeControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, 1110 const rgb_color& base, uint32 flags, orientation orientation) 1111 { 1112 if (!ShouldDraw(view, rect, updateRect)) 1113 return; 1114 1115 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 1116 rgb_color dark = tint_color(base, 1.333); // 144 1117 rgb_color darker = tint_color(base, 1.444); // 120 1118 rgb_color darkenmax = tint_color(base, B_DARKEN_MAX_TINT); 1119 1120 view->BeginLineArray(14); 1121 1122 // outline 1123 view->AddLine(BPoint(rect.left, rect.bottom - 2), 1124 BPoint(rect.left, rect.top + 1), darker); 1125 view->AddLine(BPoint(rect.left + 1, rect.top), 1126 BPoint(rect.right - 2, rect.top), darker); 1127 view->AddLine(BPoint(rect.right, rect.top + 2), 1128 BPoint(rect.right, rect.bottom - 1), darker); 1129 view->AddLine(BPoint(rect.left + 2, rect.bottom), 1130 BPoint(rect.right - 1, rect.bottom), darker); 1131 1132 // first bevel 1133 rect.InsetBy(1, 1); 1134 1135 view->SetHighColor(lighten2); 1136 view->FillRect(rect); 1137 1138 view->AddLine(BPoint(rect.left, rect.bottom), 1139 BPoint(rect.right - 1, rect.bottom), darkenmax); 1140 view->AddLine(BPoint(rect.right, rect.bottom - 1), 1141 BPoint(rect.right, rect.top), darkenmax); 1142 1143 rect.InsetBy(1, 1); 1144 1145 // second bevel and center dots 1146 view->SetHighColor(dark); 1147 view->AddLine(BPoint(rect.left, rect.bottom), 1148 BPoint(rect.right, rect.bottom), dark); 1149 view->AddLine(BPoint(rect.right, rect.top), 1150 BPoint(rect.right, rect.bottom), dark); 1151 1152 // center dots 1153 float hCenter = rect.Width() / 2; 1154 float vMiddle = rect.Height() / 2; 1155 if (orientation == B_HORIZONTAL) { 1156 view->AddLine(BPoint(rect.left + hCenter, rect.top + 1), 1157 BPoint(rect.left + hCenter, rect.top + 1), dark); 1158 view->AddLine(BPoint(rect.left + hCenter, rect.top + 3), 1159 BPoint(rect.left + hCenter, rect.top + 3), dark); 1160 view->AddLine(BPoint(rect.left + hCenter, rect.top + 5), 1161 BPoint(rect.left + hCenter, rect.top + 5), dark); 1162 } else { 1163 view->AddLine(BPoint(rect.left + 1, rect.top + vMiddle), 1164 BPoint(rect.left + 1, rect.top + vMiddle), dark); 1165 view->AddLine(BPoint(rect.left + 3, rect.top + vMiddle), 1166 BPoint(rect.left + 3, rect.top + vMiddle), dark); 1167 view->AddLine(BPoint(rect.left + 5, rect.top + vMiddle - 1), 1168 BPoint(rect.left + 5, rect.top + vMiddle), dark); 1169 } 1170 1171 view->AddLine(BPoint(rect.right + 1, rect.bottom + 1), 1172 BPoint(rect.right + 1, rect.bottom + 1), dark); 1173 1174 rect.InsetBy(1, 1); 1175 1176 // third bevel 1177 view->AddLine(BPoint(rect.left, rect.bottom), 1178 BPoint(rect.right, rect.bottom), base); 1179 view->AddLine(BPoint(rect.right, rect.top), 1180 BPoint(rect.right, rect.bottom), base); 1181 1182 view->EndLineArray(); 1183 } 1184 1185 1186 void 1187 BeControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1188 const BRect& updateRect, const rgb_color& base, uint32 flags, 1189 orientation orientation) 1190 { 1191 DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); 1192 } 1193 1194 1195 void 1196 BeControlLook::DrawSliderTriangle(BView* view, BRect& rect, 1197 const BRect& updateRect, const rgb_color& base, const rgb_color& fill, 1198 uint32 flags, orientation orientation) 1199 { 1200 if (!ShouldDraw(view, rect, updateRect)) 1201 return; 1202 1203 rgb_color lighten1 = tint_color(base, B_LIGHTEN_1_TINT); 1204 rgb_color darken2 = tint_color(base, B_DARKEN_2_TINT); 1205 rgb_color darkenmax = tint_color(base, B_DARKEN_MAX_TINT); 1206 1207 if (orientation == B_HORIZONTAL) { 1208 view->SetHighColor(lighten1); 1209 view->FillTriangle(BPoint(rect.left, rect.bottom - 1), 1210 BPoint(rect.left + 6, rect.top), 1211 BPoint(rect.right, rect.bottom - 1)); 1212 1213 view->SetHighColor(darkenmax); 1214 view->StrokeLine(BPoint(rect.right, rect.bottom + 1), 1215 BPoint(rect.left, rect.bottom + 1)); 1216 view->StrokeLine(BPoint(rect.right, rect.bottom), 1217 BPoint(rect.left + 6, rect.top)); 1218 1219 view->SetHighColor(darken2); 1220 view->StrokeLine(BPoint(rect.right - 1, rect.bottom), 1221 BPoint(rect.left, rect.bottom)); 1222 view->StrokeLine(BPoint(rect.left, rect.bottom), 1223 BPoint(rect.left + 5, rect.top + 1)); 1224 1225 view->SetHighColor(base); 1226 view->StrokeLine(BPoint(rect.right - 2, rect.bottom - 1), 1227 BPoint(rect.left + 3, rect.bottom - 1)); 1228 view->StrokeLine(BPoint(rect.right - 3, rect.bottom - 2), 1229 BPoint(rect.left + 6, rect.top + 1)); 1230 } else { 1231 view->SetHighColor(lighten1); 1232 view->FillTriangle(BPoint(rect.left + 1, rect.top), 1233 BPoint(rect.left + 7, rect.top + 6), 1234 BPoint(rect.left + 1, rect.bottom)); 1235 1236 view->SetHighColor(darkenmax); 1237 view->StrokeLine(BPoint(rect.left, rect.top + 1), 1238 BPoint(rect.left, rect.bottom)); 1239 view->StrokeLine(BPoint(rect.left + 1, rect.bottom), 1240 BPoint(rect.left + 7, rect.top + 6)); 1241 1242 view->SetHighColor(darken2); 1243 view->StrokeLine(BPoint(rect.left, rect.top), 1244 BPoint(rect.left, rect.bottom - 1)); 1245 view->StrokeLine(BPoint(rect.left + 1, rect.top), 1246 BPoint(rect.left + 6, rect.top + 5)); 1247 1248 view->SetHighColor(base); 1249 view->StrokeLine(BPoint(rect.left + 1, rect.top + 2), 1250 BPoint(rect.left + 1, rect.bottom - 1)); 1251 view->StrokeLine(BPoint(rect.left + 2, rect.bottom - 2), 1252 BPoint(rect.left + 6, rect.top + 6)); 1253 } 1254 } 1255 1256 1257 void 1258 BeControlLook::DrawSliderHashMarks(BView* view, BRect& rect, 1259 const BRect& updateRect, const rgb_color& base, int32 count, 1260 hash_mark_location location, uint32 flags, orientation orientation) 1261 { 1262 if (!ShouldDraw(view, rect, updateRect)) 1263 return; 1264 1265 rgb_color lightColor; 1266 rgb_color darkColor; 1267 1268 if ((flags & B_DISABLED) != 0) { 1269 lightColor = tint_color(base, 0.9); 1270 darkColor = tint_color(base, 1.07); 1271 } else { 1272 lightColor = tint_color(base, 0.8); 1273 darkColor = tint_color(base, 1.14); 1274 } 1275 1276 int32 hashMarkCount = std::max(count, (int32)2); 1277 // draw at least two hashmarks at min/max if 1278 // fHashMarks != B_HASH_MARKS_NONE 1279 float factor; 1280 float startPos; 1281 if (orientation == B_HORIZONTAL) { 1282 factor = (rect.Width() - 2) / (hashMarkCount - 1); 1283 startPos = rect.left + 1; 1284 } else { 1285 factor = (rect.Height() - 2) / (hashMarkCount - 1); 1286 startPos = rect.top + 1; 1287 } 1288 1289 if (location & B_HASH_MARKS_TOP) { 1290 view->BeginLineArray(hashMarkCount * 2); 1291 1292 if (orientation == B_HORIZONTAL) { 1293 float pos = startPos; 1294 for (int32 i = 0; i < hashMarkCount; i++) { 1295 view->AddLine(BPoint(pos, rect.top), 1296 BPoint(pos, rect.top + 4), darkColor); 1297 view->AddLine(BPoint(pos + 1, rect.top), 1298 BPoint(pos + 1, rect.top + 4), lightColor); 1299 1300 pos += factor; 1301 } 1302 } else { 1303 float pos = startPos; 1304 for (int32 i = 0; i < hashMarkCount; i++) { 1305 view->AddLine(BPoint(rect.left, pos), 1306 BPoint(rect.left + 4, pos), darkColor); 1307 view->AddLine(BPoint(rect.left, pos + 1), 1308 BPoint(rect.left + 4, pos + 1), lightColor); 1309 1310 pos += factor; 1311 } 1312 } 1313 1314 view->EndLineArray(); 1315 } 1316 1317 if ((location & B_HASH_MARKS_BOTTOM) != 0) { 1318 view->BeginLineArray(hashMarkCount * 2); 1319 1320 if (orientation == B_HORIZONTAL) { 1321 float pos = startPos; 1322 for (int32 i = 0; i < hashMarkCount; i++) { 1323 view->AddLine(BPoint(pos, rect.bottom - 4), 1324 BPoint(pos, rect.bottom), darkColor); 1325 view->AddLine(BPoint(pos + 1, rect.bottom - 4), 1326 BPoint(pos + 1, rect.bottom), lightColor); 1327 1328 pos += factor; 1329 } 1330 } else { 1331 float pos = startPos; 1332 for (int32 i = 0; i < hashMarkCount; i++) { 1333 view->AddLine(BPoint(rect.right - 4, pos), 1334 BPoint(rect.right, pos), darkColor); 1335 view->AddLine(BPoint(rect.right - 4, pos + 1), 1336 BPoint(rect.right, pos + 1), lightColor); 1337 1338 pos += factor; 1339 } 1340 } 1341 1342 view->EndLineArray(); 1343 } 1344 } 1345 1346 1347 void 1348 BeControlLook::DrawTabFrame(BView* view, BRect& rect, const BRect& updateRect, 1349 const rgb_color& base, uint32 flags, uint32 borders, 1350 border_style borderStyle, uint32 side) 1351 { 1352 view->SetHighColor(base); 1353 view->FillRect(rect); 1354 1355 rgb_color lightenmax = tint_color(base, B_LIGHTEN_MAX_TINT); 1356 1357 view->BeginLineArray(1); 1358 1359 switch(side) { 1360 case BTabView::kLeftSide: 1361 view->AddLine(BPoint(rect.right, rect.top), 1362 BPoint(rect.right, rect.bottom), lightenmax); 1363 break; 1364 1365 case BTabView::kRightSide: 1366 view->AddLine(BPoint(rect.left, rect.top), 1367 BPoint(rect.left, rect.bottom), lightenmax); 1368 break; 1369 1370 default: 1371 case BTabView::kTopSide: 1372 view->AddLine(BPoint(rect.left, rect.bottom), 1373 BPoint(rect.right, rect.bottom), lightenmax); 1374 break; 1375 1376 case BTabView::kBottomSide: 1377 view->AddLine(BPoint(rect.left, rect.top), 1378 BPoint(rect.right, rect.top), lightenmax); 1379 break; 1380 } 1381 1382 view->EndLineArray(); 1383 } 1384 1385 1386 void 1387 BeControlLook::DrawActiveTab(BView* view, BRect& rect, 1388 const BRect& updateRect, const rgb_color& base, uint32 flags, 1389 uint32 borders, uint32 side, int32, int32, int32, int32) 1390 { 1391 if (!ShouldDraw(view, rect, updateRect)) 1392 return; 1393 1394 view->PushState(); 1395 1396 // clip draw rect to rect plus 2px 1397 view->ClipToRect(rect.InsetByCopy(-2, -2)); 1398 1399 // set colors and draw 1400 1401 rgb_color lightenmax = tint_color(base, B_LIGHTEN_MAX_TINT); 1402 rgb_color darken4 = tint_color(base, B_DARKEN_4_TINT); 1403 rgb_color darkenmax = tint_color(base, B_DARKEN_MAX_TINT); 1404 1405 view->SetHighColor(darkenmax); 1406 view->SetLowColor(base); 1407 1408 view->BeginLineArray(12); 1409 1410 switch (side) { 1411 case BTabView::kLeftSide: 1412 // before going left 1413 view->AddLine(BPoint(rect.right - 1, rect.top - 1), 1414 BPoint(rect.right - 1, rect.top - 1), lightenmax); 1415 view->AddLine(BPoint(rect.right - 2, rect.top), 1416 BPoint(rect.right - 3, rect.top), lightenmax); 1417 1418 // going left 1419 view->AddLine(BPoint(rect.right - 4, rect.top + 1), 1420 BPoint(rect.left + 5, rect.top + 1), lightenmax); 1421 1422 // before going down 1423 view->AddLine(BPoint(rect.left + 2, rect.top + 2), 1424 BPoint(rect.left + 4, rect.top + 2), lightenmax); 1425 view->AddLine(BPoint(rect.left + 1, rect.top + 3), 1426 BPoint(rect.left + 1, rect.top + 4 ), lightenmax); 1427 1428 // going down 1429 view->AddLine(BPoint(rect.left, rect.top + 5), 1430 BPoint(rect.left, rect.bottom - 5), lightenmax); 1431 1432 // after going down 1433 view->AddLine(BPoint(rect.left + 1, rect.bottom - 4), 1434 BPoint(rect.left + 1, rect.bottom - 3), lightenmax); 1435 view->AddLine(BPoint(rect.left + 2, rect.bottom - 2), 1436 BPoint(rect.left + 3, rect.bottom - 2), darken4); 1437 1438 // going right 1439 view->AddLine(BPoint(rect.left + 4, rect.bottom - 1), 1440 BPoint(rect.right - 4, rect.bottom - 1), darken4); 1441 1442 // after going right 1443 view->AddLine(BPoint(rect.right - 3, rect.bottom), 1444 BPoint(rect.right - 2, rect.bottom), darken4); 1445 view->AddLine(BPoint(rect.right - 1, rect.bottom + 1), 1446 BPoint(rect.right - 1, rect.bottom + 1), darken4); 1447 view->AddLine(BPoint(rect.right, rect.bottom + 2), 1448 BPoint(rect.right, rect.bottom + 2), darken4); 1449 break; 1450 1451 case BTabView::kRightSide: 1452 // before going right 1453 view->AddLine(BPoint(rect.left - 1, rect.top - 1), 1454 BPoint(rect.left - 1, rect.top - 1), lightenmax); 1455 view->AddLine(BPoint(rect.left - 2, rect.top), 1456 BPoint(rect.left - 3, rect.top), lightenmax); 1457 1458 // going right 1459 view->AddLine(BPoint(rect.left - 4, rect.top + 1), 1460 BPoint(rect.right + 5, rect.top + 1), lightenmax); 1461 1462 // before going down 1463 view->AddLine(BPoint(rect.right + 2, rect.top + 2), 1464 BPoint(rect.right + 4, rect.top + 2), lightenmax); 1465 view->AddLine(BPoint(rect.right + 1, rect.top + 3), 1466 BPoint(rect.right + 1, rect.top + 4 ), lightenmax); 1467 1468 // going down 1469 view->AddLine(BPoint(rect.right, rect.top + 5), 1470 BPoint(rect.right, rect.bottom - 5), lightenmax); 1471 1472 // after going down 1473 view->AddLine(BPoint(rect.right + 1, rect.bottom - 4), 1474 BPoint(rect.right + 1, rect.bottom - 3), lightenmax); 1475 view->AddLine(BPoint(rect.right + 2, rect.bottom - 2), 1476 BPoint(rect.right + 3, rect.bottom - 2), darken4); 1477 1478 // going left 1479 view->AddLine(BPoint(rect.right + 4, rect.bottom - 1), 1480 BPoint(rect.left - 4, rect.bottom - 1), darken4); 1481 1482 // after going left 1483 view->AddLine(BPoint(rect.left - 3, rect.bottom), 1484 BPoint(rect.left - 2, rect.bottom), darken4); 1485 view->AddLine(BPoint(rect.left - 1, rect.bottom + 1), 1486 BPoint(rect.left - 1, rect.bottom + 1), darken4); 1487 view->AddLine(BPoint(rect.left, rect.bottom + 2), 1488 BPoint(rect.left, rect.bottom + 2), darken4); 1489 break; 1490 1491 default: 1492 case BTabView::kTopSide: 1493 // before going up 1494 view->AddLine(BPoint(rect.left - 1, rect.bottom - 1), 1495 BPoint(rect.left - 1, rect.bottom - 1), lightenmax); 1496 view->AddLine(BPoint(rect.left, rect.bottom - 2), 1497 BPoint(rect.left, rect.bottom - 3), lightenmax); 1498 1499 // going up 1500 view->AddLine(BPoint(rect.left + 1, rect.bottom - 4), 1501 BPoint(rect.left + 1, rect.top + 5), lightenmax); 1502 1503 // before going right 1504 view->AddLine(BPoint(rect.left + 2, rect.top + 4), 1505 BPoint(rect.left + 2, rect.top + 2), lightenmax); 1506 view->AddLine(BPoint(rect.left + 3, rect.top + 1), 1507 BPoint(rect.left + 4, rect.top + 1), lightenmax); 1508 1509 // going right 1510 view->AddLine(BPoint(rect.left + 5, rect.top), 1511 BPoint(rect.right - 5, rect.top), lightenmax); 1512 1513 // after going right 1514 view->AddLine(BPoint(rect.right - 4, rect.top + 1), 1515 BPoint(rect.right - 3, rect.top + 1), lightenmax); 1516 view->AddLine(BPoint(rect.right - 2, rect.top + 2), 1517 BPoint(rect.right - 2, rect.top + 3), darken4); 1518 1519 // going down 1520 view->AddLine(BPoint(rect.right - 1, rect.top + 4), 1521 BPoint(rect.right - 1, rect.bottom - 4), darken4); 1522 1523 // after going down 1524 view->AddLine(BPoint(rect.right, rect.bottom - 3), 1525 BPoint(rect.right, rect.bottom - 2), darken4); 1526 view->AddLine(BPoint(rect.right + 1, rect.bottom - 1), 1527 BPoint(rect.right + 1, rect.bottom - 1), darken4); 1528 view->AddLine(BPoint(rect.right + 2, rect.bottom), 1529 BPoint(rect.right + 2, rect.bottom), darken4); 1530 break; 1531 1532 case BTabView::kBottomSide: 1533 // before going down 1534 view->AddLine(BPoint(rect.left - 1, rect.top - 1), 1535 BPoint(rect.left - 1, rect.top - 1), lightenmax); 1536 view->AddLine(BPoint(rect.left, rect.top - 2), 1537 BPoint(rect.left, rect.top - 3), lightenmax); 1538 1539 // going down 1540 view->AddLine(BPoint(rect.left + 1, rect.top - 4), 1541 BPoint(rect.left + 1, rect.bottom + 5), lightenmax); 1542 1543 // before going right 1544 view->AddLine(BPoint(rect.left + 2, rect.bottom + 4), 1545 BPoint(rect.left + 2, rect.bottom + 2), lightenmax); 1546 view->AddLine(BPoint(rect.left + 3, rect.bottom + 1), 1547 BPoint(rect.left + 4, rect.bottom + 1), lightenmax); 1548 1549 // going right 1550 view->AddLine(BPoint(rect.left + 5, rect.bottom), 1551 BPoint(rect.right - 5, rect.bottom), lightenmax); 1552 1553 // after going right 1554 view->AddLine(BPoint(rect.right - 4, rect.bottom + 1), 1555 BPoint(rect.right - 3, rect.bottom + 1), lightenmax); 1556 view->AddLine(BPoint(rect.right - 2, rect.bottom + 2), 1557 BPoint(rect.right - 2, rect.bottom + 3), darken4); 1558 1559 // going up 1560 view->AddLine(BPoint(rect.right - 1, rect.bottom + 4), 1561 BPoint(rect.right - 1, rect.top - 4), darken4); 1562 1563 // after going up 1564 view->AddLine(BPoint(rect.right, rect.top - 3), 1565 BPoint(rect.right, rect.top - 2), darken4); 1566 view->AddLine(BPoint(rect.right + 1, rect.top - 1), 1567 BPoint(rect.right + 1, rect.top - 1), darken4); 1568 view->AddLine(BPoint(rect.right + 2, rect.top), 1569 BPoint(rect.right + 2, rect.top), darken4); 1570 break; 1571 } 1572 view->EndLineArray(); 1573 1574 // undraw white line 1575 view->BeginLineArray(1); 1576 switch (side) { 1577 case BTabView::kLeftSide: 1578 view->AddLine(BPoint(rect.right, rect.top - 1), 1579 BPoint(rect.right, rect.bottom + 1), base); 1580 break; 1581 1582 case BTabView::kRightSide: 1583 view->AddLine(BPoint(rect.left, rect.top - 1), 1584 BPoint(rect.left, rect.bottom + 1), base); 1585 break; 1586 1587 default: 1588 case BTabView::kTopSide: 1589 view->AddLine(BPoint(rect.left - 1, rect.bottom), 1590 BPoint(rect.right + 1, rect.bottom), base); 1591 break; 1592 1593 case BTabView::kBottomSide: 1594 view->AddLine(BPoint(rect.left - 1, rect.top), 1595 BPoint(rect.right + 1, rect.top), base); 1596 break; 1597 } 1598 view->EndLineArray(); 1599 1600 // inset rect for view contents 1601 rect.InsetBy(2, 2); 1602 1603 view->PopState(); 1604 } 1605 1606 1607 void 1608 BeControlLook::DrawInactiveTab(BView* view, BRect& rect, 1609 const BRect& updateRect, const rgb_color& base, uint32 flags, 1610 uint32 borders, uint32 side, int32 index, int32 selected, 1611 int32 first, int32 last) 1612 { 1613 if (!ShouldDraw(view, rect, updateRect)) 1614 return; 1615 1616 bool isFirst = index == first; 1617 bool isFull = index != selected - 1; 1618 1619 view->PushState(); 1620 1621 // clip draw rect to rect plus 2px 1622 view->ClipToRect(rect.InsetByCopy(-2, -2)); 1623 1624 // set colors and draw 1625 1626 rgb_color lightenmax = tint_color(base, B_LIGHTEN_MAX_TINT); 1627 rgb_color darken4 = tint_color(base, B_DARKEN_4_TINT); 1628 rgb_color darkenmax = tint_color(base, B_DARKEN_MAX_TINT); 1629 1630 view->SetHighColor(darkenmax); 1631 view->SetLowColor(base); 1632 1633 view->BeginLineArray(12); 1634 1635 switch (side) { 1636 case BTabView::kLeftSide: 1637 // only draw if first tab is unselected 1638 if (isFirst) { 1639 // before going left 1640 view->AddLine(BPoint(rect.right - 1, rect.top - 1), 1641 BPoint(rect.right - 1, rect.top - 1), lightenmax); 1642 view->AddLine(BPoint(rect.right - 2, rect.top), 1643 BPoint(rect.right - 3, rect.top), lightenmax); 1644 } 1645 1646 // going left 1647 view->AddLine(BPoint(rect.right - 4, rect.top + 1), 1648 BPoint(rect.left + 5, rect.top + 1), lightenmax); 1649 1650 // before going down 1651 view->AddLine(BPoint(rect.left + 2, rect.top + 2), 1652 BPoint(rect.left + 4, rect.top + 2), lightenmax); 1653 view->AddLine(BPoint(rect.left + 1, rect.top + 3), 1654 BPoint(rect.left + 1, rect.top + 4 ), lightenmax); 1655 1656 // going down 1657 view->AddLine(BPoint(rect.left, rect.top + 5), 1658 BPoint(rect.left, rect.bottom - 5), lightenmax); 1659 1660 // after going down 1661 view->AddLine(BPoint(rect.left + 1, rect.bottom - 4), 1662 BPoint(rect.left + 1, rect.bottom - 3), lightenmax); 1663 view->AddLine(BPoint(rect.left + 2, rect.bottom - 2), 1664 BPoint(rect.left + 3, rect.bottom - 2), darken4); 1665 1666 // going right 1667 view->AddLine(BPoint(rect.left + 4, rect.bottom - 1), 1668 BPoint(rect.right - 4, rect.bottom - 1), darken4); 1669 1670 // only draw if not before selected tab 1671 if (isFull) { 1672 // after going right 1673 view->AddLine(BPoint(rect.right - 3, rect.bottom), 1674 BPoint(rect.right - 2, rect.bottom), darken4); 1675 view->AddLine(BPoint(rect.right - 1, rect.bottom + 1), 1676 BPoint(rect.right - 1, rect.bottom + 1), darken4); 1677 } 1678 break; 1679 1680 case BTabView::kRightSide: 1681 // only draw if first tab is unselected 1682 if (isFirst) { 1683 // before going right 1684 view->AddLine(BPoint(rect.left - 1, rect.top - 1), 1685 BPoint(rect.left - 1, rect.top - 1), lightenmax); 1686 view->AddLine(BPoint(rect.left - 2, rect.top), 1687 BPoint(rect.left - 3, rect.top), lightenmax); 1688 } 1689 1690 // going right 1691 view->AddLine(BPoint(rect.left - 4, rect.top + 1), 1692 BPoint(rect.right + 5, rect.top + 1), lightenmax); 1693 1694 // before going down 1695 view->AddLine(BPoint(rect.right + 2, rect.top + 2), 1696 BPoint(rect.right + 4, rect.top + 2), lightenmax); 1697 view->AddLine(BPoint(rect.right + 1, rect.top + 3), 1698 BPoint(rect.right + 1, rect.top + 4 ), lightenmax); 1699 1700 // going down 1701 view->AddLine(BPoint(rect.right, rect.top + 5), 1702 BPoint(rect.right, rect.bottom - 5), lightenmax); 1703 1704 // after going down 1705 view->AddLine(BPoint(rect.right + 1, rect.bottom - 4), 1706 BPoint(rect.right + 1, rect.bottom - 3), lightenmax); 1707 view->AddLine(BPoint(rect.right + 2, rect.bottom - 2), 1708 BPoint(rect.right + 3, rect.bottom - 2), darken4); 1709 1710 // going left 1711 view->AddLine(BPoint(rect.right + 4, rect.bottom - 1), 1712 BPoint(rect.left - 4, rect.bottom - 1), darken4); 1713 1714 // only draw if not before selected tab 1715 if (isFull) { 1716 // after going left 1717 view->AddLine(BPoint(rect.left - 3, rect.bottom), 1718 BPoint(rect.left - 2, rect.bottom), darken4); 1719 view->AddLine(BPoint(rect.left - 1, rect.bottom + 1), 1720 BPoint(rect.left - 1, rect.bottom + 1), darken4); 1721 } 1722 break; 1723 1724 default: 1725 case BTabView::kTopSide: 1726 // only draw if first tab is unselected 1727 if (isFirst) { 1728 // before going up 1729 view->AddLine(BPoint(rect.left - 1, rect.bottom - 1), 1730 BPoint(rect.left - 1, rect.bottom - 1), lightenmax); 1731 view->AddLine(BPoint(rect.left, rect.bottom - 2), 1732 BPoint(rect.left, rect.bottom - 3), lightenmax);; 1733 } 1734 1735 // going up 1736 view->AddLine(BPoint(rect.left + 1, rect.bottom - 4), 1737 BPoint(rect.left + 1, rect.top + 5), lightenmax); 1738 1739 // before going right 1740 view->AddLine(BPoint(rect.left + 2, rect.top + 4), 1741 BPoint(rect.left + 2, rect.top + 2), lightenmax); 1742 view->AddLine(BPoint(rect.left + 3, rect.top + 1), 1743 BPoint(rect.left + 4, rect.top + 1), lightenmax); 1744 1745 // going right 1746 view->AddLine(BPoint(rect.left + 5, rect.top), 1747 BPoint(rect.right - 5, rect.top), lightenmax); 1748 1749 // after going right 1750 view->AddLine(BPoint(rect.right - 4, rect.top + 1), 1751 BPoint(rect.right - 3, rect.top + 1), lightenmax); 1752 view->AddLine(BPoint(rect.right - 2, rect.top + 2), 1753 BPoint(rect.right - 2, rect.top + 3), darken4); 1754 1755 // going down 1756 view->AddLine(BPoint(rect.right - 1, rect.top + 4), 1757 BPoint(rect.right - 1, rect.bottom - 4), darken4); 1758 1759 // only draw if not before selected tab 1760 if (isFull) { 1761 // after going down 1762 view->AddLine(BPoint(rect.right, rect.bottom - 3), 1763 BPoint(rect.right, rect.bottom - 2), darken4); 1764 view->AddLine(BPoint(rect.right + 1, rect.bottom - 1), 1765 BPoint(rect.right + 1, rect.bottom - 1), darken4); 1766 } 1767 break; 1768 1769 case BTabView::kBottomSide: 1770 // only draw if first tab is unselected 1771 if (isFirst) { 1772 // before going down 1773 view->AddLine(BPoint(rect.left - 1, rect.top - 1), 1774 BPoint(rect.left - 1, rect.top - 1), lightenmax); 1775 view->AddLine(BPoint(rect.left, rect.top - 2), 1776 BPoint(rect.left, rect.top - 3), lightenmax); 1777 } 1778 1779 // before going down 1780 view->AddLine(BPoint(rect.left + 1, rect.top - 4), 1781 BPoint(rect.left + 1, rect.bottom + 5), lightenmax); 1782 1783 // before going right 1784 view->AddLine(BPoint(rect.left + 2, rect.bottom + 4), 1785 BPoint(rect.left + 2, rect.bottom + 2), lightenmax); 1786 view->AddLine(BPoint(rect.left + 3, rect.bottom + 1), 1787 BPoint(rect.left + 4, rect.bottom + 1), lightenmax); 1788 1789 // going right 1790 view->AddLine(BPoint(rect.left + 5, rect.bottom), 1791 BPoint(rect.right - 5, rect.bottom), lightenmax); 1792 1793 // after going right 1794 view->AddLine(BPoint(rect.right - 4, rect.bottom + 1), 1795 BPoint(rect.right - 3, rect.bottom + 1), lightenmax); 1796 view->AddLine(BPoint(rect.right - 2, rect.bottom + 2), 1797 BPoint(rect.right - 2, rect.bottom + 3), darken4); 1798 1799 // going up 1800 view->AddLine(BPoint(rect.right - 1, rect.bottom + 4), 1801 BPoint(rect.right - 1, rect.top - 4), darken4); 1802 1803 // only draw if not before selected tab 1804 if (isFull) { 1805 // after going up 1806 view->AddLine(BPoint(rect.right, rect.top - 3), 1807 BPoint(rect.right, rect.top - 2), darken4); 1808 view->AddLine(BPoint(rect.right + 1, rect.top - 1), 1809 BPoint(rect.right + 1, rect.top - 1), darken4); 1810 } 1811 break; 1812 } 1813 1814 view->EndLineArray(); 1815 1816 // inset rect for view contents 1817 rect.InsetBy(2, 2); 1818 1819 view->PopState(); 1820 } 1821 1822 1823 void 1824 BeControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, 1825 const rgb_color& base, orientation orientation, uint32 flags, 1826 uint32 borders) 1827 { 1828 if (!ShouldDraw(view, rect, updateRect)) 1829 return; 1830 1831 rgb_color background; 1832 if ((flags & (B_CLICKED | B_ACTIVATED)) != 0) 1833 background = tint_color(base, B_DARKEN_1_TINT); 1834 else 1835 background = base; 1836 1837 rgb_color light = tint_color(background, 0.6); 1838 rgb_color shadow = tint_color(background, 1.21); 1839 1840 // frame 1841 if (borders != 0 && rect.Width() > 3 && rect.Height() > 3) 1842 DrawRaisedBorder(view, rect, updateRect, background, flags, borders); 1843 1844 // dots and rest of background 1845 if (orientation == B_HORIZONTAL) { 1846 if (rect.Width() > 2) { 1847 // background on left/right 1848 BRegion region(rect); 1849 rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5); 1850 rect.right = rect.left + 1; 1851 region.Exclude(rect); 1852 view->SetHighColor(background); 1853 view->FillRegion(®ion); 1854 } 1855 1856 BPoint dot = rect.LeftTop(); 1857 BPoint stop = rect.LeftBottom(); 1858 int32 num = 1; 1859 while (dot.y <= stop.y) { 1860 rgb_color col1; 1861 rgb_color col2; 1862 switch (num) { 1863 case 1: 1864 col1 = background; 1865 col2 = background; 1866 break; 1867 case 2: 1868 col1 = shadow; 1869 col2 = background; 1870 break; 1871 case 3: 1872 default: 1873 col1 = background; 1874 col2 = light; 1875 num = 0; 1876 break; 1877 } 1878 view->SetHighColor(col1); 1879 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1880 view->SetHighColor(col2); 1881 dot.x++; 1882 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1883 dot.x -= 1.0; 1884 // next pixel 1885 num++; 1886 dot.y++; 1887 } 1888 } else { 1889 if (rect.Height() > 2) { 1890 // background on left/right 1891 BRegion region(rect); 1892 rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5); 1893 rect.bottom = rect.top + 1; 1894 region.Exclude(rect); 1895 view->SetHighColor(background); 1896 view->FillRegion(®ion); 1897 } 1898 1899 BPoint dot = rect.LeftTop(); 1900 BPoint stop = rect.RightTop(); 1901 int32 num = 1; 1902 while (dot.x <= stop.x) { 1903 rgb_color col1; 1904 rgb_color col2; 1905 switch (num) { 1906 case 1: 1907 col1 = background; 1908 col2 = background; 1909 break; 1910 case 2: 1911 col1 = shadow; 1912 col2 = background; 1913 break; 1914 case 3: 1915 default: 1916 col1 = background; 1917 col2 = light; 1918 num = 0; 1919 break; 1920 } 1921 view->SetHighColor(col1); 1922 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1923 view->SetHighColor(col2); 1924 dot.y++; 1925 view->StrokeLine(dot, dot, B_SOLID_HIGH); 1926 dot.y -= 1.0; 1927 // next pixel 1928 num++; 1929 dot.x++; 1930 } 1931 } 1932 } 1933 1934 1935 // #pragma mark - various borders 1936 1937 1938 void 1939 BeControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, 1940 const rgb_color& base, border_style borderStyle, uint32 flags, 1941 uint32 borders) 1942 { 1943 if (borderStyle == B_NO_BORDER) 1944 return; 1945 1946 if (!ShouldDraw(view, rect, updateRect)) 1947 return; 1948 1949 view->PushState(); 1950 1951 view->ClipToRect(rect); 1952 1953 rgb_color lightColor; 1954 rgb_color shadowColor; 1955 if (base.Brightness() > 128) { 1956 lightColor = tint_color(base, B_DARKEN_2_TINT); 1957 shadowColor = tint_color(base, B_LIGHTEN_2_TINT); 1958 } else { 1959 lightColor = tint_color(base, B_LIGHTEN_MAX_TINT); 1960 shadowColor = tint_color(base, B_DARKEN_3_TINT); 1961 } 1962 1963 view->BeginLineArray(8); 1964 1965 if (borderStyle == B_FANCY_BORDER) { 1966 if ((borders & B_LEFT_BORDER) != 0) { 1967 view->AddLine(rect.LeftBottom(), rect.LeftTop(), shadowColor); 1968 rect.left++; 1969 } 1970 if ((borders & B_TOP_BORDER) != 0) { 1971 view->AddLine(rect.LeftTop(), rect.RightTop(), shadowColor); 1972 rect.top++; 1973 } 1974 if ((borders & B_RIGHT_BORDER) != 0) { 1975 view->AddLine(rect.RightTop(), rect.RightBottom(), shadowColor); 1976 rect.right--; 1977 } 1978 if ((borders & B_BOTTOM_BORDER) != 0) { 1979 view->AddLine(rect.RightBottom(), rect.LeftBottom(), shadowColor); 1980 rect.bottom--; 1981 } 1982 1983 if ((borders & B_LEFT_BORDER) != 0) { 1984 view->AddLine(rect.LeftBottom(), rect.LeftTop(), lightColor); 1985 rect.left++; 1986 } 1987 if ((borders & B_TOP_BORDER) != 0) { 1988 view->AddLine(rect.LeftTop(), rect.RightTop(), lightColor); 1989 rect.top++; 1990 } 1991 if ((borders & B_RIGHT_BORDER) != 0) { 1992 view->AddLine(rect.RightTop(), rect.RightBottom(), lightColor); 1993 rect.right--; 1994 } 1995 if ((borders & B_BOTTOM_BORDER) != 0) { 1996 view->AddLine(rect.RightBottom(), rect.LeftBottom(), lightColor); 1997 rect.bottom--; 1998 } 1999 } else if (borderStyle == B_PLAIN_BORDER) { 2000 if ((borders & B_LEFT_BORDER) != 0) { 2001 view->AddLine(rect.LeftBottom(), rect.LeftTop(), shadowColor); 2002 rect.left++; 2003 } 2004 if ((borders & B_TOP_BORDER) != 0) { 2005 view->AddLine(rect.LeftTop(), rect.RightTop(), shadowColor); 2006 rect.top++; 2007 } 2008 if ((borders & B_RIGHT_BORDER) != 0) { 2009 view->AddLine(rect.RightTop(), rect.RightBottom(), shadowColor); 2010 rect.right--; 2011 } 2012 if ((borders & B_BOTTOM_BORDER) != 0) { 2013 view->AddLine(rect.RightBottom(), rect.LeftBottom(), shadowColor); 2014 rect.bottom--; 2015 } 2016 2017 if ((borders & B_LEFT_BORDER) != 0) { 2018 view->AddLine(rect.LeftBottom(), rect.LeftTop(), lightColor); 2019 rect.left++; 2020 } 2021 if ((borders & B_TOP_BORDER) != 0) { 2022 view->AddLine(rect.LeftTop(), rect.RightTop(), lightColor); 2023 rect.top++; 2024 } 2025 if ((borders & B_RIGHT_BORDER) != 0) { 2026 view->AddLine(rect.RightTop(), rect.RightBottom(), lightColor); 2027 rect.right--; 2028 } 2029 if ((borders & B_BOTTOM_BORDER) != 0) { 2030 view->AddLine(rect.RightBottom(), rect.LeftBottom(), lightColor); 2031 rect.bottom--; 2032 } 2033 } 2034 2035 view->EndLineArray(); 2036 2037 view->PopState(); 2038 } 2039 2040 2041 void 2042 BeControlLook::DrawRaisedBorder(BView* view, BRect& rect, 2043 const BRect& updateRect, const rgb_color& base, uint32 flags, 2044 uint32 borders) 2045 { 2046 if (!ShouldDraw(view, rect, updateRect)) 2047 return; 2048 2049 view->PushState(); 2050 2051 view->ClipToRect(rect); 2052 2053 rgb_color lightColor; 2054 rgb_color shadowColor; 2055 2056 if ((flags & B_DISABLED) != 0) { 2057 lightColor = base; 2058 shadowColor = base; 2059 } else { 2060 lightColor = tint_color(base, 0.85); 2061 shadowColor = tint_color(base, 1.07); 2062 } 2063 2064 view->BeginLineArray(8); 2065 2066 if ((borders & B_LEFT_BORDER) != 0) { 2067 view->AddLine(rect.LeftBottom(), rect.LeftTop(), lightColor); 2068 rect.left++; 2069 } 2070 if ((borders & B_TOP_BORDER) != 0) { 2071 view->AddLine(rect.LeftTop(), rect.RightTop(), lightColor); 2072 rect.top++; 2073 } 2074 if ((borders & B_RIGHT_BORDER) != 0) { 2075 view->AddLine(rect.RightTop(), rect.RightBottom(), lightColor); 2076 rect.right--; 2077 } 2078 if ((borders & B_BOTTOM_BORDER) != 0) { 2079 view->AddLine(rect.RightBottom(), rect.LeftBottom(), lightColor); 2080 rect.bottom--; 2081 } 2082 2083 if ((borders & B_LEFT_BORDER) != 0) { 2084 view->AddLine(rect.LeftBottom(), rect.LeftTop(), shadowColor); 2085 rect.left++; 2086 } 2087 if ((borders & B_TOP_BORDER) != 0) { 2088 view->AddLine(rect.LeftTop(), rect.RightTop(), shadowColor); 2089 rect.top++; 2090 } 2091 if ((borders & B_RIGHT_BORDER) != 0) { 2092 view->AddLine(rect.RightTop(), rect.RightBottom(), shadowColor); 2093 rect.right--; 2094 } 2095 if ((borders & B_BOTTOM_BORDER) != 0) { 2096 view->AddLine(rect.RightBottom(), rect.LeftBottom(), shadowColor); 2097 rect.bottom--; 2098 } 2099 2100 view->EndLineArray(); 2101 2102 view->PopState(); 2103 } 2104 2105 2106 void 2107 BeControlLook::DrawTextControlBorder(BView* view, BRect& rect, 2108 const BRect& updateRect, const rgb_color& base, uint32 flags, 2109 uint32 borders) 2110 { 2111 if (!ShouldDraw(view, rect, updateRect)) 2112 return; 2113 2114 view->PushState(); 2115 2116 view->ClipToRect(rect); 2117 2118 bool isEnabled = (flags & B_DISABLED) == 0; 2119 bool isFocused = (flags & B_FOCUSED) != 0; 2120 2121 rgb_color dark; 2122 rgb_color light; 2123 2124 // outer bevel 2125 2126 dark = tint_color(base, (isEnabled ? B_DARKEN_1_TINT : B_DARKEN_2_TINT)); 2127 light = tint_color(base, (isEnabled ? B_LIGHTEN_MAX_TINT : B_LIGHTEN_2_TINT)); 2128 2129 _DrawFrame(view, rect, dark, dark, light, light); 2130 2131 // inner bevel 2132 2133 if (isEnabled && isFocused) { 2134 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 2135 view->StrokeRect(rect); 2136 rect.InsetBy(1, 1); 2137 } else { 2138 dark = tint_color(base, (isEnabled ? B_DARKEN_4_TINT : B_LIGHTEN_2_TINT)); 2139 light = base; 2140 2141 _DrawFrame(view, rect, dark, dark, light, light); 2142 } 2143 2144 view->PopState(); 2145 } 2146 2147 2148 void 2149 BeControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, 2150 const rgb_color& base, uint32 borders) 2151 { 2152 DrawBorder(view, rect, updateRect, base, B_FANCY_BORDER, 0, borders); 2153 } 2154 2155 2156 // #pragma mark - Labels 2157 2158 2159 void 2160 BeControlLook::DrawLabel(BView* view, const char* label, BRect rect, 2161 const BRect& updateRect, const rgb_color& base, uint32 flags, 2162 const rgb_color* textColor) 2163 { 2164 DrawLabel(view, label, NULL, rect, updateRect, base, flags, 2165 DefaultLabelAlignment(), textColor); 2166 } 2167 2168 2169 void 2170 BeControlLook::DrawLabel(BView* view, const char* label, BRect rect, 2171 const BRect& updateRect, const rgb_color& base, uint32 flags, 2172 const BAlignment& alignment, const rgb_color* textColor) 2173 { 2174 DrawLabel(view, label, NULL, rect, updateRect, base, flags, alignment, 2175 textColor); 2176 } 2177 2178 2179 void 2180 BeControlLook::DrawLabel(BView* view, const char* label, const rgb_color& base, 2181 uint32 flags, const BPoint& where, const rgb_color* textColor) 2182 { 2183 view->PushState(); 2184 2185 bool isButton = (flags & B_FLAT) != 0 || (flags & B_HOVER) != 0 2186 || (flags & B_DEFAULT_BUTTON) != 0; 2187 bool isEnabled = (flags & B_DISABLED) == 0; 2188 bool isActivated = (flags & B_ACTIVATED) != 0; 2189 2190 BWindow* window = view->Window(); 2191 bool isDesktop = window != NULL 2192 && window->Feel() == kDesktopWindowFeel 2193 && window->Look() == kDesktopWindowLook 2194 && view->Parent() 2195 && view->Parent()->Parent() == NULL 2196 && (flags & B_IGNORE_OUTLINE) == 0; 2197 2198 rgb_color low; 2199 rgb_color color; 2200 rgb_color glowColor; 2201 2202 if (textColor != NULL) 2203 glowColor = *textColor; 2204 else if ((flags & B_IS_CONTROL) != 0) 2205 glowColor = ui_color(B_CONTROL_TEXT_COLOR); 2206 else 2207 glowColor = ui_color(B_PANEL_TEXT_COLOR); 2208 2209 color = glowColor; 2210 2211 if (isDesktop) 2212 low = view->Parent()->ViewColor(); 2213 else 2214 low = base; 2215 2216 if (!isEnabled) { 2217 color.red = (uint8)(((int32)low.red + color.red + 1) / 2); 2218 color.green = (uint8)(((int32)low.green + color.green + 1) / 2); 2219 color.blue = (uint8)(((int32)low.blue + color.blue + 1) / 2); 2220 } 2221 2222 if (isDesktop) { 2223 // enforce proper use of desktop label colors 2224 if (low.Brightness() < 100) { 2225 if (textColor == NULL) 2226 color = make_color(255, 255, 255); 2227 2228 glowColor = make_color(0, 0, 0); 2229 } else { 2230 if (textColor == NULL) 2231 color = make_color(0, 0, 0); 2232 2233 glowColor = make_color(255, 255, 255); 2234 } 2235 2236 // drawing occurs on the desktop 2237 if (fCachedWorkspace != current_workspace()) { 2238 int8 indice = 0; 2239 int32 mask; 2240 bool tmpOutline; 2241 while (fBackgroundInfo.FindInt32("be:bgndimginfoworkspaces", 2242 indice, &mask) == B_OK 2243 && fBackgroundInfo.FindBool("be:bgndimginfoerasetext", 2244 indice, &tmpOutline) == B_OK) { 2245 2246 if (((1 << current_workspace()) & mask) != 0) { 2247 fCachedOutline = tmpOutline; 2248 fCachedWorkspace = current_workspace(); 2249 break; 2250 } 2251 indice++; 2252 } 2253 } 2254 2255 if (fCachedOutline) { 2256 BFont font; 2257 view->GetFont(&font); 2258 2259 view->SetDrawingMode(B_OP_ALPHA); 2260 view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); 2261 // Draw glow or outline 2262 if (glowColor.Brightness() > 128) { 2263 font.SetFalseBoldWidth(2.0); 2264 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 2265 2266 glowColor.alpha = 30; 2267 view->SetHighColor(glowColor); 2268 view->DrawString(label, where); 2269 2270 font.SetFalseBoldWidth(1.0); 2271 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 2272 2273 glowColor.alpha = 65; 2274 view->SetHighColor(glowColor); 2275 view->DrawString(label, where); 2276 2277 font.SetFalseBoldWidth(0.0); 2278 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 2279 } else { 2280 font.SetFalseBoldWidth(1.0); 2281 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 2282 2283 glowColor.alpha = 30; 2284 view->SetHighColor(glowColor); 2285 view->DrawString(label, where); 2286 2287 font.SetFalseBoldWidth(0.0); 2288 view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); 2289 2290 glowColor.alpha = 200; 2291 view->SetHighColor(glowColor); 2292 view->DrawString(label, BPoint(where.x + 1, where.y + 1)); 2293 } 2294 } 2295 } 2296 2297 rgb_color invertedIfClicked = color; 2298 if (isButton && isEnabled && isActivated) { 2299 // only for enabled and activated buttons 2300 invertedIfClicked.red = 255 - invertedIfClicked.red; 2301 invertedIfClicked.green = 255 - invertedIfClicked.green; 2302 invertedIfClicked.blue = 255 - invertedIfClicked.blue; 2303 } 2304 2305 view->SetLowColor(invertedIfClicked); 2306 view->SetHighColor(invertedIfClicked); 2307 view->SetDrawingMode(B_OP_OVER); 2308 view->DrawString(label, where); 2309 view->SetDrawingMode(B_OP_COPY); 2310 2311 view->PopState(); 2312 } 2313 2314 2315 void 2316 BeControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, 2317 BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, 2318 const BAlignment& alignment, const rgb_color* textColor) 2319 { 2320 if (!ShouldDraw(view, rect, updateRect)) 2321 return; 2322 2323 if (label == NULL && icon == NULL) 2324 return; 2325 2326 if (label == NULL && icon != NULL) { 2327 // icon only 2328 BRect alignedRect = BLayoutUtils::AlignInFrame( 2329 rect.OffsetByCopy(-2, -2), 2330 icon->Bounds().Size(), alignment); 2331 view->SetDrawingMode(B_OP_OVER); 2332 view->DrawBitmap(icon, alignedRect.LeftTop()); 2333 view->SetDrawingMode(B_OP_COPY); 2334 return; 2335 } 2336 2337 view->PushState(); 2338 2339 // label, possibly with icon 2340 float availableWidth = rect.Width() + 1; 2341 float width = 0; 2342 float textOffset = 0; 2343 float height = 0; 2344 2345 if (icon != NULL && label != NULL) { 2346 // move text over to fit icon 2347 width = icon->Bounds().Width() + DefaultLabelSpacing() + 1; 2348 height = icon->Bounds().Height() + 1; 2349 textOffset = width; 2350 availableWidth -= textOffset; 2351 } 2352 2353 // truncate the label if necessary and get the width and height 2354 BString truncatedLabel(label); 2355 2356 BFont font; 2357 view->GetFont(&font); 2358 2359 font.TruncateString(&truncatedLabel, B_TRUNCATE_MIDDLE, availableWidth); 2360 width += ceilf(font.StringWidth(truncatedLabel.String())); 2361 2362 font_height fontHeight; 2363 font.GetHeight(&fontHeight); 2364 float textHeight = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); 2365 height = std::max(height, textHeight); 2366 2367 // handle alignment 2368 BRect alignedRect(BLayoutUtils::AlignOnRect(rect, 2369 BSize(width - 1, height - 1), alignment)); 2370 2371 if (icon != NULL) { 2372 BPoint location(alignedRect.LeftTop()); 2373 if (icon->Bounds().Height() + 1 < height) 2374 location.y += ceilf((height - icon->Bounds().Height() - 1) / 2); 2375 2376 view->SetDrawingMode(B_OP_OVER); 2377 view->DrawBitmap(icon, location); 2378 view->SetDrawingMode(B_OP_COPY); 2379 } 2380 2381 BPoint location(alignedRect.left + textOffset, 2382 alignedRect.top + ceilf(fontHeight.ascent)); 2383 if (textHeight < height) 2384 location.y += ceilf((height - textHeight) / 2); 2385 2386 if ((flags & B_FOCUSED) != 0) { 2387 // draw underline under label 2388 float x = location.x; 2389 float y = location.y + ceilf(fontHeight.descent); 2390 view->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 2391 view->StrokeLine(BPoint(x, y), 2392 BPoint(x + view->StringWidth(truncatedLabel.String()), y)); 2393 } 2394 2395 DrawLabel(view, truncatedLabel.String(), base, flags, location, textColor); 2396 2397 view->PopState(); 2398 } 2399 2400 2401 void 2402 BeControlLook::GetFrameInsets(frame_type frameType, uint32 flags, float& _left, 2403 float& _top, float& _right, float& _bottom) 2404 { 2405 // All frames have the same inset on each side. 2406 float inset = 0; 2407 2408 switch (frameType) { 2409 case B_BUTTON_FRAME: 2410 inset = (flags & B_DEFAULT_BUTTON) != 0 ? 5 : 2; 2411 break; 2412 2413 case B_GROUP_FRAME: 2414 case B_MENU_FIELD_FRAME: 2415 inset = 3; 2416 break; 2417 2418 case B_SCROLL_VIEW_FRAME: 2419 case B_TEXT_CONTROL_FRAME: 2420 inset = 2; 2421 break; 2422 } 2423 2424 _left = inset; 2425 _top = inset; 2426 _right = inset; 2427 _bottom = inset; 2428 } 2429 2430 2431 void 2432 BeControlLook::GetBackgroundInsets(background_type backgroundType, 2433 uint32 flags, float& _left, float& _top, float& _right, float& _bottom) 2434 { 2435 // Most backgrounds have the same inset on each side. 2436 float inset = 0; 2437 2438 switch (backgroundType) { 2439 case B_BUTTON_BACKGROUND: 2440 case B_MENU_BACKGROUND: 2441 case B_MENU_BAR_BACKGROUND: 2442 case B_MENU_FIELD_BACKGROUND: 2443 case B_MENU_ITEM_BACKGROUND: 2444 inset = 1; 2445 break; 2446 case B_BUTTON_WITH_POP_UP_BACKGROUND: 2447 _left = 1; 2448 _top = 1; 2449 _right = 1 + kButtonPopUpIndicatorWidth; 2450 _bottom = 1; 2451 return; 2452 case B_HORIZONTAL_SCROLL_BAR_BACKGROUND: 2453 _left = 2; 2454 _top = 0; 2455 _right = 1; 2456 _bottom = 0; 2457 return; 2458 case B_VERTICAL_SCROLL_BAR_BACKGROUND: 2459 _left = 0; 2460 _top = 2; 2461 _right = 0; 2462 _bottom = 1; 2463 return; 2464 } 2465 2466 _left = inset; 2467 _top = inset; 2468 _right = inset; 2469 _bottom = inset; 2470 } 2471 2472 2473 void 2474 BeControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, 2475 const BRect& updateRect, const rgb_color& base, uint32 flags, 2476 uint32 borders, orientation orientation) 2477 { 2478 _DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, 2479 base, true, flags, borders, orientation); 2480 } 2481 2482 2483 void 2484 BeControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, 2485 const BRect& updateRect, float radius, const rgb_color& base, uint32 flags, 2486 uint32 borders, orientation orientation) 2487 { 2488 _DrawButtonBackground(view, rect, updateRect, radius, radius, radius, 2489 radius, base, true, flags, borders, orientation); 2490 } 2491 2492 2493 void 2494 BeControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, 2495 const BRect& updateRect, float leftTopRadius, float rightTopRadius, 2496 float leftBottomRadius, float rightBottomRadius, const rgb_color& base, 2497 uint32 flags, uint32 borders, orientation orientation) 2498 { 2499 _DrawButtonBackground(view, rect, updateRect, leftTopRadius, 2500 rightTopRadius, leftBottomRadius, rightBottomRadius, base, true, flags, 2501 borders, orientation); 2502 } 2503 2504 2505 // #pragma mark - protected methods 2506 2507 2508 void 2509 BeControlLook::_DrawButtonFrame(BView* view, BRect& rect, 2510 const BRect& updateRect, float, float, float, float, const rgb_color& base, 2511 const rgb_color& background, float contrast, float brightness, 2512 uint32 flags, uint32 borders) 2513 { 2514 if (!ShouldDraw(view, rect, updateRect)) 2515 return; 2516 2517 view->PushState(); 2518 2519 view->ClipToRect(rect); 2520 2521 // flags 2522 bool isEnabled = (flags & B_DISABLED) == 0; 2523 bool isDefault = (flags & B_DEFAULT_BUTTON) != 0; 2524 2525 // colors 2526 rgb_color lighten1 = tint_color(base, B_LIGHTEN_1_TINT); // 231 2527 lighten1.red++; lighten1.green++; lighten1.blue++; // 232 = 231 + 1 2528 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 2529 rgb_color lightenMax = tint_color(base, B_LIGHTEN_MAX_TINT); 2530 rgb_color darken1 = tint_color(base, B_DARKEN_1_TINT); // 184 2531 rgb_color darken2 = tint_color(base, B_DARKEN_2_TINT); // 158 2532 rgb_color darken3 = tint_color(base, B_DARKEN_3_TINT); 2533 rgb_color darken4 = tint_color(base, B_DARKEN_4_TINT); // 96 2534 2535 rgb_color buttonBgColor = lighten1; 2536 rgb_color lightColor; 2537 2538 rgb_color dark1BorderColor; 2539 rgb_color dark2BorderColor; 2540 2541 rgb_color bevelColor1; 2542 rgb_color bevelColor2; 2543 rgb_color bevelColorRBCorner; 2544 2545 rgb_color borderBevelShadow; 2546 rgb_color borderBevelLight; 2547 2548 if (isEnabled) { 2549 lightColor = tint_color(base, B_LIGHTEN_2_TINT); 2550 dark1BorderColor = darken3; 2551 dark2BorderColor = darken4; 2552 bevelColor1 = darken2; 2553 bevelColor2 = lighten1; 2554 2555 if (isDefault) { 2556 borderBevelShadow = tint_color(dark1BorderColor, 2557 (B_NO_TINT + B_DARKEN_1_TINT) / 2); 2558 borderBevelLight = tint_color(dark1BorderColor, B_LIGHTEN_1_TINT); 2559 2560 borderBevelLight.red = (borderBevelLight.red + base.red) / 2; 2561 borderBevelLight.green = (borderBevelLight.green + base.green) / 2; 2562 borderBevelLight.blue = (borderBevelLight.blue + base.blue) / 2; 2563 2564 dark1BorderColor = darken3; 2565 dark2BorderColor = darken4; 2566 2567 bevelColorRBCorner = borderBevelShadow; 2568 } else { 2569 borderBevelShadow = tint_color(base, 2570 (B_NO_TINT + B_DARKEN_1_TINT) / 2); 2571 borderBevelLight = buttonBgColor; 2572 bevelColorRBCorner = dark1BorderColor; 2573 } 2574 } else { 2575 lightColor = lighten2; 2576 dark1BorderColor = darken1; 2577 dark2BorderColor = darken2; 2578 bevelColor1 = base; 2579 bevelColor2 = buttonBgColor; 2580 2581 if (isDefault) { 2582 borderBevelShadow = dark1BorderColor; 2583 borderBevelLight = base; 2584 dark1BorderColor = tint_color(dark1BorderColor, B_DARKEN_1_TINT); 2585 dark2BorderColor = tint_color(dark1BorderColor, 1.16); 2586 } else { 2587 borderBevelShadow = base; 2588 borderBevelLight = base; 2589 } 2590 2591 bevelColorRBCorner = tint_color(base, 1.08); 2592 } 2593 2594 if (isDefault) { 2595 if (isEnabled) { 2596 // dark border 2597 view->BeginLineArray(4); 2598 if ((borders & B_LEFT_BORDER) != 0) { 2599 view->AddLine(BPoint(rect.left, rect.top + 1), 2600 BPoint(rect.left, rect.bottom - 1), dark2BorderColor); 2601 rect.left++; 2602 } 2603 if ((borders & B_TOP_BORDER) != 0) { 2604 view->AddLine(BPoint(rect.left, rect.top), 2605 BPoint(rect.right - 1, rect.top), dark2BorderColor); 2606 rect.top++; 2607 } 2608 if ((borders & B_RIGHT_BORDER) != 0) { 2609 view->AddLine(BPoint(rect.right, rect.top), 2610 BPoint(rect.right, rect.bottom - 1), dark2BorderColor); 2611 rect.right--; 2612 } 2613 if ((borders & B_BOTTOM_BORDER) != 0) { 2614 view->AddLine(BPoint(rect.left, rect.bottom), 2615 BPoint(rect.right, rect.bottom), dark2BorderColor); 2616 rect.bottom--; 2617 } 2618 view->EndLineArray(); 2619 2620 // bevel 2621 view->SetHighColor(darken1); 2622 view->StrokeRect(rect); 2623 2624 rect.InsetBy(1, 1); 2625 2626 // fill 2627 view->SetHighColor(lighten1); 2628 view->FillRect(rect); 2629 2630 rect.InsetBy(2, 2); 2631 } else { 2632 // dark border 2633 view->BeginLineArray(4); 2634 if ((borders & B_LEFT_BORDER) != 0) { 2635 view->AddLine(BPoint(rect.left, rect.top + 1), 2636 BPoint(rect.left, rect.bottom - 1), darken1); 2637 rect.left++; 2638 } 2639 if ((borders & B_TOP_BORDER) != 0) { 2640 view->AddLine(BPoint(rect.left, rect.top), 2641 BPoint(rect.right - 1, rect.top), darken1); 2642 rect.top++; 2643 } 2644 if ((borders & B_RIGHT_BORDER) != 0) { 2645 view->AddLine(BPoint(rect.right, rect.top), 2646 BPoint(rect.right, rect.bottom - 1), darken1); 2647 rect.right--; 2648 } 2649 if ((borders & B_BOTTOM_BORDER) != 0) { 2650 view->AddLine(BPoint(rect.left, rect.bottom), 2651 BPoint(rect.right, rect.bottom), darken1); 2652 rect.bottom--; 2653 } 2654 view->EndLineArray(); 2655 2656 // fill 2657 view->SetHighColor(lighten1); 2658 view->FillRect(rect); 2659 2660 rect.InsetBy(3, 3); 2661 } 2662 } else { 2663 // if not default button, inset top and bottom by 1px 2664 rect.InsetBy(1, 0); 2665 } 2666 2667 // stroke frame to draw four corners, then write on top 2668 view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 2669 view->StrokeRect(rect); 2670 2671 view->BeginLineArray(16); 2672 2673 // external border 2674 view->AddLine(BPoint(rect.left, rect.top + 1), 2675 BPoint(rect.left, rect.bottom - 1), 2676 (borders & B_LEFT_BORDER) != 0 ? dark2BorderColor : darken1); 2677 view->AddLine(BPoint(rect.left + 1, rect.top), 2678 BPoint(rect.right - 1, rect.top), 2679 (borders & B_TOP_BORDER) != 0 ? dark2BorderColor : darken1); 2680 view->AddLine(BPoint(rect.right, rect.top + 1), 2681 BPoint(rect.right, rect.bottom - 1), 2682 (borders & B_RIGHT_BORDER) != 0 ? dark2BorderColor : darken1); 2683 view->AddLine(BPoint(rect.left + 1, rect.bottom), 2684 BPoint(rect.right - 1, rect.bottom), 2685 (borders & B_BOTTOM_BORDER) != 0 ? dark2BorderColor : darken1); 2686 2687 // inset past external border 2688 rect.InsetBy(1, 1); 2689 2690 // internal bevel 2691 view->AddLine(rect.LeftBottom(), rect.LeftTop(), bevelColor2); 2692 view->AddLine(rect.LeftTop(), rect.RightTop(), bevelColor2); 2693 view->AddLine(BPoint(rect.right, rect.top + 1), rect.RightBottom(), 2694 bevelColor1); 2695 view->AddLine(rect.RightBottom(), BPoint(rect.left + 1, rect.bottom), 2696 bevelColor1); 2697 2698 // inset past internal bevel 2699 rect.InsetBy(1, 1); 2700 2701 // internal gloss outside 2702 view->AddLine(BPoint(rect.left, rect.bottom + 1), rect.LeftTop(), 2703 lightenMax); // come down an extra pixel 2704 view->AddLine(rect.LeftTop(), rect.RightTop(), lightenMax); 2705 view->AddLine(rect.RightTop(), rect.RightBottom(), base); 2706 view->AddLine(rect.RightBottom(), BPoint(rect.left + 1, rect.bottom), 2707 base); // compensate for extra pixel 2708 2709 // inset past gloss outside 2710 rect.InsetBy(1, 1); 2711 2712 // internal gloss inside 2713 view->AddLine(BPoint(rect.left, rect.bottom + 1), rect.LeftTop(), 2714 lightenMax); // come down an extra pixel 2715 view->AddLine(rect.LeftTop(), rect.RightTop(), lightenMax); 2716 view->AddLine(rect.RightTop(), rect.RightBottom(), buttonBgColor); 2717 view->AddLine(rect.RightBottom(), BPoint(rect.left + 1, rect.bottom), 2718 buttonBgColor); // compensate for extra pixel 2719 2720 // inset past gloss inside 2721 rect.InsetBy(1, 1); 2722 2723 view->EndLineArray(); 2724 2725 view->PopState(); 2726 } 2727 2728 2729 void 2730 BeControlLook::_DrawButtonBackground(BView* view, BRect& rect, 2731 const BRect& updateRect, float, float, float, float, const rgb_color& base, 2732 bool popupIndicator, uint32 flags, uint32 borders, orientation orientation) 2733 { 2734 if (!ShouldDraw(view, rect, updateRect)) 2735 return; 2736 2737 // fill the button area 2738 view->SetHighColor(tint_color(base, B_LIGHTEN_1_TINT)); 2739 view->FillRect(rect); 2740 2741 bool isEnabled = (flags & B_DISABLED) == 0; 2742 bool isActivated = (flags & B_ACTIVATED) != 0; 2743 2744 if (isEnabled && isActivated) { 2745 // invert if clicked without altering rect 2746 BRect invertRect(rect.InsetByCopy(-3, -3)); 2747 view->SetDrawingMode(B_OP_INVERT); 2748 view->FillRect(invertRect); 2749 } 2750 } 2751 2752 2753 void 2754 BeControlLook::_DrawPopUpMarker(BView* view, const BRect& rect, 2755 const rgb_color& base, uint32 flags) 2756 { 2757 bool isEnabled = (flags & B_DISABLED) == 0; 2758 2759 BPoint position(rect.right - 8, rect.bottom - 8); 2760 BPoint triangle[3]; 2761 triangle[0] = position + BPoint(-2.5, -0.5); 2762 triangle[1] = position + BPoint(2.5, -0.5); 2763 triangle[2] = position + BPoint(0.0, 2.0); 2764 2765 uint32 viewFlags = view->Flags(); 2766 view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); 2767 2768 rgb_color markerColor = isEnabled 2769 ? tint_color(base, B_DARKEN_4_TINT) 2770 : tint_color(base, B_DARKEN_2_TINT); 2771 2772 view->SetHighColor(markerColor); 2773 view->FillTriangle(triangle[0], triangle[1], triangle[2]); 2774 2775 view->SetFlags(viewFlags); 2776 } 2777 2778 2779 void 2780 BeControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect, 2781 const BRect& updateRect, float, float, float, float, const rgb_color& base, 2782 bool popupIndicator, uint32 flags) 2783 { 2784 if (!ShouldDraw(view, rect, updateRect)) 2785 return; 2786 2787 // BeControlLook does not support rounded corners and it never will 2788 if (popupIndicator) { 2789 BRect rightRect(rect); 2790 rightRect.left = rect.right - 10; 2791 2792 _DrawMenuFieldBackgroundInside(view, rect, updateRect, 2793 0, 0, 0, 0, base, flags, B_ALL_BORDERS); 2794 _DrawPopUpMarker(view, rightRect, base, flags); 2795 } else { 2796 _DrawMenuFieldBackgroundInside(view, rect, updateRect, 0, 0, 2797 0, 0, base, flags); 2798 } 2799 } 2800 2801 2802 void 2803 BeControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, 2804 const BRect& updateRect, float, float, float, float, const rgb_color& base, 2805 uint32 flags, uint32 borders) 2806 { 2807 if (!ShouldDraw(view, rect, updateRect)) 2808 return; 2809 2810 view->PushState(); 2811 2812 view->ClipToRect(rect); 2813 2814 // flags 2815 bool isEnabled = (flags & B_DISABLED) == 0; 2816 2817 // colors 2818 rgb_color darken4; 2819 rgb_color darken1; 2820 rgb_color lighten1; 2821 rgb_color lighten2; 2822 2823 if (isEnabled) { 2824 darken4 = tint_color(base, B_DARKEN_4_TINT); 2825 darken1 = tint_color(base, B_DARKEN_1_TINT); 2826 lighten1 = tint_color(base, B_LIGHTEN_1_TINT); 2827 lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 2828 } else { 2829 darken4 = tint_color(base, B_DARKEN_2_TINT); 2830 darken1 = tint_color(base, (B_NO_TINT + B_DARKEN_1_TINT) / 2.0); 2831 lighten1 = tint_color(base, (B_NO_TINT + B_LIGHTEN_1_TINT) / 2.0); 2832 lighten2 = tint_color(base, B_LIGHTEN_1_TINT); 2833 } 2834 2835 // fill background 2836 view->SetHighColor(base); 2837 view->FillRect(rect); 2838 2839 // draw shadow lines around bottom and right sides 2840 view->BeginLineArray(6); 2841 2842 // bottom below item text, darker then BMenuBar 2843 // would normaly draw it 2844 view->AddLine(BPoint(rect.left, rect.bottom), 2845 BPoint(rect.left - 1, rect.bottom), darken4); 2846 2847 // bottom below popup marker 2848 view->AddLine(BPoint(rect.left, rect.bottom), 2849 BPoint(rect.right, rect.bottom), darken4); 2850 // right of popup marker 2851 view->AddLine(BPoint(rect.right, rect.bottom - 1), 2852 BPoint(rect.right, rect.top), darken4); 2853 // top above popup marker 2854 view->AddLine(BPoint(rect.left, rect.top), 2855 BPoint(rect.right - 2, rect.top), lighten2); 2856 2857 rect.top += 1; 2858 rect.bottom -= 1; 2859 rect.right -= 1; 2860 2861 // bottom below popup marker 2862 view->AddLine(BPoint(rect.left, rect.bottom), 2863 BPoint(rect.right, rect.bottom), darken1); 2864 // right of popup marker 2865 view->AddLine(BPoint(rect.right, rect.bottom - 1), 2866 BPoint(rect.right, rect.top), darken1); 2867 2868 view->EndLineArray(); 2869 2870 rect.bottom -= 1; 2871 rect.right -= 1; 2872 view->SetHighColor(base); 2873 view->FillRect(rect); 2874 2875 view->PopState(); 2876 } 2877 2878 2879 void 2880 BeControlLook::_DrawScrollBarBackgroundFirst(BView* view, BRect& rect, 2881 const BRect& updateRect, const rgb_color& base, uint32 flags, 2882 orientation orientation) 2883 { 2884 if (!ShouldDraw(view, rect, updateRect)) 2885 return; 2886 2887 view->PushState(); 2888 2889 view->ClipToRect(rect); 2890 2891 bool isEnabled = (flags & B_DISABLED) == 0; 2892 BRect orig(rect); 2893 2894 // border = 152 2895 rgb_color border = tint_color(base, B_DARKEN_2_TINT); 2896 rgb_color shine, shadow, bg; 2897 if (isEnabled) { 2898 // shine = 216, shadow = 184, bg = 200 2899 shine = base; 2900 shadow = tint_color(base, B_DARKEN_1_TINT); 2901 bg = tint_color(base, 1.074); 2902 } else { 2903 // shine = 255, shadow = bg = 240 2904 shine = tint_color(base, B_LIGHTEN_MAX_TINT); 2905 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 2906 lighten2.red++; lighten2.green++; lighten2.blue++; 2907 // lighten2 = 239, 240 = 239 + 1 2908 shadow = bg = lighten2; 2909 } 2910 2911 // fill background, we'll draw arrows and thumb on top 2912 view->SetDrawingMode(B_OP_COPY); 2913 2914 view->BeginLineArray(5); 2915 if (orientation == B_VERTICAL) { 2916 // left shadow 2917 view->AddLine(rect.LeftTop(), rect.LeftBottom(), 2918 isEnabled ? shadow : shine); 2919 rect.left++; 2920 view->AddLine(rect.LeftTop(), rect.LeftBottom(), shadow); 2921 rect.left++; 2922 // top shadow 2923 view->AddLine(rect.LeftTop(), rect.RightTop(), 2924 isEnabled ? shadow : shine); 2925 rect.top++; 2926 view->AddLine(rect.LeftTop(), rect.RightTop(), shadow); 2927 rect.top++; 2928 // shine 2929 view->AddLine(rect.RightTop(), rect.RightBottom(), base); 2930 rect.right--; 2931 } else { 2932 // left shadow 2933 view->AddLine(rect.LeftTop(), rect.LeftBottom(), shadow); 2934 rect.left++; 2935 view->AddLine(rect.LeftTop(), rect.LeftBottom(), shadow); 2936 rect.left++; 2937 // top shadow 2938 view->AddLine(rect.LeftTop(), rect.RightTop(), shadow); 2939 rect.top++; 2940 view->AddLine(rect.LeftTop(), rect.RightTop(), shadow); 2941 rect.top++; 2942 // shine 2943 view->AddLine(rect.LeftBottom(), rect.RightBottom(), base); 2944 rect.bottom--; 2945 } 2946 view->EndLineArray(); 2947 2948 // fill bg 2949 view->SetHighColor(bg); 2950 view->FillRect(rect); 2951 2952 rect = orig; 2953 2954 // draw border last 2955 view->BeginLineArray(2); 2956 if (orientation == B_VERTICAL) { 2957 // top border 2958 view->AddLine(rect.LeftTop(), rect.RightTop(), border); 2959 // bottom border 2960 view->AddLine(rect.LeftBottom(), rect.RightBottom(), border); 2961 } else { 2962 // left border 2963 view->AddLine(rect.LeftTop(), rect.LeftBottom(), border); 2964 // right border 2965 view->AddLine(rect.RightTop(), rect.RightBottom(), border); 2966 } 2967 view->EndLineArray(); 2968 2969 view->PopState(); 2970 } 2971 2972 2973 void 2974 BeControlLook::_DrawScrollBarBackgroundSecond(BView* view, BRect& rect, 2975 const BRect& updateRect, const rgb_color& base, uint32 flags, 2976 orientation orientation) 2977 { 2978 if (!ShouldDraw(view, rect, updateRect)) 2979 return; 2980 2981 view->PushState(); 2982 2983 view->ClipToRect(rect); 2984 2985 bool isEnabled = (flags & B_DISABLED) == 0; 2986 2987 BRect orig(rect); 2988 2989 // border = 152 2990 rgb_color border = tint_color(base, B_DARKEN_2_TINT); 2991 rgb_color darkBorder, shine, shadow, bg; 2992 if (isEnabled) { 2993 // darkBorder = 96 shine = 216, shadow = 184, bg = 200 2994 darkBorder = tint_color(base, B_DARKEN_4_TINT); 2995 shine = base; 2996 shadow = tint_color(base, B_DARKEN_1_TINT); 2997 bg = tint_color(base, 1.074); 2998 } else { 2999 // darkBorder = 184, shine = 255, shadow = bg = 240 3000 darkBorder = tint_color(base, B_DARKEN_1_TINT); 3001 shine = tint_color(base, B_LIGHTEN_MAX_TINT); 3002 rgb_color lighten2 = tint_color(base, B_LIGHTEN_2_TINT); 3003 lighten2.red++; lighten2.green++; lighten2.blue++; 3004 // lighten2 = 239, 240 = 239 + 1 3005 shadow = bg = lighten2; 3006 } 3007 3008 // fill background, we'll draw arrows and thumb on top 3009 view->SetDrawingMode(B_OP_COPY); 3010 3011 view->BeginLineArray(3); 3012 if (orientation == B_VERTICAL) { 3013 // left shadow (no top shadow on second rect) 3014 view->AddLine(rect.LeftTop(), rect.LeftBottom(), 3015 isEnabled ? shadow : shine); 3016 rect.left++; 3017 view->AddLine(rect.LeftTop(), rect.LeftBottom(), shadow); 3018 rect.left++; 3019 // shine (use base color) 3020 view->AddLine(rect.RightTop(), rect.RightBottom(), base); 3021 rect.right--; 3022 } else { 3023 // left shadow (no top shadow on second rect) 3024 view->AddLine(rect.LeftTop(), rect.RightTop(), 3025 isEnabled ? shadow : shine); 3026 rect.top++; 3027 view->AddLine(rect.LeftTop(), rect.RightTop(), shadow); 3028 rect.top++; 3029 // shine (use base color) 3030 view->AddLine(rect.LeftBottom(), rect.RightBottom(), base); 3031 rect.bottom--; 3032 } 3033 view->EndLineArray(); 3034 3035 // fill bg 3036 view->SetHighColor(bg); 3037 view->FillRect(rect); 3038 3039 rect = orig; 3040 3041 // draw border over bg 3042 view->BeginLineArray(2); 3043 if (orientation == B_VERTICAL) { 3044 // top border 3045 view->AddLine(rect.LeftTop(), rect.RightTop(), darkBorder); 3046 // bottom border 3047 view->AddLine(rect.LeftBottom(), rect.RightBottom(), border); 3048 } else { 3049 // left border 3050 view->AddLine(rect.LeftTop(), rect.LeftBottom(), darkBorder); 3051 // right border 3052 view->AddLine(rect.RightTop(), rect.RightBottom(), border); 3053 } 3054 view->EndLineArray(); 3055 3056 view->PopState(); 3057 } 3058 3059 void 3060 BeControlLook::_DrawScrollBarKnobDot(BView* view, 3061 float hcenter, float vmiddle, rgb_color dark, rgb_color light, 3062 orientation orientation) 3063 { 3064 // orientation is unused 3065 view->BeginLineArray(4); 3066 view->AddLine(BPoint(hcenter + 2, vmiddle - 2), 3067 BPoint(hcenter + 2, vmiddle + 2), dark); 3068 view->AddLine(BPoint(hcenter + 2, vmiddle + 2), 3069 BPoint(hcenter - 2, vmiddle + 2), dark); 3070 view->AddLine(BPoint(hcenter - 2, vmiddle + 1), 3071 BPoint(hcenter - 2, vmiddle - 1), light); 3072 view->AddLine(BPoint(hcenter - 2, vmiddle - 1), 3073 BPoint(hcenter - 2, vmiddle + 1), light); 3074 view->EndLineArray(); 3075 } 3076 3077 3078 void 3079 BeControlLook::_DrawScrollBarKnobLine(BView* view, 3080 float hcenter, float vmiddle, rgb_color dark, rgb_color light, 3081 orientation orientation) 3082 { 3083 if (orientation == B_HORIZONTAL) { 3084 view->BeginLineArray(4); 3085 view->AddLine(BPoint(hcenter, vmiddle + 3), 3086 BPoint(hcenter + 1, vmiddle + 3), dark); 3087 view->AddLine(BPoint(hcenter + 1, vmiddle + 3), 3088 BPoint(hcenter + 1, vmiddle - 3), dark); 3089 view->AddLine(BPoint(hcenter, vmiddle - 3), 3090 BPoint(hcenter - 1, vmiddle - 3), light); 3091 view->AddLine(BPoint(hcenter - 1, vmiddle - 3), 3092 BPoint(hcenter - 1, vmiddle + 3), light); 3093 view->EndLineArray(); 3094 } else { 3095 view->BeginLineArray(4); 3096 view->AddLine(BPoint(hcenter + 3, vmiddle), 3097 BPoint(hcenter + 3, vmiddle + 1), dark); 3098 view->AddLine(BPoint(hcenter + 3, vmiddle + 1), 3099 BPoint(hcenter - 3, vmiddle + 1), dark); 3100 view->AddLine(BPoint(hcenter - 3, vmiddle), 3101 BPoint(hcenter - 3, vmiddle - 1), light); 3102 view->AddLine(BPoint(hcenter - 3, vmiddle - 1), 3103 BPoint(hcenter + 3, vmiddle - 1), light); 3104 view->EndLineArray(); 3105 } 3106 } 3107 3108 3109 void 3110 BeControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, 3111 const rgb_color& top, const rgb_color& right, const rgb_color& bottom, 3112 uint32 borders) 3113 { 3114 view->BeginLineArray(4); 3115 3116 // draw in reverse so that bottom and right corners cover top and left 3117 3118 if ((borders & B_BOTTOM_BORDER) != 0) { 3119 view->AddLine( 3120 BPoint(rect.left, rect.bottom), 3121 BPoint(rect.right, rect.bottom), bottom); 3122 rect.bottom--; 3123 } 3124 if ((borders & B_RIGHT_BORDER) != 0) { 3125 view->AddLine( 3126 BPoint(rect.right, rect.top), 3127 BPoint(rect.right, rect.bottom), right); 3128 rect.right--; 3129 } 3130 if ((borders & B_TOP_BORDER) != 0) { 3131 view->AddLine( 3132 BPoint(rect.left, rect.top), 3133 BPoint(rect.right, rect.top), top); 3134 rect.top++; 3135 } 3136 if ((borders & B_LEFT_BORDER) != 0) { 3137 view->AddLine( 3138 BPoint(rect.left, rect.bottom), 3139 BPoint(rect.left, rect.top), left); 3140 rect.left++; 3141 } 3142 3143 view->EndLineArray(); 3144 } 3145 3146 } // namespace BPrivate 3147 3148 3149 extern "C" BControlLook* (instantiate_control_look)(image_id id) 3150 { 3151 return new (std::nothrow)BPrivate::BeControlLook(id); 3152 } 3153