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