1 /* 2 * Copyright 2001-2005, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Marc Flerackers (mflerackers@androme.be) 7 * Mike Wilber 8 * Stefano Ceccherini (burton666@libero.it) 9 * Ivan Tonizza 10 * Stephan Aßmus, <superstippi@gmx.de> 11 */ 12 13 14 #include <Button.h> 15 #include <Font.h> 16 #include <String.h> 17 #include <Window.h> 18 19 20 BButton::BButton(BRect frame, const char *name, const char *label, BMessage *message, 21 uint32 resizingMode, uint32 flags) 22 : BControl(frame, name, label, message, resizingMode, flags | B_WILL_DRAW), 23 fDrawAsDefault(false) 24 { 25 // Resize to minimum height if needed 26 font_height fh; 27 GetFontHeight(&fh); 28 float minHeight = 12.0f + (float)ceil(fh.ascent + fh.descent); 29 if (Bounds().Height() < minHeight) 30 ResizeTo(Bounds().Width(), minHeight); 31 } 32 33 34 BButton::~BButton() 35 { 36 } 37 38 39 BButton::BButton(BMessage *archive) 40 : BControl (archive) 41 { 42 if (archive->FindBool("_default", &fDrawAsDefault) != B_OK) 43 fDrawAsDefault = false; 44 } 45 46 47 BArchivable * 48 BButton::Instantiate(BMessage *archive) 49 { 50 if (validate_instantiation(archive, "BButton")) 51 return new BButton(archive); 52 53 return NULL; 54 } 55 56 57 status_t 58 BButton::Archive(BMessage* archive, bool deep) const 59 { 60 status_t err = BControl::Archive(archive, deep); 61 62 if (err != B_OK) 63 return err; 64 65 if (IsDefault()) 66 err = archive->AddBool("_default", true); 67 68 return err; 69 } 70 71 72 void 73 BButton::Draw(BRect updateRect) 74 { 75 font_height fh; 76 GetFontHeight(&fh); 77 78 const BRect bounds = Bounds(); 79 BRect rect = bounds; 80 81 const bool enabled = IsEnabled(); 82 const bool pushed = Value() == B_CONTROL_ON; 83 #if 0 84 // Default indicator 85 if (IsDefault()) 86 rect = DrawDefault(rect, enabled); 87 else 88 rect.InsetBy(1.0f, 1.0f); 89 90 BRect fillArea = rect; 91 fillArea.InsetBy(3.0f, 3.0f); 92 93 BString text = Label(); 94 95 #if 1 96 // Label truncation 97 BFont font; 98 GetFont(&font); 99 font.TruncateString(&text, B_TRUNCATE_END, fillArea.Width()); 100 #endif 101 102 // Label position 103 const float stringWidth = StringWidth(text.String()); 104 const float x = (bounds.right - stringWidth) / 2.0f; 105 const float labelY = bounds.top 106 + ((bounds.Height() - fh.ascent - fh.descent) / 2.0f) 107 + fh.ascent + 1.0f; 108 const float focusLineY = labelY + fh.descent; 109 110 /* speed trick: 111 if the focus changes but the button is not pressed then we can 112 redraw only the focus line, 113 if the focus changes and the button is pressed invert the internal rect 114 this block takes care of all the focus changes 115 */ 116 if (IsFocusChanging()) { 117 if (pushed) { 118 rect.InsetBy(2.0, 2.0); 119 InvertRect(rect); 120 } else 121 DrawFocusLine(x, focusLineY, stringWidth, IsFocus() && Window()->IsActive()); 122 123 return; 124 } 125 126 // Colors 127 const rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR); 128 const rgb_color buttonBgColor=tint_color(panelBgColor, B_LIGHTEN_1_TINT); 129 const rgb_color maxLightColor=tint_color(panelBgColor, B_LIGHTEN_MAX_TINT); 130 const rgb_color maxShadowColor=tint_color(panelBgColor, B_DARKEN_MAX_TINT); 131 const rgb_color darkBorderColor = tint_color(panelBgColor, 132 enabled ? B_DARKEN_4_TINT : B_DARKEN_2_TINT); 133 const rgb_color firstBevelColor = enabled ? tint_color(panelBgColor, B_DARKEN_2_TINT) 134 : panelBgColor; 135 const rgb_color cornerColor = IsDefault() ? firstBevelColor : panelBgColor; 136 137 // Fill the button area 138 SetHighColor(buttonBgColor); 139 FillRect(fillArea); 140 141 // external border 142 SetHighColor(darkBorderColor); 143 StrokeRect(rect); 144 145 BeginLineArray(14); 146 147 // Corners 148 AddLine(rect.LeftTop(), rect.LeftTop(), cornerColor); 149 AddLine(rect.LeftBottom(), rect.LeftBottom(), cornerColor); 150 AddLine(rect.RightTop(), rect.RightTop(), cornerColor); 151 AddLine(rect.RightBottom(), rect.RightBottom(), cornerColor); 152 153 rect.InsetBy(1.0f,1.0f); 154 155 // Shadow 156 AddLine(rect.LeftBottom(), rect.RightBottom(), firstBevelColor); 157 AddLine(rect.RightBottom(), rect.RightTop(), firstBevelColor); 158 // Light 159 AddLine(rect.LeftTop(), rect.LeftBottom(),buttonBgColor); 160 AddLine(rect.LeftTop(), rect.RightTop(), buttonBgColor); 161 162 rect.InsetBy(1.0f, 1.0f); 163 164 // Shadow 165 AddLine(rect.LeftBottom(), rect.RightBottom(), panelBgColor); 166 AddLine(rect.RightBottom(), rect.RightTop(), panelBgColor); 167 // Light 168 AddLine(rect.LeftTop(), rect.LeftBottom(),maxLightColor); 169 AddLine(rect.LeftTop(), rect.RightTop(), maxLightColor); 170 171 rect.InsetBy(1.0f,1.0f); 172 173 // Light 174 AddLine(rect.LeftTop(), rect.LeftBottom(),maxLightColor); 175 AddLine(rect.LeftTop(), rect.RightTop(), maxLightColor); 176 177 EndLineArray(); 178 179 // Invert if clicked 180 if (enabled && pushed) { 181 rect.InsetBy(-2.0f, -2.0f); 182 InvertRect(rect); 183 } 184 185 // Label color 186 if (enabled) { 187 if (pushed) { 188 SetHighColor(maxLightColor); 189 SetLowColor(maxShadowColor); 190 } else { 191 SetHighColor(maxShadowColor); 192 SetLowColor(tint_color(panelBgColor, B_LIGHTEN_2_TINT)); 193 } 194 } else { 195 SetHighColor(tint_color(panelBgColor, B_DISABLED_LABEL_TINT)); 196 SetLowColor(tint_color(panelBgColor, B_LIGHTEN_2_TINT)); 197 } 198 199 // Draw the label 200 DrawString(text.String(), BPoint(x, labelY)); 201 202 // Focus line 203 if (enabled && IsFocus() && Window()->IsActive() && !pushed) 204 DrawFocusLine(x,focusLineY,stringWidth,true); 205 #else 206 // Default indicator 207 if (IsDefault()) 208 rect = DrawDefault(rect, enabled); 209 210 BRect fillArea = rect; 211 fillArea.InsetBy(3.0, 3.0); 212 213 BString text = Label(); 214 215 #if 1 216 // Label truncation 217 BFont font; 218 GetFont(&font); 219 font.TruncateString(&text, B_TRUNCATE_END, fillArea.Width() - 4); 220 #endif 221 222 // Label position 223 const float stringWidth = StringWidth(text.String()); 224 const float x = (rect.right - stringWidth) / 2.0; 225 const float labelY = bounds.top 226 + ((bounds.Height() - fh.ascent - fh.descent) / 2.0) 227 + fh.ascent + 1.0; 228 const float focusLineY = labelY + fh.descent; 229 230 /* speed trick: 231 if the focus changes but the button is not pressed then we can 232 redraw only the focus line, 233 if the focus changes and the button is pressed invert the internal rect 234 this block takes care of all the focus changes 235 */ 236 if (IsFocusChanging()) { 237 if (pushed) { 238 rect.InsetBy(2.0, 2.0); 239 InvertRect(rect); 240 } else 241 DrawFocusLine(x, focusLineY, stringWidth, IsFocus() && Window()->IsActive()); 242 243 return; 244 } 245 246 // colors 247 rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR); 248 rgb_color buttonBgColor = tint_color(panelBgColor, B_LIGHTEN_1_TINT); 249 rgb_color lightColor; 250 rgb_color maxLightColor; 251 rgb_color maxShadowColor = tint_color(panelBgColor, B_DARKEN_MAX_TINT); 252 253 rgb_color dark1BorderColor; 254 rgb_color dark2BorderColor; 255 256 rgb_color bevelColor1; 257 rgb_color bevelColor2; 258 rgb_color bevelColorRBCorner; 259 260 rgb_color borderBevelShadow; 261 rgb_color borderBevelLight; 262 263 if (enabled) { 264 lightColor = tint_color(panelBgColor, B_LIGHTEN_2_TINT); 265 maxLightColor = tint_color(panelBgColor, B_LIGHTEN_MAX_TINT); 266 267 dark1BorderColor = tint_color(panelBgColor, B_DARKEN_3_TINT); 268 dark2BorderColor = tint_color(panelBgColor, B_DARKEN_4_TINT); 269 270 bevelColor1 = tint_color(panelBgColor, B_DARKEN_2_TINT); 271 bevelColor2 = panelBgColor; 272 273 if (IsDefault()) { 274 borderBevelShadow = tint_color(dark1BorderColor, (B_NO_TINT + B_DARKEN_1_TINT) / 2); 275 borderBevelLight = tint_color(dark1BorderColor, B_LIGHTEN_1_TINT); 276 277 borderBevelLight.red = (borderBevelLight.red + panelBgColor.red) / 2; 278 borderBevelLight.green = (borderBevelLight.green + panelBgColor.green) / 2; 279 borderBevelLight.blue = (borderBevelLight.blue + panelBgColor.blue) / 2; 280 281 dark1BorderColor = tint_color(dark1BorderColor, B_DARKEN_3_TINT); 282 dark2BorderColor = tint_color(dark1BorderColor, B_DARKEN_4_TINT); 283 284 bevelColorRBCorner = borderBevelShadow; 285 } else { 286 borderBevelShadow = tint_color(panelBgColor, (B_NO_TINT + B_DARKEN_1_TINT) / 2); 287 borderBevelLight = buttonBgColor; 288 289 bevelColorRBCorner = dark1BorderColor; 290 } 291 } else { 292 lightColor = tint_color(panelBgColor, B_LIGHTEN_2_TINT); 293 maxLightColor = tint_color(panelBgColor, B_LIGHTEN_1_TINT); 294 295 dark1BorderColor = tint_color(panelBgColor, B_DARKEN_1_TINT); 296 dark2BorderColor = tint_color(panelBgColor, B_DARKEN_2_TINT); 297 298 bevelColor1 = panelBgColor; 299 bevelColor2 = buttonBgColor; 300 301 if (IsDefault()) { 302 borderBevelShadow = dark1BorderColor; 303 borderBevelLight = panelBgColor; 304 dark1BorderColor = tint_color(dark1BorderColor, B_DARKEN_1_TINT); 305 dark2BorderColor = tint_color(dark1BorderColor, 1.16); 306 307 } else { 308 borderBevelShadow = panelBgColor; 309 borderBevelLight = panelBgColor; 310 } 311 312 bevelColorRBCorner = tint_color(panelBgColor, 1.08);; 313 } 314 315 // fill the button area 316 SetHighColor(buttonBgColor); 317 FillRect(fillArea); 318 319 BeginLineArray(22); 320 // bevel around external border 321 AddLine(BPoint(rect.left, rect.bottom), 322 BPoint(rect.left, rect.top), borderBevelShadow); 323 AddLine(BPoint(rect.left + 1, rect.top), 324 BPoint(rect.right, rect.top), borderBevelShadow); 325 326 AddLine(BPoint(rect.right, rect.top + 1), 327 BPoint(rect.right, rect.bottom), borderBevelLight); 328 AddLine(BPoint(rect.left + 1, rect.bottom), 329 BPoint(rect.right - 1, rect.bottom), borderBevelLight); 330 331 rect.InsetBy(1.0, 1.0); 332 333 // external border 334 AddLine(BPoint(rect.left, rect.bottom), 335 BPoint(rect.left, rect.top), dark1BorderColor); 336 AddLine(BPoint(rect.left + 1, rect.top), 337 BPoint(rect.right, rect.top), dark1BorderColor); 338 AddLine(BPoint(rect.right, rect.top + 1), 339 BPoint(rect.right, rect.bottom), dark2BorderColor); 340 AddLine(BPoint(rect.right - 1, rect.bottom), 341 BPoint(rect.left + 1, rect.bottom), dark2BorderColor); 342 343 rect.InsetBy(1.0, 1.0); 344 345 // Light 346 AddLine(BPoint(rect.left, rect.top), 347 BPoint(rect.left, rect.top), buttonBgColor); 348 AddLine(BPoint(rect.left, rect.top + 1), 349 BPoint(rect.left, rect.bottom - 1), lightColor); 350 AddLine(BPoint(rect.left, rect.bottom), 351 BPoint(rect.left, rect.bottom), bevelColor2); 352 AddLine(BPoint(rect.left + 1, rect.top), 353 BPoint(rect.right - 1, rect.top), lightColor); 354 AddLine(BPoint(rect.right, rect.top), 355 BPoint(rect.right, rect.top), bevelColor2); 356 // Shadow 357 AddLine(BPoint(rect.left + 1, rect.bottom), 358 BPoint(rect.right - 1, rect.bottom), bevelColor1); 359 AddLine(BPoint(rect.right, rect.bottom), 360 BPoint(rect.right, rect.bottom), bevelColorRBCorner); 361 AddLine(BPoint(rect.right, rect.bottom - 1), 362 BPoint(rect.right, rect.top + 1), bevelColor1); 363 364 rect.InsetBy(1.0, 1.0); 365 366 // Light 367 AddLine(BPoint(rect.left, rect.top), 368 BPoint(rect.left, rect.bottom - 1), maxLightColor); 369 AddLine(BPoint(rect.left, rect.bottom), 370 BPoint(rect.left, rect.bottom), buttonBgColor); 371 AddLine(BPoint(rect.left + 1, rect.top), 372 BPoint(rect.right - 1, rect.top), maxLightColor); 373 AddLine(BPoint(rect.right, rect.top), 374 BPoint(rect.right, rect.top), buttonBgColor); 375 // Shadow 376 AddLine(BPoint(rect.left + 1, rect.bottom), 377 BPoint(rect.right, rect.bottom), bevelColor2); 378 AddLine(BPoint(rect.right, rect.bottom - 1), 379 BPoint(rect.right, rect.top + 1), bevelColor2); 380 381 rect.InsetBy(1.0,1.0); 382 383 EndLineArray(); 384 385 // Invert if clicked 386 if (enabled && pushed) { 387 rect.InsetBy(-2.0, -2.0); 388 InvertRect(rect); 389 } 390 391 // Label color 392 if (enabled) { 393 if (pushed) { 394 SetHighColor(maxLightColor); 395 SetLowColor(255 - buttonBgColor.red, 396 255 - buttonBgColor.green, 397 255 - buttonBgColor.blue); 398 } else { 399 SetHighColor(maxShadowColor); 400 SetLowColor(buttonBgColor); 401 } 402 } else { 403 SetHighColor(tint_color(panelBgColor, B_DISABLED_LABEL_TINT)); 404 SetLowColor(buttonBgColor); 405 } 406 407 // Draw the label 408 DrawString(text.String(), BPoint(x, labelY)); 409 410 // Focus line 411 if (enabled && IsFocus() && Window()->IsActive() && !pushed) 412 DrawFocusLine(x, focusLineY, stringWidth, true); 413 #endif 414 } 415 416 417 void 418 BButton::MouseDown(BPoint point) 419 { 420 if (!IsEnabled()) 421 return; 422 423 SetValue(B_CONTROL_ON); 424 425 if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) { 426 SetTracking(true); 427 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); 428 } else { 429 BRect bounds = Bounds(); 430 uint32 buttons; 431 432 do { 433 Window()->UpdateIfNeeded(); 434 snooze(40000); 435 436 GetMouse(&point, &buttons, true); 437 438 bool inside = bounds.Contains(point); 439 440 if ((Value() == B_CONTROL_ON) != inside) 441 SetValue(inside ? B_CONTROL_ON : B_CONTROL_OFF); 442 } while (buttons != 0); 443 444 if (Value() == B_CONTROL_ON) 445 Invoke(); 446 } 447 } 448 449 450 void 451 BButton::AttachedToWindow() 452 { 453 BControl::AttachedToWindow(); 454 // low color will now be the parents view color 455 456 if (IsDefault()) 457 Window()->SetDefaultButton(this); 458 459 SetViewColor(B_TRANSPARENT_COLOR); 460 } 461 462 463 void 464 BButton::KeyDown(const char *bytes, int32 numBytes) 465 { 466 if (*bytes == B_ENTER || *bytes == B_SPACE) { 467 if (!IsEnabled()) 468 return; 469 470 SetValue(B_CONTROL_ON); 471 472 // make sure the user saw that 473 Window()->UpdateIfNeeded(); 474 snooze(25000); 475 476 Invoke(); 477 478 } else 479 BControl::KeyDown(bytes, numBytes); 480 } 481 482 483 void 484 BButton::MakeDefault(bool flag) 485 { 486 BButton *oldDefault = NULL; 487 BWindow *window = Window(); 488 489 if (window) 490 oldDefault = window->DefaultButton(); 491 492 if (flag) { 493 if (fDrawAsDefault && oldDefault == this) 494 return; 495 496 if (!fDrawAsDefault) { 497 fDrawAsDefault = true; 498 499 ResizeBy(6.0f, 6.0f); 500 MoveBy(-3.0f, -3.0f); 501 } 502 503 if (window && oldDefault != this) 504 window->SetDefaultButton(this); 505 } else { 506 if (!fDrawAsDefault) 507 return; 508 509 fDrawAsDefault = false; 510 511 ResizeBy(-6.0f, -6.0f); 512 MoveBy(3.0f, 3.0f); 513 514 if (window && oldDefault == this) 515 window->SetDefaultButton(NULL); 516 } 517 } 518 519 520 void 521 BButton::SetLabel(const char *string) 522 { 523 BControl::SetLabel(string); 524 } 525 526 527 bool 528 BButton::IsDefault() const 529 { 530 return fDrawAsDefault; 531 } 532 533 534 void 535 BButton::MessageReceived(BMessage *message) 536 { 537 BControl::MessageReceived(message); 538 } 539 540 541 void 542 BButton::WindowActivated(bool active) 543 { 544 BControl::WindowActivated(active); 545 } 546 547 548 void 549 BButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message) 550 { 551 if (!IsTracking()) 552 return; 553 554 bool inside = Bounds().Contains(point); 555 556 if ((Value() == B_CONTROL_ON) != inside) 557 SetValue(inside ? B_CONTROL_ON : B_CONTROL_OFF); 558 } 559 560 561 void 562 BButton::MouseUp(BPoint point) 563 { 564 if (!IsTracking()) 565 return; 566 567 if (Bounds().Contains(point)) 568 Invoke(); 569 570 SetTracking(false); 571 } 572 573 574 void 575 BButton::DetachedFromWindow() 576 { 577 BControl::DetachedFromWindow(); 578 } 579 580 581 void 582 BButton::SetValue(int32 value) 583 { 584 if (value != Value()) 585 BControl::SetValue(value); 586 } 587 588 589 void 590 BButton::GetPreferredSize(float *_width, float *_height) 591 { 592 if (_height) { 593 font_height fontHeight; 594 GetFontHeight(&fontHeight); 595 596 // *_height = 12.0f + ceilf(fontHeight.ascent + fontHeight.descent) 597 *_height = ceilf((fontHeight.ascent + fontHeight.descent) * 1.8) 598 + (fDrawAsDefault ? 6.0f : 0); 599 } 600 601 if (_width) { 602 float width = 20.0f + (float)ceil(StringWidth(Label())); 603 if (width < 75.0f) 604 width = 75.0f; 605 606 if (fDrawAsDefault) 607 width += 6.0f; 608 609 *_width = width; 610 } 611 } 612 613 614 void 615 BButton::ResizeToPreferred() 616 { 617 BControl::ResizeToPreferred(); 618 } 619 620 621 status_t 622 BButton::Invoke(BMessage *message) 623 { 624 Sync(); 625 snooze(50000); 626 627 status_t err = BControl::Invoke(message); 628 629 SetValue(B_CONTROL_OFF); 630 631 return err; 632 } 633 634 635 void 636 BButton::FrameMoved(BPoint newLocation) 637 { 638 BControl::FrameMoved(newLocation); 639 } 640 641 642 void 643 BButton::FrameResized(float width, float height) 644 { 645 BControl::FrameResized(width, height); 646 } 647 648 649 void 650 BButton::MakeFocus(bool focused) 651 { 652 BControl::MakeFocus(focused); 653 } 654 655 656 void 657 BButton::AllAttached() 658 { 659 BControl::AllAttached(); 660 } 661 662 663 void 664 BButton::AllDetached() 665 { 666 BControl::AllDetached(); 667 } 668 669 670 BHandler * 671 BButton::ResolveSpecifier(BMessage *message, int32 index, 672 BMessage *specifier, int32 what, 673 const char *property) 674 { 675 return BControl::ResolveSpecifier(message, index, specifier, what, property); 676 } 677 678 679 status_t 680 BButton::GetSupportedSuites(BMessage *message) 681 { 682 return BControl::GetSupportedSuites(message); 683 } 684 685 686 status_t 687 BButton::Perform(perform_code d, void *arg) 688 { 689 return BControl::Perform(d, arg); 690 } 691 692 693 void BButton::_ReservedButton1() {} 694 void BButton::_ReservedButton2() {} 695 void BButton::_ReservedButton3() {} 696 697 698 BButton & 699 BButton::operator=(const BButton &) 700 { 701 return *this; 702 } 703 704 705 BRect 706 BButton::DrawDefault(BRect bounds, bool enabled) 707 { 708 #if 0 709 rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), 710 lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), 711 darken1 = tint_color(no_tint, B_DARKEN_1_TINT); 712 713 rgb_color borderColor; 714 if (enabled) 715 borderColor = tint_color(no_tint, B_DARKEN_4_TINT); 716 else 717 borderColor = darken1; 718 719 // Dark border 720 BeginLineArray(4); 721 AddLine(BPoint(bounds.left, bounds.bottom - 1.0f), 722 BPoint(bounds.left, bounds.top + 1.0f), borderColor); 723 AddLine(BPoint(bounds.left + 1.0f, bounds.top), 724 BPoint(bounds.right - 1.0f, bounds.top), borderColor); 725 AddLine(BPoint(bounds.right, bounds.top + 1.0f), 726 BPoint(bounds.right, bounds.bottom - 1.0f), borderColor); 727 AddLine(BPoint(bounds.left + 1.0f, bounds.bottom), 728 BPoint(bounds.right - 1.0f, bounds.bottom), borderColor); 729 EndLineArray(); 730 731 if (enabled) { 732 // Bevel 733 bounds.InsetBy(1.0f, 1.0f); 734 SetHighColor(darken1); 735 StrokeRect(bounds); 736 } 737 738 bounds.InsetBy(1.0f, 1.0f); 739 740 // Filling 741 float inset = enabled? 2.0f : 3.0f; 742 SetHighColor(lighten1); 743 744 FillRect(BRect(bounds.left, bounds.top, 745 bounds.right, bounds.top+inset-1.0f)); 746 FillRect(BRect(bounds.left, bounds.bottom-inset+1.0f, 747 bounds.right, bounds.bottom)); 748 FillRect(BRect(bounds.left, bounds.top+inset-1.0f, 749 bounds.left+inset-1.0f, bounds.bottom-inset+1.0f)); 750 FillRect(BRect(bounds.right-inset+1.0f, bounds.top+inset-1.0f, 751 bounds.right, bounds.bottom-inset+1.0f)); 752 753 bounds.InsetBy(inset,inset); 754 755 return bounds; 756 #else 757 rgb_color low = LowColor(); 758 rgb_color focusColor = tint_color(low, enabled ? (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2 759 : (B_NO_TINT + B_DARKEN_1_TINT) / 2); 760 761 SetHighColor(focusColor); 762 763 StrokeRect(bounds, B_SOLID_LOW); 764 bounds.InsetBy(1.0, 1.0); 765 StrokeRect(bounds); 766 bounds.InsetBy(1.0, 1.0); 767 StrokeRect(bounds); 768 bounds.InsetBy(1.0, 1.0); 769 770 return bounds; 771 #endif 772 } 773 774 775 status_t 776 BButton::Execute() 777 { 778 if (!IsEnabled()) 779 return B_ERROR; 780 781 SetValue(B_CONTROL_ON); 782 return Invoke(); 783 } 784 785 786 void 787 BButton::DrawFocusLine(float x, float y, float width, bool visible) 788 { 789 if (visible) 790 SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 791 else { 792 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 793 B_LIGHTEN_1_TINT)); 794 } 795 796 // Blue Line 797 StrokeLine(BPoint(x, y), BPoint(x + width, y)); 798 799 if (visible) 800 SetHighColor(255, 255, 255); 801 // White Line 802 StrokeLine(BPoint(x, y + 1.0f), BPoint(x + width, y + 1.0f)); 803 } 804