2 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de>
3 * Copyright 2012-2017 Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
7 * Stephan Aßmus, superstippi@gmx.de
8 * John Scipione, jscipione@gmail.com
12 #include <HaikuControlLook.h>
18 #include <GradientLinear.h>
19 #include <LayoutUtils.h>
25 #include <WindowPrivate.h>
31 static const float kEdgeBevelLightTint
= 0.59;
32 static const float kEdgeBevelShadowTint
= 1.0735;
33 static const float kHoverTintFactor
= 0.85;
35 static const float kButtonPopUpIndicatorWidth
= 11;
38 HaikuControlLook::HaikuControlLook()
45 HaikuControlLook::~HaikuControlLook()
51 HaikuControlLook::DefaultLabelAlignment() const
53 return BAlignment(B_ALIGN_LEFT
, B_ALIGN_VERTICAL_CENTER
);
58 HaikuControlLook::DefaultLabelSpacing() const
60 return ceilf(be_plain_font
->Size() / 2.0);
65 HaikuControlLook::DefaultItemSpacing() const
67 return ceilf(be_plain_font
->Size() * 0.85);
72 HaikuControlLook::Flags(BControl
* control
) const
74 uint32 flags
= B_IS_CONTROL
;
76 if (!control
->IsEnabled())
79 if (control
->IsFocus() && control
->Window() != NULL
80 && control
->Window()->IsActive()) {
84 switch (control
->Value()) {
88 case B_CONTROL_PARTIALLY_ON
:
89 flags
|= B_PARTIALLY_ACTIVATED
;
93 if (control
->Parent() != NULL
94 && (control
->Parent()->Flags() & B_DRAW_ON_CHILDREN
) != 0) {
95 // In this constellation, assume we want to render the control
96 // against the already existing view contents of the parent view.
97 flags
|= B_BLEND_FRAME
;
108 HaikuControlLook::DrawButtonFrame(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
109 const rgb_color
& base
, const rgb_color
& background
, uint32 flags
,
112 _DrawButtonFrame(view
, rect
, updateRect
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, base
,
113 background
, 1.0, 1.0, flags
, borders
);
118 HaikuControlLook::DrawButtonFrame(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
119 float radius
, const rgb_color
& base
, const rgb_color
& background
, uint32 flags
,
122 _DrawButtonFrame(view
, rect
, updateRect
, radius
, radius
, radius
, radius
,
123 base
, background
, 1.0, 1.0, flags
, borders
);
128 HaikuControlLook::DrawButtonFrame(BView
* view
, BRect
& rect
,
129 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
130 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
131 const rgb_color
& background
, uint32 flags
,
134 _DrawButtonFrame(view
, rect
, updateRect
, leftTopRadius
, rightTopRadius
,
135 leftBottomRadius
, rightBottomRadius
, base
, background
,
136 1.0, 1.0, flags
, borders
);
141 HaikuControlLook::DrawButtonBackground(BView
* view
, BRect
& rect
,
142 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
143 uint32 borders
, orientation orientation
)
145 _DrawButtonBackground(view
, rect
, updateRect
, 0.0f
, 0.0f
, 0.0f
, 0.0f
,
146 base
, false, flags
, borders
, orientation
);
151 HaikuControlLook::DrawButtonBackground(BView
* view
, BRect
& rect
,
152 const BRect
& updateRect
, float radius
, const rgb_color
& base
, uint32 flags
,
153 uint32 borders
, orientation orientation
)
155 _DrawButtonBackground(view
, rect
, updateRect
, radius
, radius
, radius
,
156 radius
, base
, false, flags
, borders
, orientation
);
161 HaikuControlLook::DrawButtonBackground(BView
* view
, BRect
& rect
,
162 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
163 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
164 uint32 flags
, uint32 borders
, orientation orientation
)
166 _DrawButtonBackground(view
, rect
, updateRect
, leftTopRadius
,
167 rightTopRadius
, leftBottomRadius
, rightBottomRadius
, base
, false, flags
,
168 borders
, orientation
);
173 HaikuControlLook::DrawMenuBarBackground(BView
* view
, BRect
& rect
,
174 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
177 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
186 if ((flags
& B_ACTIVATED
) != 0) {
187 rgb_color bevelColor1
= tint_color(base
, 1.40);
188 rgb_color bevelColor2
= tint_color(base
, 1.25);
193 _DrawFrame(view
, rect
,
194 bevelColor1
, bevelColor1
,
195 bevelColor2
, bevelColor2
,
196 borders
& B_TOP_BORDER
);
198 rgb_color cornerColor
= tint_color(base
, 0.9);
199 rgb_color bevelColorTop
= tint_color(base
, 0.5);
200 rgb_color bevelColorLeft
= tint_color(base
, 0.7);
201 rgb_color bevelColorRightBottom
= tint_color(base
, 1.08);
206 _DrawFrame(view
, rect
,
207 bevelColorLeft
, bevelColorTop
,
208 bevelColorRightBottom
, bevelColorRightBottom
,
209 cornerColor
, cornerColor
,
214 _FillGradient(view
, rect
, base
, topTint
, bottomTint
);
219 HaikuControlLook::DrawMenuFieldFrame(BView
* view
, BRect
& rect
,
220 const BRect
& updateRect
, const rgb_color
& base
,
221 const rgb_color
& background
, uint32 flags
, uint32 borders
)
223 _DrawButtonFrame(view
, rect
, updateRect
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, base
,
224 background
, 0.6, 1.0, flags
, borders
);
229 HaikuControlLook::DrawMenuFieldFrame(BView
* view
, BRect
& rect
,
230 const BRect
& updateRect
, float radius
, const rgb_color
& base
,
231 const rgb_color
& background
, uint32 flags
, uint32 borders
)
233 _DrawButtonFrame(view
, rect
, updateRect
, radius
, radius
, radius
, radius
,
234 base
, background
, 0.6, 1.0, flags
, borders
);
239 HaikuControlLook::DrawMenuFieldFrame(BView
* view
, BRect
& rect
,
240 const BRect
& updateRect
, float leftTopRadius
,
241 float rightTopRadius
, float leftBottomRadius
,
242 float rightBottomRadius
, const rgb_color
& base
,
243 const rgb_color
& background
, uint32 flags
, uint32 borders
)
245 _DrawButtonFrame(view
, rect
, updateRect
, leftTopRadius
, rightTopRadius
,
246 leftBottomRadius
, rightBottomRadius
, base
, background
, 0.6, 1.0,
252 HaikuControlLook::DrawMenuFieldBackground(BView
* view
, BRect
& rect
,
253 const BRect
& updateRect
, const rgb_color
& base
, bool popupIndicator
,
256 _DrawMenuFieldBackgroundOutside(view
, rect
, updateRect
,
257 0.0f
, 0.0f
, 0.0f
, 0.0f
, base
, popupIndicator
, flags
);
262 HaikuControlLook::DrawMenuFieldBackground(BView
* view
, BRect
& rect
,
263 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
266 _DrawMenuFieldBackgroundInside(view
, rect
, updateRect
,
267 0.0f
, 0.0f
, 0.0f
, 0.0f
, base
, flags
, borders
);
272 HaikuControlLook::DrawMenuFieldBackground(BView
* view
, BRect
& rect
,
273 const BRect
& updateRect
, float radius
, const rgb_color
& base
,
274 bool popupIndicator
, uint32 flags
)
276 _DrawMenuFieldBackgroundOutside(view
, rect
, updateRect
, radius
, radius
,
277 radius
, radius
, base
, popupIndicator
, flags
);
282 HaikuControlLook::DrawMenuFieldBackground(BView
* view
, BRect
& rect
,
283 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
284 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
285 bool popupIndicator
, uint32 flags
)
287 _DrawMenuFieldBackgroundOutside(view
, rect
, updateRect
, leftTopRadius
,
288 rightTopRadius
, leftBottomRadius
, rightBottomRadius
, base
,
289 popupIndicator
, flags
);
294 HaikuControlLook::DrawMenuBackground(BView
* view
, BRect
& rect
,
295 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
298 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
302 rgb_color background
= tint_color(base
, 0.75);
304 // inner bevel colors
305 rgb_color bevelLightColor
;
306 rgb_color bevelShadowColor
;
308 if ((flags
& B_DISABLED
) != 0) {
309 bevelLightColor
= tint_color(background
, 0.80);
310 bevelShadowColor
= tint_color(background
, 1.07);
312 bevelLightColor
= tint_color(background
, 0.6);
313 bevelShadowColor
= tint_color(background
, 1.12);
317 _DrawFrame(view
, rect
,
318 bevelLightColor
, bevelLightColor
,
319 bevelShadowColor
, bevelShadowColor
,
323 view
->SetHighColor(background
);
324 view
->FillRect(rect
);
329 HaikuControlLook::DrawMenuItemBackground(BView
* view
, BRect
& rect
,
330 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
333 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
339 rgb_color selectedColor
= base
;
341 if ((flags
& B_ACTIVATED
) != 0) {
344 } else if ((flags
& B_DISABLED
) != 0) {
352 rgb_color bevelLightColor
= tint_color(selectedColor
, topTint
);
353 rgb_color bevelShadowColor
= tint_color(selectedColor
, bottomTint
);
355 // draw surface edges
356 _DrawFrame(view
, rect
,
357 bevelLightColor
, bevelLightColor
,
358 bevelShadowColor
, bevelShadowColor
,
362 view
->SetLowColor(selectedColor
);
363 // _FillGradient(view, rect, selectedColor, topTint, bottomTint);
364 _FillGradient(view
, rect
, selectedColor
, bottomTint
, topTint
);
369 HaikuControlLook::DrawStatusBar(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
370 const rgb_color
& base
, const rgb_color
& barColor
, float progressPosition
)
372 if (!rect
.Intersects(updateRect
))
375 _DrawOuterResessedFrame(view
, rect
, base
, 0.6);
378 rgb_color dark1BorderColor
= tint_color(base
, 1.3);
379 rgb_color dark2BorderColor
= tint_color(base
, 1.2);
380 rgb_color dark1FilledBorderColor
= tint_color(barColor
, 1.20);
381 rgb_color dark2FilledBorderColor
= tint_color(barColor
, 1.45);
383 BRect
filledRect(rect
);
384 filledRect
.right
= progressPosition
- 1;
386 BRect
nonfilledRect(rect
);
387 nonfilledRect
.left
= progressPosition
;
389 bool filledSurface
= filledRect
.Width() > 0;
390 bool nonfilledSurface
= nonfilledRect
.Width() > 0;
393 _DrawFrame(view
, filledRect
,
394 dark1FilledBorderColor
, dark1FilledBorderColor
,
395 dark2FilledBorderColor
, dark2FilledBorderColor
);
397 _FillGlossyGradient(view
, filledRect
, barColor
, 0.55, 0.68, 0.76, 0.90);
400 if (nonfilledSurface
) {
401 _DrawFrame(view
, nonfilledRect
, dark1BorderColor
, dark1BorderColor
,
402 dark2BorderColor
, dark2BorderColor
,
403 B_TOP_BORDER
| B_BOTTOM_BORDER
| B_RIGHT_BORDER
);
405 if (nonfilledRect
.left
< nonfilledRect
.right
) {
406 // shadow from fill bar, or left border
407 rgb_color leftBorder
= dark1BorderColor
;
409 leftBorder
= tint_color(base
, 0.50);
410 view
->SetHighColor(leftBorder
);
411 view
->StrokeLine(nonfilledRect
.LeftTop(),
412 nonfilledRect
.LeftBottom());
413 nonfilledRect
.left
++;
416 _FillGradient(view
, nonfilledRect
, base
, 0.25, 0.06);
422 HaikuControlLook::DrawCheckBox(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
423 const rgb_color
& base
, uint32 flags
)
425 if (!rect
.Intersects(updateRect
))
428 rgb_color dark1BorderColor
;
429 rgb_color dark2BorderColor
;
430 rgb_color navigationColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
432 if ((flags
& B_DISABLED
) != 0) {
433 _DrawOuterResessedFrame(view
, rect
, base
, 0.0, 1.0, flags
);
435 dark1BorderColor
= tint_color(base
, 1.15);
436 dark2BorderColor
= tint_color(base
, 1.15);
437 } else if ((flags
& B_CLICKED
) != 0) {
438 dark1BorderColor
= tint_color(base
, 1.50);
439 dark2BorderColor
= tint_color(base
, 1.48);
441 _DrawFrame(view
, rect
,
442 dark1BorderColor
, dark1BorderColor
,
443 dark2BorderColor
, dark2BorderColor
);
445 dark2BorderColor
= dark1BorderColor
;
447 _DrawOuterResessedFrame(view
, rect
, base
, 0.6, 1.0, flags
);
449 dark1BorderColor
= tint_color(base
, 1.40);
450 dark2BorderColor
= tint_color(base
, 1.38);
453 if ((flags
& B_FOCUSED
) != 0) {
454 dark1BorderColor
= navigationColor
;
455 dark2BorderColor
= navigationColor
;
458 _DrawFrame(view
, rect
,
459 dark1BorderColor
, dark1BorderColor
,
460 dark2BorderColor
, dark2BorderColor
);
462 if ((flags
& B_DISABLED
) != 0)
463 _FillGradient(view
, rect
, base
, 0.4, 0.2);
465 _FillGradient(view
, rect
, base
, 0.15, 0.0);
468 if (_RadioButtonAndCheckBoxMarkColor(base
, markColor
, flags
)) {
469 view
->SetHighColor(markColor
);
472 view
->GetFont(&font
);
473 float inset
= std::max(2.0f
, roundf(font
.Size() / 6));
474 rect
.InsetBy(inset
, inset
);
476 float penSize
= std::max(1.0f
, ceilf(rect
.Width() / 3.5f
));
477 if (penSize
> 1.0f
&& fmodf(penSize
, 2.0f
) == 0.0f
) {
478 // Tweak ends to "include" the pixel at the index,
479 // we need to do this in order to produce results like R5,
480 // where coordinates were inclusive
485 view
->SetPenSize(penSize
);
486 view
->SetDrawingMode(B_OP_OVER
);
487 view
->StrokeLine(rect
.LeftTop(), rect
.RightBottom());
488 view
->StrokeLine(rect
.LeftBottom(), rect
.RightTop());
494 HaikuControlLook::DrawRadioButton(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
495 const rgb_color
& base
, uint32 flags
)
497 if (!rect
.Intersects(updateRect
))
500 rgb_color borderColor
;
501 rgb_color bevelLight
;
502 rgb_color bevelShadow
;
503 rgb_color navigationColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
505 if ((flags
& B_DISABLED
) != 0) {
506 borderColor
= tint_color(base
, 1.15);
509 } else if ((flags
& B_CLICKED
) != 0) {
510 borderColor
= tint_color(base
, 1.50);
511 bevelLight
= borderColor
;
512 bevelShadow
= borderColor
;
514 borderColor
= tint_color(base
, 1.45);
515 bevelLight
= tint_color(base
, 0.55);
516 bevelShadow
= tint_color(base
, 1.11);
519 if ((flags
& B_FOCUSED
) != 0) {
520 borderColor
= navigationColor
;
523 BGradientLinear bevelGradient
;
524 bevelGradient
.AddColor(bevelShadow
, 0);
525 bevelGradient
.AddColor(bevelLight
, 255);
526 bevelGradient
.SetStart(rect
.LeftTop());
527 bevelGradient
.SetEnd(rect
.RightBottom());
529 view
->FillEllipse(rect
, bevelGradient
);
532 bevelGradient
.MakeEmpty();
533 bevelGradient
.AddColor(borderColor
, 0);
534 bevelGradient
.AddColor(tint_color(borderColor
, 0.8), 255);
535 view
->FillEllipse(rect
, bevelGradient
);
540 if ((flags
& B_DISABLED
) != 0) {
548 BGradientLinear gradient
;
549 _MakeGradient(gradient
, rect
, base
, topTint
, bottomTint
);
550 view
->FillEllipse(rect
, gradient
);
553 if (_RadioButtonAndCheckBoxMarkColor(base
, markColor
, flags
)) {
554 view
->SetHighColor(markColor
);
556 view
->GetFont(&font
);
557 float inset
= roundf(font
.Size() / 4);
558 rect
.InsetBy(inset
, inset
);
559 view
->FillEllipse(rect
);
565 HaikuControlLook::DrawScrollBarBackground(BView
* view
, BRect
& rect1
, BRect
& rect2
,
566 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
567 orientation orientation
)
569 DrawScrollBarBackground(view
, rect1
, updateRect
, base
, flags
, orientation
);
570 DrawScrollBarBackground(view
, rect2
, updateRect
, base
, flags
, orientation
);
575 HaikuControlLook::DrawScrollBarBackground(BView
* view
, BRect
& rect
,
576 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
577 orientation orientation
)
579 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
588 if ((flags
& B_DISABLED
) != 0) {
591 darkEdge1Tint
= B_DARKEN_2_TINT
;
592 darkEdge2Tint
= B_DARKEN_2_TINT
;
593 shadowTint
= gradient1Tint
;
595 gradient1Tint
= 1.10;
596 gradient2Tint
= 1.05;
597 darkEdge1Tint
= B_DARKEN_3_TINT
;
598 darkEdge2Tint
= B_DARKEN_2_TINT
;
599 shadowTint
= gradient1Tint
;
602 rgb_color darkEdge1
= tint_color(base
, darkEdge1Tint
);
603 rgb_color darkEdge2
= tint_color(base
, darkEdge2Tint
);
604 rgb_color shadow
= tint_color(base
, shadowTint
);
606 if (orientation
== B_HORIZONTAL
) {
607 // dark vertical line on left edge
608 if (rect
.Width() > 0) {
609 view
->SetHighColor(darkEdge1
);
610 view
->StrokeLine(rect
.LeftTop(), rect
.LeftBottom());
613 // dark vertical line on right edge
614 if (rect
.Width() >= 0) {
615 view
->SetHighColor(darkEdge2
);
616 view
->StrokeLine(rect
.RightTop(), rect
.RightBottom());
619 // vertical shadow line after left edge
620 if (rect
.Width() >= 0) {
621 view
->SetHighColor(shadow
);
622 view
->StrokeLine(rect
.LeftTop(), rect
.LeftBottom());
626 if (rect
.Width() >= 0) {
627 _FillGradient(view
, rect
, base
, gradient1Tint
, gradient2Tint
,
631 // dark vertical line on top edge
632 if (rect
.Height() > 0) {
633 view
->SetHighColor(darkEdge1
);
634 view
->StrokeLine(rect
.LeftTop(), rect
.RightTop());
637 // dark vertical line on bottom edge
638 if (rect
.Height() >= 0) {
639 view
->SetHighColor(darkEdge2
);
640 view
->StrokeLine(rect
.LeftBottom(), rect
.RightBottom());
643 // horizontal shadow line after top edge
644 if (rect
.Height() >= 0) {
645 view
->SetHighColor(shadow
);
646 view
->StrokeLine(rect
.LeftTop(), rect
.RightTop());
650 if (rect
.Height() >= 0) {
651 _FillGradient(view
, rect
, base
, gradient1Tint
, gradient2Tint
,
659 HaikuControlLook::DrawScrollViewFrame(BView
* view
, BRect
& rect
,
660 const BRect
& updateRect
, BRect verticalScrollBarFrame
,
661 BRect horizontalScrollBarFrame
, const rgb_color
& base
,
662 border_style borderStyle
, uint32 flags
, uint32 _borders
)
664 // calculate scroll corner rect before messing with the "rect"
665 BRect
scrollCornerFillRect(rect
.right
, rect
.bottom
,
666 rect
.right
, rect
.bottom
);
668 if (horizontalScrollBarFrame
.IsValid())
669 scrollCornerFillRect
.left
= horizontalScrollBarFrame
.right
+ 1;
671 if (verticalScrollBarFrame
.IsValid())
672 scrollCornerFillRect
.top
= verticalScrollBarFrame
.bottom
+ 1;
674 if (borderStyle
== B_NO_BORDER
) {
675 if (scrollCornerFillRect
.IsValid()) {
676 view
->SetHighColor(base
);
677 view
->FillRect(scrollCornerFillRect
);
682 bool excludeScrollCorner
= borderStyle
== B_FANCY_BORDER
683 && horizontalScrollBarFrame
.IsValid()
684 && verticalScrollBarFrame
.IsValid();
686 uint32 borders
= _borders
;
687 if (excludeScrollCorner
) {
688 rect
.bottom
= horizontalScrollBarFrame
.top
;
689 rect
.right
= verticalScrollBarFrame
.left
;
690 borders
&= ~(B_RIGHT_BORDER
| B_BOTTOM_BORDER
);
693 rgb_color scrollbarFrameColor
= tint_color(base
, B_DARKEN_2_TINT
);
695 if (borderStyle
== B_FANCY_BORDER
)
696 _DrawOuterResessedFrame(view
, rect
, base
, 1.0, 1.0, flags
, borders
);
698 if ((flags
& B_FOCUSED
) != 0) {
699 rgb_color focusColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
700 _DrawFrame(view
, rect
, focusColor
, focusColor
, focusColor
, focusColor
,
703 _DrawFrame(view
, rect
, scrollbarFrameColor
, scrollbarFrameColor
,
704 scrollbarFrameColor
, scrollbarFrameColor
, borders
);
707 if (excludeScrollCorner
) {
708 horizontalScrollBarFrame
.InsetBy(-1, -1);
709 // do not overdraw the top edge
710 horizontalScrollBarFrame
.top
+= 2;
712 borders
&= ~B_TOP_BORDER
;
713 _DrawOuterResessedFrame(view
, horizontalScrollBarFrame
, base
,
714 1.0, 1.0, flags
, borders
);
715 _DrawFrame(view
, horizontalScrollBarFrame
, scrollbarFrameColor
,
716 scrollbarFrameColor
, scrollbarFrameColor
, scrollbarFrameColor
,
719 verticalScrollBarFrame
.InsetBy(-1, -1);
720 // do not overdraw the left edge
721 verticalScrollBarFrame
.left
+= 2;
723 borders
&= ~B_LEFT_BORDER
;
724 _DrawOuterResessedFrame(view
, verticalScrollBarFrame
, base
,
725 1.0, 1.0, flags
, borders
);
726 _DrawFrame(view
, verticalScrollBarFrame
, scrollbarFrameColor
,
727 scrollbarFrameColor
, scrollbarFrameColor
, scrollbarFrameColor
,
730 // exclude recessed frame
731 scrollCornerFillRect
.top
++;
732 scrollCornerFillRect
.left
++;
735 if (scrollCornerFillRect
.IsValid()) {
736 view
->SetHighColor(base
);
737 view
->FillRect(scrollCornerFillRect
);
743 HaikuControlLook::DrawArrowShape(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
744 const rgb_color
& base
, uint32 direction
, uint32 flags
, float tint
)
746 BPoint tri1
, tri2
, tri3
;
747 float hInset
= rect
.Width() / 3;
748 float vInset
= rect
.Height() / 3;
749 rect
.InsetBy(hInset
, vInset
);
753 tri1
.Set(rect
.right
, rect
.top
);
754 tri2
.Set(rect
.right
- rect
.Width() / 1.33,
755 (rect
.top
+ rect
.bottom
+ 1) / 2);
756 tri3
.Set(rect
.right
, rect
.bottom
+ 1);
759 tri1
.Set(rect
.left
+ 1, rect
.bottom
+ 1);
760 tri2
.Set(rect
.left
+ 1 + rect
.Width() / 1.33,
761 (rect
.top
+ rect
.bottom
+ 1) / 2);
762 tri3
.Set(rect
.left
+ 1, rect
.top
);
765 tri1
.Set(rect
.left
, rect
.bottom
);
766 tri2
.Set((rect
.left
+ rect
.right
+ 1) / 2,
767 rect
.bottom
- rect
.Height() / 1.33);
768 tri3
.Set(rect
.right
+ 1, rect
.bottom
);
772 tri1
.Set(rect
.left
, rect
.top
+ 1);
773 tri2
.Set((rect
.left
+ rect
.right
+ 1) / 2,
774 rect
.top
+ 1 + rect
.Height() / 1.33);
775 tri3
.Set(rect
.right
+ 1, rect
.top
+ 1);
777 case B_LEFT_UP_ARROW
:
778 tri1
.Set(rect
.left
, rect
.bottom
);
779 tri2
.Set(rect
.left
, rect
.top
);
780 tri3
.Set(rect
.right
- 1, rect
.top
);
782 case B_RIGHT_UP_ARROW
:
783 tri1
.Set(rect
.left
+ 1, rect
.top
);
784 tri2
.Set(rect
.right
, rect
.top
);
785 tri3
.Set(rect
.right
, rect
.bottom
);
787 case B_RIGHT_DOWN_ARROW
:
788 tri1
.Set(rect
.right
, rect
.top
);
789 tri2
.Set(rect
.right
, rect
.bottom
);
790 tri3
.Set(rect
.left
+ 1, rect
.bottom
);
792 case B_LEFT_DOWN_ARROW
:
793 tri1
.Set(rect
.right
- 1, rect
.bottom
);
794 tri2
.Set(rect
.left
, rect
.bottom
);
795 tri3
.Set(rect
.left
, rect
.top
);
800 arrowShape
.MoveTo(tri1
);
801 arrowShape
.LineTo(tri2
);
802 arrowShape
.LineTo(tri3
);
804 if ((flags
& B_DISABLED
) != 0)
805 tint
= (tint
+ B_NO_TINT
+ B_NO_TINT
) / 3;
807 view
->SetHighColor(tint_color(base
, tint
));
809 float penSize
= view
->PenSize();
810 drawing_mode mode
= view
->DrawingMode();
812 view
->MovePenTo(BPoint(0, 0));
814 view
->SetPenSize(ceilf(hInset
/ 2.0));
815 view
->SetDrawingMode(B_OP_OVER
);
816 view
->StrokeShape(&arrowShape
);
818 view
->SetPenSize(penSize
);
819 view
->SetDrawingMode(mode
);
824 HaikuControlLook::SliderBarColor(const rgb_color
& base
)
826 return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR
), B_DARKEN_1_TINT
);
831 HaikuControlLook::DrawSliderBar(BView
* view
, BRect rect
, const BRect
& updateRect
,
832 const rgb_color
& base
, rgb_color leftFillColor
, rgb_color rightFillColor
,
833 float sliderScale
, uint32 flags
, orientation orientation
)
835 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
838 // save the clipping constraints of the view
841 // separate the bar in two sides
842 float sliderPosition
;
843 BRect leftBarSide
= rect
;
844 BRect rightBarSide
= rect
;
846 if (orientation
== B_HORIZONTAL
) {
847 sliderPosition
= floorf(rect
.left
+ 2 + (rect
.Width() - 2)
849 leftBarSide
.right
= sliderPosition
- 1;
850 rightBarSide
.left
= sliderPosition
;
852 // NOTE: position is reverse of coords
853 sliderPosition
= floorf(rect
.top
+ 2 + (rect
.Height() - 2)
854 * (1.0 - sliderScale
));
855 leftBarSide
.top
= sliderPosition
;
856 rightBarSide
.bottom
= sliderPosition
- 1;
859 // fill the background for the corners, exclude the middle bar for now
860 BRegion
region(rect
);
861 region
.Exclude(rightBarSide
);
862 view
->ConstrainClippingRegion(®ion
);
866 DrawSliderBar(view
, rect
, updateRect
, base
, leftFillColor
, flags
,
872 region
.Exclude(leftBarSide
);
873 view
->ConstrainClippingRegion(®ion
);
877 DrawSliderBar(view
, rect
, updateRect
, base
, rightFillColor
, flags
,
882 // restore the clipping constraints of the view
888 HaikuControlLook::DrawSliderBar(BView
* view
, BRect rect
, const BRect
& updateRect
,
889 const rgb_color
& base
, rgb_color fillColor
, uint32 flags
,
890 orientation orientation
)
892 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
895 // separate the rect into corners
896 BRect
leftCorner(rect
);
897 BRect
rightCorner(rect
);
900 if (orientation
== B_HORIZONTAL
) {
901 leftCorner
.right
= leftCorner
.left
+ leftCorner
.Height();
902 rightCorner
.left
= rightCorner
.right
- rightCorner
.Height();
903 barRect
.left
+= ceilf(barRect
.Height() / 2);
904 barRect
.right
-= ceilf(barRect
.Height() / 2);
906 leftCorner
.bottom
= leftCorner
.top
+ leftCorner
.Width();
907 rightCorner
.top
= rightCorner
.bottom
- rightCorner
.Width();
908 barRect
.top
+= ceilf(barRect
.Width() / 2);
909 barRect
.bottom
-= ceilf(barRect
.Width() / 2);
912 // fill the background for the corners, exclude the middle bar for now
913 BRegion
region(rect
);
914 region
.Exclude(barRect
);
915 view
->ConstrainClippingRegion(®ion
);
917 if ((flags
& B_BLEND_FRAME
) == 0) {
918 view
->SetHighColor(base
);
919 view
->FillRect(rect
);
922 // figure out the tints to be used
924 float edgeShadowTint
;
925 float frameLightTint
;
926 float frameShadowTint
;
928 float fillShadowTint
;
929 uint8 edgeLightAlpha
;
930 uint8 edgeShadowAlpha
;
931 uint8 frameLightAlpha
;
932 uint8 frameShadowAlpha
;
934 if ((flags
& B_DISABLED
) != 0) {
936 edgeShadowTint
= 1.0;
937 frameLightTint
= 1.20;
938 frameShadowTint
= 1.25;
940 fillShadowTint
= 1.05;
942 edgeShadowAlpha
= 12;
943 frameLightAlpha
= 40;
944 frameShadowAlpha
= 45;
946 fillColor
.red
= uint8(fillColor
.red
* 0.4 + base
.red
* 0.6);
947 fillColor
.green
= uint8(fillColor
.green
* 0.4 + base
.green
* 0.6);
948 fillColor
.blue
= uint8(fillColor
.blue
* 0.4 + base
.blue
* 0.6);
950 edgeLightTint
= 0.65;
951 edgeShadowTint
= 1.07;
952 frameLightTint
= 1.40;
953 frameShadowTint
= 1.50;
955 fillShadowTint
= 1.1;
957 edgeShadowAlpha
= 15;
958 frameLightAlpha
= 92;
959 frameShadowAlpha
= 107;
962 rgb_color edgeLightColor
;
963 rgb_color edgeShadowColor
;
964 rgb_color frameLightColor
;
965 rgb_color frameShadowColor
;
966 rgb_color fillLightColor
= tint_color(fillColor
, fillLightTint
);
967 rgb_color fillShadowColor
= tint_color(fillColor
, fillShadowTint
);
969 drawing_mode oldMode
= view
->DrawingMode();
971 if ((flags
& B_BLEND_FRAME
) != 0) {
972 edgeLightColor
= (rgb_color
){ 255, 255, 255, edgeLightAlpha
};
973 edgeShadowColor
= (rgb_color
){ 0, 0, 0, edgeShadowAlpha
};
974 frameLightColor
= (rgb_color
){ 0, 0, 0, frameLightAlpha
};
975 frameShadowColor
= (rgb_color
){ 0, 0, 0, frameShadowAlpha
};
977 view
->SetDrawingMode(B_OP_ALPHA
);
979 edgeLightColor
= tint_color(base
, edgeLightTint
);
980 edgeShadowColor
= tint_color(base
, edgeShadowTint
);
981 frameLightColor
= tint_color(fillColor
, frameLightTint
);
982 frameShadowColor
= tint_color(fillColor
, frameShadowTint
);
985 if (orientation
== B_HORIZONTAL
) {
986 _DrawRoundBarCorner(view
, leftCorner
, updateRect
, edgeLightColor
,
987 edgeShadowColor
, frameLightColor
, frameShadowColor
, fillLightColor
,
988 fillShadowColor
, 1.0, 1.0, 0.0, -1.0, orientation
);
990 _DrawRoundBarCorner(view
, rightCorner
, updateRect
, edgeLightColor
,
991 edgeShadowColor
, frameLightColor
, frameShadowColor
, fillLightColor
,
992 fillShadowColor
, 0.0, 1.0, -1.0, -1.0, orientation
);
994 _DrawRoundBarCorner(view
, leftCorner
, updateRect
, edgeLightColor
,
995 edgeShadowColor
, frameLightColor
, frameShadowColor
, fillLightColor
,
996 fillShadowColor
, 1.0, 1.0, -1.0, 0.0, orientation
);
998 _DrawRoundBarCorner(view
, rightCorner
, updateRect
, edgeLightColor
,
999 edgeShadowColor
, frameLightColor
, frameShadowColor
, fillLightColor
,
1000 fillShadowColor
, 1.0, 0.0, -1.0, -1.0, orientation
);
1003 view
->ConstrainClippingRegion(NULL
);
1005 view
->BeginLineArray(4);
1006 if (orientation
== B_HORIZONTAL
) {
1007 view
->AddLine(barRect
.LeftTop(), barRect
.RightTop(), edgeShadowColor
);
1008 view
->AddLine(barRect
.LeftBottom(), barRect
.RightBottom(),
1010 barRect
.InsetBy(0, 1);
1011 view
->AddLine(barRect
.LeftTop(), barRect
.RightTop(), frameShadowColor
);
1012 view
->AddLine(barRect
.LeftBottom(), barRect
.RightBottom(),
1014 barRect
.InsetBy(0, 1);
1016 view
->AddLine(barRect
.LeftTop(), barRect
.LeftBottom(), edgeShadowColor
);
1017 view
->AddLine(barRect
.RightTop(), barRect
.RightBottom(),
1019 barRect
.InsetBy(1, 0);
1020 view
->AddLine(barRect
.LeftTop(), barRect
.LeftBottom(), frameShadowColor
);
1021 view
->AddLine(barRect
.RightTop(), barRect
.RightBottom(),
1023 barRect
.InsetBy(1, 0);
1025 view
->EndLineArray();
1027 view
->SetDrawingMode(oldMode
);
1029 _FillGradient(view
, barRect
, fillColor
, fillShadowTint
, fillLightTint
,
1035 HaikuControlLook::DrawSliderThumb(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
1036 const rgb_color
& base
, uint32 flags
, orientation orientation
)
1038 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
1041 // figure out frame color
1042 rgb_color frameLightColor
;
1043 rgb_color frameShadowColor
;
1044 rgb_color shadowColor
= (rgb_color
){ 0, 0, 0, 60 };
1046 if ((flags
& B_FOCUSED
) != 0) {
1048 frameLightColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
1049 frameShadowColor
= frameLightColor
;
1051 // figure out the tints to be used
1052 float frameLightTint
;
1053 float frameShadowTint
;
1055 if ((flags
& B_DISABLED
) != 0) {
1056 frameLightTint
= 1.30;
1057 frameShadowTint
= 1.35;
1058 shadowColor
.alpha
= 30;
1060 frameLightTint
= 1.6;
1061 frameShadowTint
= 1.65;
1064 frameLightColor
= tint_color(base
, frameLightTint
);
1065 frameShadowColor
= tint_color(base
, frameShadowTint
);
1068 BRect
originalRect(rect
);
1072 _DrawFrame(view
, rect
, frameLightColor
, frameLightColor
,
1073 frameShadowColor
, frameShadowColor
);
1075 flags
&= ~B_ACTIVATED
;
1076 DrawButtonBackground(view
, rect
, updateRect
, base
, flags
);
1079 view
->SetDrawingMode(B_OP_ALPHA
);
1080 view
->SetHighColor(shadowColor
);
1081 originalRect
.left
++;
1083 view
->StrokeLine(originalRect
.LeftBottom(), originalRect
.RightBottom());
1084 originalRect
.bottom
--;
1085 view
->StrokeLine(originalRect
.RightTop(), originalRect
.RightBottom());
1088 if (orientation
== B_HORIZONTAL
) {
1089 rect
.InsetBy(0, floorf(rect
.Height() / 4));
1090 rect
.left
= floorf((rect
.left
+ rect
.right
) / 2);
1091 rect
.right
= rect
.left
+ 1;
1092 shadowColor
= tint_color(base
, B_DARKEN_2_TINT
);
1093 shadowColor
.alpha
= 128;
1094 view
->SetHighColor(shadowColor
);
1095 view
->StrokeLine(rect
.LeftTop(), rect
.LeftBottom());
1096 rgb_color lightColor
= tint_color(base
, B_LIGHTEN_2_TINT
);
1097 lightColor
.alpha
= 128;
1098 view
->SetHighColor(lightColor
);
1099 view
->StrokeLine(rect
.RightTop(), rect
.RightBottom());
1101 rect
.InsetBy(floorf(rect
.Width() / 4), 0);
1102 rect
.top
= floorf((rect
.top
+ rect
.bottom
) / 2);
1103 rect
.bottom
= rect
.top
+ 1;
1104 shadowColor
= tint_color(base
, B_DARKEN_2_TINT
);
1105 shadowColor
.alpha
= 128;
1106 view
->SetHighColor(shadowColor
);
1107 view
->StrokeLine(rect
.LeftTop(), rect
.RightTop());
1108 rgb_color lightColor
= tint_color(base
, B_LIGHTEN_2_TINT
);
1109 lightColor
.alpha
= 128;
1110 view
->SetHighColor(lightColor
);
1111 view
->StrokeLine(rect
.LeftBottom(), rect
.RightBottom());
1114 view
->SetDrawingMode(B_OP_COPY
);
1119 HaikuControlLook::DrawSliderTriangle(BView
* view
, BRect
& rect
,
1120 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
1121 orientation orientation
)
1123 DrawSliderTriangle(view
, rect
, updateRect
, base
, base
, flags
, orientation
);
1128 HaikuControlLook::DrawSliderTriangle(BView
* view
, BRect
& rect
,
1129 const BRect
& updateRect
, const rgb_color
& base
, const rgb_color
& fill
,
1130 uint32 flags
, orientation orientation
)
1132 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
1135 // figure out frame color
1136 rgb_color frameLightColor
;
1137 rgb_color frameShadowColor
;
1138 rgb_color shadowColor
= (rgb_color
){ 0, 0, 0, 60 };
1140 float topTint
= 0.49;
1141 float middleTint1
= 0.62;
1142 float middleTint2
= 0.76;
1143 float bottomTint
= 0.90;
1145 if ((flags
& B_DISABLED
) != 0) {
1146 topTint
= (topTint
+ B_NO_TINT
) / 2;
1147 middleTint1
= (middleTint1
+ B_NO_TINT
) / 2;
1148 middleTint2
= (middleTint2
+ B_NO_TINT
) / 2;
1149 bottomTint
= (bottomTint
+ B_NO_TINT
) / 2;
1150 } else if ((flags
& B_HOVER
) != 0) {
1151 topTint
*= kHoverTintFactor
;
1152 middleTint1
*= kHoverTintFactor
;
1153 middleTint2
*= kHoverTintFactor
;
1154 bottomTint
*= kHoverTintFactor
;
1157 if ((flags
& B_FOCUSED
) != 0) {
1159 frameLightColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
1160 frameShadowColor
= frameLightColor
;
1162 // figure out the tints to be used
1163 float frameLightTint
;
1164 float frameShadowTint
;
1166 if ((flags
& B_DISABLED
) != 0) {
1167 frameLightTint
= 1.30;
1168 frameShadowTint
= 1.35;
1169 shadowColor
.alpha
= 30;
1171 frameLightTint
= 1.6;
1172 frameShadowTint
= 1.65;
1175 frameLightColor
= tint_color(base
, frameLightTint
);
1176 frameShadowColor
= tint_color(base
, frameShadowTint
);
1179 // make room for the shadow
1183 uint32 viewFlags
= view
->Flags();
1184 view
->SetFlags(viewFlags
| B_SUBPIXEL_PRECISE
);
1185 view
->SetLineMode(B_ROUND_CAP
, B_ROUND_JOIN
);
1187 float centerh
= (rect
.left
+ rect
.right
) / 2;
1188 float centerv
= (rect
.top
+ rect
.bottom
) / 2;
1191 if (orientation
== B_HORIZONTAL
) {
1192 shape
.MoveTo(BPoint(rect
.left
+ 0.5, rect
.bottom
+ 0.5));
1193 shape
.LineTo(BPoint(rect
.right
+ 0.5, rect
.bottom
+ 0.5));
1194 shape
.LineTo(BPoint(rect
.right
+ 0.5, rect
.bottom
- 1 + 0.5));
1195 shape
.LineTo(BPoint(centerh
+ 0.5, rect
.top
+ 0.5));
1196 shape
.LineTo(BPoint(rect
.left
+ 0.5, rect
.bottom
- 1 + 0.5));
1198 shape
.MoveTo(BPoint(rect
.right
+ 0.5, rect
.top
+ 0.5));
1199 shape
.LineTo(BPoint(rect
.right
+ 0.5, rect
.bottom
+ 0.5));
1200 shape
.LineTo(BPoint(rect
.right
- 1 + 0.5, rect
.bottom
+ 0.5));
1201 shape
.LineTo(BPoint(rect
.left
+ 0.5, centerv
+ 0.5));
1202 shape
.LineTo(BPoint(rect
.right
- 1 + 0.5, rect
.top
+ 0.5));
1206 view
->MovePenTo(BPoint(1, 1));
1208 view
->SetDrawingMode(B_OP_ALPHA
);
1209 view
->SetHighColor(shadowColor
);
1210 view
->StrokeShape(&shape
);
1212 view
->MovePenTo(B_ORIGIN
);
1214 view
->SetDrawingMode(B_OP_COPY
);
1215 view
->SetHighColor(frameLightColor
);
1216 view
->StrokeShape(&shape
);
1220 if (orientation
== B_HORIZONTAL
) {
1221 shape
.MoveTo(BPoint(rect
.left
, rect
.bottom
+ 1));
1222 shape
.LineTo(BPoint(rect
.right
+ 1, rect
.bottom
+ 1));
1223 shape
.LineTo(BPoint(centerh
+ 0.5, rect
.top
));
1225 shape
.MoveTo(BPoint(rect
.right
+ 1, rect
.top
));
1226 shape
.LineTo(BPoint(rect
.right
+ 1, rect
.bottom
+ 1));
1227 shape
.LineTo(BPoint(rect
.left
, centerv
+ 0.5));
1231 BGradientLinear gradient
;
1232 if ((flags
& B_DISABLED
) != 0) {
1233 _MakeGradient(gradient
, rect
, fill
, topTint
, bottomTint
);
1235 _MakeGlossyGradient(gradient
, rect
, fill
, topTint
, middleTint1
,
1236 middleTint2
, bottomTint
);
1239 view
->FillShape(&shape
, gradient
);
1241 view
->SetFlags(viewFlags
);
1246 HaikuControlLook::DrawSliderHashMarks(BView
* view
, BRect
& rect
,
1247 const BRect
& updateRect
, const rgb_color
& base
, int32 count
,
1248 hash_mark_location location
, uint32 flags
, orientation orientation
)
1250 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
1253 rgb_color lightColor
;
1254 rgb_color darkColor
;
1256 if ((flags
& B_DISABLED
) != 0) {
1257 lightColor
= tint_color(base
, 0.9);
1258 darkColor
= tint_color(base
, 1.07);
1260 lightColor
= tint_color(base
, 0.8);
1261 darkColor
= tint_color(base
, 1.14);
1264 int32 hashMarkCount
= std::max(count
, (int32
)2);
1265 // draw at least two hashmarks at min/max if
1266 // fHashMarks != B_HASH_MARKS_NONE
1269 if (orientation
== B_HORIZONTAL
) {
1270 factor
= (rect
.Width() - 2) / (hashMarkCount
- 1);
1271 startPos
= rect
.left
+ 1;
1273 factor
= (rect
.Height() - 2) / (hashMarkCount
- 1);
1274 startPos
= rect
.top
+ 1;
1277 if (location
& B_HASH_MARKS_TOP
) {
1278 view
->BeginLineArray(hashMarkCount
* 2);
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
);
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
);
1302 view
->EndLineArray();
1305 if ((location
& B_HASH_MARKS_BOTTOM
) != 0) {
1306 view
->BeginLineArray(hashMarkCount
* 2);
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
);
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
);
1330 view
->EndLineArray();
1336 HaikuControlLook::DrawActiveTab(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
1337 const rgb_color
& base
, uint32 flags
, uint32 borders
, uint32 side
)
1339 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
1342 // Snap the rectangle to pixels to avoid rounding errors.
1343 rect
.left
= floorf(rect
.left
);
1344 rect
.right
= floorf(rect
.right
);
1345 rect
.top
= floorf(rect
.top
);
1346 rect
.bottom
= floorf(rect
.bottom
);
1348 // save the clipping constraints of the view
1351 // set clipping constraints to updateRect
1352 BRegion
clipping(updateRect
);
1353 view
->ConstrainClippingRegion(&clipping
);
1355 rgb_color edgeShadowColor
;
1356 rgb_color edgeLightColor
;
1357 rgb_color frameShadowColor
;
1358 rgb_color frameLightColor
;
1359 rgb_color bevelShadowColor
;
1360 rgb_color bevelLightColor
;
1361 BGradientLinear fillGradient
;
1362 fillGradient
.SetStart(rect
.LeftTop() + BPoint(3, 3));
1363 fillGradient
.SetEnd(rect
.LeftBottom() + BPoint(3, -3));
1365 if ((flags
& B_DISABLED
) != 0) {
1366 edgeLightColor
= base
;
1367 edgeShadowColor
= base
;
1368 frameLightColor
= tint_color(base
, 1.25);
1369 frameShadowColor
= tint_color(base
, 1.30);
1370 bevelLightColor
= tint_color(base
, 0.8);
1371 bevelShadowColor
= tint_color(base
, 1.07);
1372 fillGradient
.AddColor(tint_color(base
, 0.85), 0);
1373 fillGradient
.AddColor(base
, 255);
1375 edgeLightColor
= tint_color(base
, 0.80);
1376 edgeShadowColor
= tint_color(base
, 1.03);
1377 frameLightColor
= tint_color(base
, 1.30);
1378 frameShadowColor
= tint_color(base
, 1.30);
1379 bevelLightColor
= tint_color(base
, 0.6);
1380 bevelShadowColor
= tint_color(base
, 1.07);
1381 fillGradient
.AddColor(tint_color(base
, 0.75), 0);
1382 fillGradient
.AddColor(tint_color(base
, 1.03), 255);
1385 static const float kRoundCornerRadius
= 4.0f
;
1387 // left top corner dimensions
1388 BRect
leftTopCorner(rect
);
1389 leftTopCorner
.right
= floorf(leftTopCorner
.left
+ kRoundCornerRadius
);
1390 leftTopCorner
.bottom
= floorf(rect
.top
+ kRoundCornerRadius
);
1392 // right top corner dimensions
1393 BRect
rightTopCorner(rect
);
1394 rightTopCorner
.left
= floorf(rightTopCorner
.right
- kRoundCornerRadius
);
1395 rightTopCorner
.bottom
= floorf(rect
.top
+ kRoundCornerRadius
);
1397 // left bottom corner dimensions
1398 BRect
leftBottomCorner(rect
);
1399 leftBottomCorner
.right
= floorf(leftBottomCorner
.left
+ kRoundCornerRadius
);
1400 leftBottomCorner
.top
= floorf(rect
.bottom
- kRoundCornerRadius
);
1402 // right bottom corner dimensions
1403 BRect
rightBottomCorner(rect
);
1404 rightBottomCorner
.left
= floorf(rightBottomCorner
.right
1405 - kRoundCornerRadius
);
1406 rightBottomCorner
.top
= floorf(rect
.bottom
- kRoundCornerRadius
);
1410 clipping
.Exclude(leftTopCorner
);
1411 clipping
.Exclude(rightTopCorner
);
1413 // draw the left top corner
1414 _DrawRoundCornerLeftTop(view
, leftTopCorner
, updateRect
, base
,
1415 edgeShadowColor
, frameLightColor
, bevelLightColor
,
1417 // draw the right top corner
1418 _DrawRoundCornerRightTop(view
, rightTopCorner
, updateRect
, base
,
1419 edgeShadowColor
, edgeLightColor
, frameLightColor
,
1420 frameShadowColor
, bevelLightColor
, bevelShadowColor
,
1423 case B_BOTTOM_BORDER
:
1424 clipping
.Exclude(leftBottomCorner
);
1425 clipping
.Exclude(rightBottomCorner
);
1427 // draw the left bottom corner
1428 _DrawRoundCornerLeftBottom(view
, leftBottomCorner
, updateRect
, base
,
1429 edgeShadowColor
, edgeLightColor
, frameLightColor
,
1430 frameShadowColor
, bevelLightColor
, bevelShadowColor
,
1432 // draw the right bottom corner
1433 _DrawRoundCornerRightBottom(view
, rightBottomCorner
, updateRect
,
1434 base
, edgeLightColor
, frameShadowColor
, bevelShadowColor
,
1438 clipping
.Exclude(leftTopCorner
);
1439 clipping
.Exclude(leftBottomCorner
);
1441 // draw the left top corner
1442 _DrawRoundCornerLeftTop(view
, leftTopCorner
, updateRect
, base
,
1443 edgeShadowColor
, frameLightColor
, bevelLightColor
,
1445 // draw the left bottom corner
1446 _DrawRoundCornerLeftBottom(view
, leftBottomCorner
, updateRect
, base
,
1447 edgeShadowColor
, edgeLightColor
, frameLightColor
,
1448 frameShadowColor
, bevelLightColor
, bevelShadowColor
,
1451 case B_RIGHT_BORDER
:
1452 clipping
.Exclude(rightTopCorner
);
1453 clipping
.Exclude(rightBottomCorner
);
1455 // draw the right top corner
1456 _DrawRoundCornerRightTop(view
, rightTopCorner
, updateRect
, base
,
1457 edgeShadowColor
, edgeLightColor
, frameLightColor
,
1458 frameShadowColor
, bevelLightColor
, bevelShadowColor
,
1460 // draw the right bottom corner
1461 _DrawRoundCornerRightBottom(view
, rightBottomCorner
, updateRect
,
1462 base
, edgeLightColor
, frameShadowColor
, bevelShadowColor
,
1467 // clip out the corners
1468 view
->ConstrainClippingRegion(&clipping
);
1470 uint32 bordersToDraw
= 0;
1473 bordersToDraw
= (B_LEFT_BORDER
| B_TOP_BORDER
| B_RIGHT_BORDER
);
1475 case B_BOTTOM_BORDER
:
1476 bordersToDraw
= (B_LEFT_BORDER
| B_BOTTOM_BORDER
| B_RIGHT_BORDER
);
1479 bordersToDraw
= (B_LEFT_BORDER
| B_BOTTOM_BORDER
| B_TOP_BORDER
);
1481 case B_RIGHT_BORDER
:
1482 bordersToDraw
= (B_RIGHT_BORDER
| B_BOTTOM_BORDER
| B_TOP_BORDER
);
1486 // draw the rest of frame and fill
1487 _DrawFrame(view
, rect
, edgeShadowColor
, edgeShadowColor
, edgeLightColor
,
1488 edgeLightColor
, borders
);
1489 if (side
== B_TOP_BORDER
|| side
== B_BOTTOM_BORDER
) {
1490 if ((borders
& B_LEFT_BORDER
) == 0)
1492 if ((borders
& B_RIGHT_BORDER
) == 0)
1494 } else if (side
== B_LEFT_BORDER
|| side
== B_RIGHT_BORDER
) {
1495 if ((borders
& B_TOP_BORDER
) == 0)
1497 if ((borders
& B_BOTTOM_BORDER
) == 0)
1501 _DrawFrame(view
, rect
, frameLightColor
, frameLightColor
, frameShadowColor
,
1502 frameShadowColor
, bordersToDraw
);
1504 _DrawFrame(view
, rect
, bevelLightColor
, bevelLightColor
, bevelShadowColor
,
1507 view
->FillRect(rect
, fillGradient
);
1509 // restore the clipping constraints of the view
1515 HaikuControlLook::DrawInactiveTab(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
1516 const rgb_color
& base
, uint32 flags
, uint32 borders
, uint32 side
)
1518 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
1521 rgb_color edgeShadowColor
;
1522 rgb_color edgeLightColor
;
1523 rgb_color frameShadowColor
;
1524 rgb_color frameLightColor
;
1525 rgb_color bevelShadowColor
;
1526 rgb_color bevelLightColor
;
1527 BGradientLinear fillGradient
;
1528 fillGradient
.SetStart(rect
.LeftTop() + BPoint(3, 3));
1529 fillGradient
.SetEnd(rect
.LeftBottom() + BPoint(3, -3));
1531 if ((flags
& B_DISABLED
) != 0) {
1532 edgeLightColor
= base
;
1533 edgeShadowColor
= base
;
1534 frameLightColor
= tint_color(base
, 1.25);
1535 frameShadowColor
= tint_color(base
, 1.30);
1536 bevelLightColor
= tint_color(base
, 0.8);
1537 bevelShadowColor
= tint_color(base
, 1.07);
1538 fillGradient
.AddColor(tint_color(base
, 0.85), 0);
1539 fillGradient
.AddColor(base
, 255);
1541 edgeLightColor
= tint_color(base
, 0.80);
1542 edgeShadowColor
= tint_color(base
, 1.03);
1543 frameLightColor
= tint_color(base
, 1.30);
1544 frameShadowColor
= tint_color(base
, 1.30);
1545 bevelLightColor
= tint_color(base
, 1.10);
1546 bevelShadowColor
= tint_color(base
, 1.17);
1547 fillGradient
.AddColor(tint_color(base
, 1.12), 0);
1548 fillGradient
.AddColor(tint_color(base
, 1.08), 255);
1551 BRect background
= rect
;
1555 background
.bottom
= rect
.top
;
1557 case B_BOTTOM_BORDER
:
1559 background
.top
= rect
.bottom
;
1563 background
.right
= rect
.left
;
1565 case B_RIGHT_BORDER
:
1567 background
.left
= rect
.right
;
1571 // active tabs stand out at the top, but this is an inactive tab
1572 view
->SetHighColor(base
);
1573 view
->FillRect(background
);
1576 _DrawFrame(view
, rect
, edgeShadowColor
, edgeShadowColor
, edgeLightColor
,
1577 edgeLightColor
, borders
);
1579 _DrawFrame(view
, rect
, frameLightColor
, frameLightColor
, frameShadowColor
,
1580 frameShadowColor
, borders
);
1582 if (rect
.IsValid()) {
1583 if (side
== B_TOP_BORDER
|| side
== B_BOTTOM_BORDER
) {
1584 _DrawFrame(view
, rect
, bevelShadowColor
, bevelShadowColor
,
1585 bevelLightColor
, bevelLightColor
, B_LEFT_BORDER
& ~borders
);
1586 } else if (side
== B_LEFT_BORDER
|| side
== B_RIGHT_BORDER
) {
1587 _DrawFrame(view
, rect
, bevelShadowColor
, bevelShadowColor
,
1588 bevelLightColor
, bevelLightColor
, B_TOP_BORDER
& ~borders
);
1591 if (side
== B_TOP_BORDER
|| side
== B_BOTTOM_BORDER
) {
1592 if ((B_LEFT_BORDER
& ~borders
) != 0)
1594 } else if (side
== B_LEFT_BORDER
|| side
== B_RIGHT_BORDER
) {
1595 if ((B_TOP_BORDER
& ~borders
) != 0)
1600 view
->FillRect(rect
, fillGradient
);
1605 HaikuControlLook::DrawSplitter(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
1606 const rgb_color
& base
, orientation orientation
, uint32 flags
,
1609 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
1612 rgb_color background
;
1613 if ((flags
& (B_CLICKED
| B_ACTIVATED
)) != 0)
1614 background
= tint_color(base
, B_DARKEN_1_TINT
);
1618 rgb_color light
= tint_color(background
, 0.6);
1619 rgb_color shadow
= tint_color(background
, 1.21);
1622 if (borders
!= 0 && rect
.Width() > 3 && rect
.Height() > 3)
1623 DrawRaisedBorder(view
, rect
, updateRect
, background
, flags
, borders
);
1625 // dots and rest of background
1626 if (orientation
== B_HORIZONTAL
) {
1627 if (rect
.Width() > 2) {
1628 // background on left/right
1629 BRegion
region(rect
);
1630 rect
.left
= floorf((rect
.left
+ rect
.right
) / 2.0 - 0.5);
1631 rect
.right
= rect
.left
+ 1;
1632 region
.Exclude(rect
);
1633 view
->SetHighColor(background
);
1634 view
->FillRegion(®ion
);
1637 BPoint dot
= rect
.LeftTop();
1638 BPoint stop
= rect
.LeftBottom();
1640 while (dot
.y
<= stop
.y
) {
1659 view
->SetHighColor(col1
);
1660 view
->StrokeLine(dot
, dot
, B_SOLID_HIGH
);
1661 view
->SetHighColor(col2
);
1663 view
->StrokeLine(dot
, dot
, B_SOLID_HIGH
);
1670 if (rect
.Height() > 2) {
1671 // background on left/right
1672 BRegion
region(rect
);
1673 rect
.top
= floorf((rect
.top
+ rect
.bottom
) / 2.0 - 0.5);
1674 rect
.bottom
= rect
.top
+ 1;
1675 region
.Exclude(rect
);
1676 view
->SetHighColor(background
);
1677 view
->FillRegion(®ion
);
1680 BPoint dot
= rect
.LeftTop();
1681 BPoint stop
= rect
.RightTop();
1683 while (dot
.x
<= stop
.x
) {
1702 view
->SetHighColor(col1
);
1703 view
->StrokeLine(dot
, dot
, B_SOLID_HIGH
);
1704 view
->SetHighColor(col2
);
1706 view
->StrokeLine(dot
, dot
, B_SOLID_HIGH
);
1720 HaikuControlLook::DrawBorder(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
1721 const rgb_color
& base
, border_style borderStyle
, uint32 flags
,
1724 if (borderStyle
== B_NO_BORDER
)
1727 rgb_color scrollbarFrameColor
= tint_color(base
, B_DARKEN_2_TINT
);
1728 if ((flags
& B_FOCUSED
) != 0)
1729 scrollbarFrameColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
1731 if (borderStyle
== B_FANCY_BORDER
)
1732 _DrawOuterResessedFrame(view
, rect
, base
, 1.0, 1.0, flags
, borders
);
1734 _DrawFrame(view
, rect
, scrollbarFrameColor
, scrollbarFrameColor
,
1735 scrollbarFrameColor
, scrollbarFrameColor
, borders
);
1740 HaikuControlLook::DrawRaisedBorder(BView
* view
, BRect
& rect
,
1741 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
1744 rgb_color lightColor
;
1745 rgb_color shadowColor
;
1747 if ((flags
& B_DISABLED
) != 0) {
1751 lightColor
= tint_color(base
, 0.85);
1752 shadowColor
= tint_color(base
, 1.07);
1755 _DrawFrame(view
, rect
, lightColor
, lightColor
, shadowColor
, shadowColor
,
1761 HaikuControlLook::DrawTextControlBorder(BView
* view
, BRect
& rect
,
1762 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
1765 if (!rect
.Intersects(updateRect
))
1768 rgb_color dark1BorderColor
;
1769 rgb_color dark2BorderColor
;
1770 rgb_color navigationColor
= ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
1771 rgb_color invalidColor
= ui_color(B_FAILURE_COLOR
);
1773 if ((flags
& B_DISABLED
) != 0) {
1774 _DrawOuterResessedFrame(view
, rect
, base
, 0.0, 1.0, flags
, borders
);
1776 if ((flags
& B_BLEND_FRAME
) != 0)
1777 dark1BorderColor
= (rgb_color
){ 0, 0, 0, 40 };
1779 dark1BorderColor
= tint_color(base
, 1.15);
1780 dark2BorderColor
= dark1BorderColor
;
1781 } else if ((flags
& B_CLICKED
) != 0) {
1782 dark1BorderColor
= tint_color(base
, 1.50);
1783 dark2BorderColor
= tint_color(base
, 1.49);
1785 // BCheckBox uses this to indicate the clicked state...
1786 _DrawFrame(view
, rect
,
1787 dark1BorderColor
, dark1BorderColor
,
1788 dark2BorderColor
, dark2BorderColor
);
1790 dark2BorderColor
= dark1BorderColor
;
1792 _DrawOuterResessedFrame(view
, rect
, base
, 0.6, 1.0, flags
, borders
);
1794 if ((flags
& B_BLEND_FRAME
) != 0) {
1795 dark1BorderColor
= (rgb_color
){ 0, 0, 0, 102 };
1796 dark2BorderColor
= (rgb_color
){ 0, 0, 0, 97 };
1798 dark1BorderColor
= tint_color(base
, 1.40);
1799 dark2BorderColor
= tint_color(base
, 1.38);
1803 if ((flags
& B_DISABLED
) == 0 && (flags
& B_FOCUSED
) != 0) {
1804 dark1BorderColor
= navigationColor
;
1805 dark2BorderColor
= navigationColor
;
1808 if ((flags
& B_DISABLED
) == 0 && (flags
& B_INVALID
) != 0) {
1809 dark1BorderColor
= invalidColor
;
1810 dark2BorderColor
= invalidColor
;
1813 if ((flags
& B_BLEND_FRAME
) != 0) {
1814 drawing_mode oldMode
= view
->DrawingMode();
1815 view
->SetDrawingMode(B_OP_ALPHA
);
1817 _DrawFrame(view
, rect
,
1818 dark1BorderColor
, dark1BorderColor
,
1819 dark2BorderColor
, dark2BorderColor
, borders
);
1821 view
->SetDrawingMode(oldMode
);
1823 _DrawFrame(view
, rect
,
1824 dark1BorderColor
, dark1BorderColor
,
1825 dark2BorderColor
, dark2BorderColor
, borders
);
1831 HaikuControlLook::DrawGroupFrame(BView
* view
, BRect
& rect
, const BRect
& updateRect
,
1832 const rgb_color
& base
, uint32 borders
)
1834 rgb_color frameColor
= tint_color(base
, 1.30);
1835 rgb_color bevelLight
= tint_color(base
, 0.8);
1836 rgb_color bevelShadow
= tint_color(base
, 1.03);
1838 _DrawFrame(view
, rect
, bevelShadow
, bevelShadow
, bevelLight
, bevelLight
,
1841 _DrawFrame(view
, rect
, frameColor
, frameColor
, frameColor
, frameColor
,
1844 _DrawFrame(view
, rect
, bevelLight
, bevelLight
, bevelShadow
, bevelShadow
,
1850 HaikuControlLook::DrawLabel(BView
* view
, const char* label
, BRect rect
,
1851 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
1852 const rgb_color
* textColor
)
1854 DrawLabel(view
, label
, NULL
, rect
, updateRect
, base
, flags
,
1855 DefaultLabelAlignment(), textColor
);
1860 HaikuControlLook::DrawLabel(BView
* view
, const char* label
, BRect rect
,
1861 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
1862 const BAlignment
& alignment
, const rgb_color
* textColor
)
1864 DrawLabel(view
, label
, NULL
, rect
, updateRect
, base
, flags
, alignment
,
1870 HaikuControlLook::DrawLabel(BView
* view
, const char* label
, const rgb_color
& base
,
1871 uint32 flags
, const BPoint
& where
, const rgb_color
* textColor
)
1873 // setup the text color
1875 BWindow
* window
= view
->Window();
1876 bool isDesktop
= window
1877 && window
->Feel() == kDesktopWindowFeel
1878 && window
->Look() == kDesktopWindowLook
1880 && view
->Parent()->Parent() == NULL
1881 && (flags
& B_IGNORE_OUTLINE
) == 0;
1885 rgb_color glowColor
;
1887 if (textColor
!= NULL
)
1888 glowColor
= *textColor
;
1889 else if ((flags
& B_IS_CONTROL
) != 0)
1890 glowColor
= ui_color(B_CONTROL_TEXT_COLOR
);
1892 glowColor
= ui_color(B_PANEL_TEXT_COLOR
);
1897 low
= view
->Parent()->ViewColor();
1901 if ((flags
& B_DISABLED
) != 0) {
1902 color
.red
= (uint8
)(((int32
)low
.red
+ color
.red
+ 1) / 2);
1903 color
.green
= (uint8
)(((int32
)low
.green
+ color
.green
+ 1) / 2);
1904 color
.blue
= (uint8
)(((int32
)low
.blue
+ color
.blue
+ 1) / 2);
1907 drawing_mode oldMode
= view
->DrawingMode();
1910 // enforce proper use of desktop label colors
1911 if (low
.Brightness() < 100) {
1912 if (textColor
== NULL
)
1913 color
= make_color(255, 255, 255);
1915 glowColor
= make_color(0, 0, 0);
1917 if (textColor
== NULL
)
1918 color
= make_color(0, 0, 0);
1920 glowColor
= make_color(255, 255, 255);
1923 // drawing occurs on the desktop
1924 if (fCachedWorkspace
!= current_workspace()) {
1928 while (fBackgroundInfo
.FindInt32("be:bgndimginfoworkspaces",
1929 indice
, &mask
) == B_OK
1930 && fBackgroundInfo
.FindBool("be:bgndimginfoerasetext",
1931 indice
, &tmpOutline
) == B_OK
) {
1933 if (((1 << current_workspace()) & mask
) != 0) {
1934 fCachedOutline
= tmpOutline
;
1935 fCachedWorkspace
= current_workspace();
1942 if (fCachedOutline
) {
1944 view
->GetFont(&font
);
1946 view
->SetDrawingMode(B_OP_ALPHA
);
1947 view
->SetBlendingMode(B_CONSTANT_ALPHA
, B_ALPHA_OVERLAY
);
1948 // Draw glow or outline
1949 if (glowColor
.Brightness() > 128) {
1950 font
.SetFalseBoldWidth(2.0);
1951 view
->SetFont(&font
, B_FONT_FALSE_BOLD_WIDTH
);
1953 glowColor
.alpha
= 30;
1954 view
->SetHighColor(glowColor
);
1955 view
->DrawString(label
, where
);
1957 font
.SetFalseBoldWidth(1.0);
1958 view
->SetFont(&font
, B_FONT_FALSE_BOLD_WIDTH
);
1960 glowColor
.alpha
= 65;
1961 view
->SetHighColor(glowColor
);
1962 view
->DrawString(label
, where
);
1964 font
.SetFalseBoldWidth(0.0);
1965 view
->SetFont(&font
, B_FONT_FALSE_BOLD_WIDTH
);
1967 font
.SetFalseBoldWidth(1.0);
1968 view
->SetFont(&font
, B_FONT_FALSE_BOLD_WIDTH
);
1970 glowColor
.alpha
= 30;
1971 view
->SetHighColor(glowColor
);
1972 view
->DrawString(label
, where
);
1974 font
.SetFalseBoldWidth(0.0);
1975 view
->SetFont(&font
, B_FONT_FALSE_BOLD_WIDTH
);
1977 glowColor
.alpha
= 200;
1978 view
->SetHighColor(glowColor
);
1979 view
->DrawString(label
, BPoint(where
.x
+ 1, where
.y
+ 1));
1984 view
->SetHighColor(color
);
1985 view
->SetDrawingMode(B_OP_OVER
);
1986 view
->DrawString(label
, where
);
1987 view
->SetDrawingMode(oldMode
);
1992 HaikuControlLook::DrawLabel(BView
* view
, const char* label
, const BBitmap
* icon
,
1993 BRect rect
, const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
1994 const BAlignment
& alignment
, const rgb_color
* textColor
)
1996 if (!rect
.Intersects(updateRect
))
1999 if (label
== NULL
&& icon
== NULL
)
2002 if (label
== NULL
) {
2004 BRect alignedRect
= BLayoutUtils::AlignInFrame(rect
,
2005 icon
->Bounds().Size(), alignment
);
2006 drawing_mode oldMode
= view
->DrawingMode();
2007 view
->SetDrawingMode(B_OP_OVER
);
2008 view
->DrawBitmap(icon
, alignedRect
.LeftTop());
2009 view
->SetDrawingMode(oldMode
);
2013 // label, possibly with icon
2014 float availableWidth
= rect
.Width() + 1;
2016 float textOffset
= 0;
2020 width
= icon
->Bounds().Width() + DefaultLabelSpacing() + 1;
2021 height
= icon
->Bounds().Height() + 1;
2023 availableWidth
-= textOffset
;
2026 // truncate the label if necessary and get the width and height
2027 BString
truncatedLabel(label
);
2030 view
->GetFont(&font
);
2032 font
.TruncateString(&truncatedLabel
, B_TRUNCATE_END
, availableWidth
);
2033 width
+= ceilf(font
.StringWidth(truncatedLabel
.String()));
2035 font_height fontHeight
;
2036 font
.GetHeight(&fontHeight
);
2037 float textHeight
= ceilf(fontHeight
.ascent
) + ceilf(fontHeight
.descent
);
2038 height
= std::max(height
, textHeight
);
2041 BRect
alignedRect(BLayoutUtils::AlignOnRect(rect
,
2042 BSize(width
- 1, height
- 1), alignment
));
2045 BPoint
location(alignedRect
.LeftTop());
2046 if (icon
->Bounds().Height() + 1 < height
)
2047 location
.y
+= ceilf((height
- icon
->Bounds().Height() - 1) / 2);
2049 drawing_mode oldMode
= view
->DrawingMode();
2050 view
->SetDrawingMode(B_OP_OVER
);
2051 view
->DrawBitmap(icon
, location
);
2052 view
->SetDrawingMode(oldMode
);
2055 BPoint
location(alignedRect
.left
+ textOffset
,
2056 alignedRect
.top
+ ceilf(fontHeight
.ascent
));
2057 if (textHeight
< height
)
2058 location
.y
+= ceilf((height
- textHeight
) / 2);
2060 DrawLabel(view
, truncatedLabel
.String(), base
, flags
, location
, textColor
);
2065 HaikuControlLook::GetFrameInsets(frame_type frameType
, uint32 flags
, float& _left
,
2066 float& _top
, float& _right
, float& _bottom
)
2068 // All frames have the same inset on each side.
2071 switch (frameType
) {
2072 case B_BUTTON_FRAME
:
2073 inset
= (flags
& B_DEFAULT_BUTTON
) != 0 ? 5 : 2;
2076 case B_MENU_FIELD_FRAME
:
2079 case B_SCROLL_VIEW_FRAME
:
2080 case B_TEXT_CONTROL_FRAME
:
2093 HaikuControlLook::GetBackgroundInsets(background_type backgroundType
,
2094 uint32 flags
, float& _left
, float& _top
, float& _right
, float& _bottom
)
2096 // Most backgrounds have the same inset on each side.
2099 switch (backgroundType
) {
2100 case B_BUTTON_BACKGROUND
:
2101 case B_MENU_BACKGROUND
:
2102 case B_MENU_BAR_BACKGROUND
:
2103 case B_MENU_FIELD_BACKGROUND
:
2104 case B_MENU_ITEM_BACKGROUND
:
2107 case B_BUTTON_WITH_POP_UP_BACKGROUND
:
2110 _right
= 1 + kButtonPopUpIndicatorWidth
;
2113 case B_HORIZONTAL_SCROLL_BAR_BACKGROUND
:
2119 case B_VERTICAL_SCROLL_BAR_BACKGROUND
:
2135 HaikuControlLook::DrawButtonWithPopUpBackground(BView
* view
, BRect
& rect
,
2136 const BRect
& updateRect
, const rgb_color
& base
, uint32 flags
,
2137 uint32 borders
, orientation orientation
)
2139 _DrawButtonBackground(view
, rect
, updateRect
, 0.0f
, 0.0f
, 0.0f
, 0.0f
,
2140 base
, true, flags
, borders
, orientation
);
2145 HaikuControlLook::DrawButtonWithPopUpBackground(BView
* view
, BRect
& rect
,
2146 const BRect
& updateRect
, float radius
, const rgb_color
& base
, uint32 flags
,
2147 uint32 borders
, orientation orientation
)
2149 _DrawButtonBackground(view
, rect
, updateRect
, radius
, radius
, radius
,
2150 radius
, base
, true, flags
, borders
, orientation
);
2155 HaikuControlLook::DrawButtonWithPopUpBackground(BView
* view
, BRect
& rect
,
2156 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
2157 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
2158 uint32 flags
, uint32 borders
, orientation orientation
)
2160 _DrawButtonBackground(view
, rect
, updateRect
, leftTopRadius
,
2161 rightTopRadius
, leftBottomRadius
, rightBottomRadius
, base
, true, flags
,
2162 borders
, orientation
);
2170 HaikuControlLook::_DrawButtonFrame(BView
* view
, BRect
& rect
,
2171 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
2172 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
2173 const rgb_color
& background
, float contrast
, float brightness
,
2174 uint32 flags
, uint32 borders
)
2176 if (!rect
.IsValid())
2179 // save the clipping constraints of the view
2182 // set clipping constraints to updateRect
2183 BRegion
clipping(updateRect
);
2184 view
->ConstrainClippingRegion(&clipping
);
2186 // If the button is flat and neither activated nor otherwise highlighted
2187 // (mouse hovering or focussed), draw it flat.
2188 if ((flags
& B_FLAT
) != 0
2189 && (flags
& (B_ACTIVATED
| B_PARTIALLY_ACTIVATED
)) == 0
2190 && ((flags
& (B_HOVER
| B_FOCUSED
)) == 0
2191 || (flags
& B_DISABLED
) != 0)) {
2192 _DrawFrame(view
, rect
, background
, background
, background
,
2193 background
, borders
);
2194 _DrawFrame(view
, rect
, background
, background
, background
,
2195 background
, borders
);
2200 // outer edge colors
2201 rgb_color edgeLightColor
;
2202 rgb_color edgeShadowColor
;
2204 // default button frame color
2205 rgb_color defaultIndicatorColor
= ui_color(B_CONTROL_BORDER_COLOR
);
2206 rgb_color cornerBgColor
;
2208 if ((flags
& B_DISABLED
) != 0) {
2209 defaultIndicatorColor
= disable_color(defaultIndicatorColor
,
2213 drawing_mode oldMode
= view
->DrawingMode();
2215 if ((flags
& B_DEFAULT_BUTTON
) != 0) {
2216 cornerBgColor
= defaultIndicatorColor
;
2217 edgeLightColor
= _EdgeLightColor(defaultIndicatorColor
,
2218 contrast
* ((flags
& B_DISABLED
) != 0 ? 0.3 : 0.8),
2219 brightness
* ((flags
& B_DISABLED
) != 0 ? 1.0 : 0.9), flags
);
2220 edgeShadowColor
= _EdgeShadowColor(defaultIndicatorColor
,
2221 contrast
* ((flags
& B_DISABLED
) != 0 ? 0.3 : 0.8),
2222 brightness
* ((flags
& B_DISABLED
) != 0 ? 1.0 : 0.9), flags
);
2224 // draw default button indicator
2225 // Allow a 1-pixel border of the background to come through.
2228 view
->SetHighColor(defaultIndicatorColor
);
2229 view
->StrokeRoundRect(rect
, leftTopRadius
, leftTopRadius
);
2232 view
->StrokeRoundRect(rect
, leftTopRadius
, leftTopRadius
);
2235 cornerBgColor
= background
;
2236 if ((flags
& B_BLEND_FRAME
) != 0) {
2237 // set the background color to transparent for the case
2238 // that we are on the desktop
2239 cornerBgColor
.alpha
= 0;
2240 view
->SetDrawingMode(B_OP_ALPHA
);
2243 edgeLightColor
= _EdgeLightColor(background
,
2244 contrast
* ((flags
& B_DISABLED
) != 0 ? 0.0 : 1.0),
2245 brightness
* 1.0, flags
);
2246 edgeShadowColor
= _EdgeShadowColor(background
,
2247 contrast
* (flags
& B_DISABLED
) != 0 ? 0.0 : 1.0,
2248 brightness
* 1.0, flags
);
2252 rgb_color frameLightColor
= _FrameLightColor(base
, flags
);
2253 rgb_color frameShadowColor
= _FrameShadowColor(base
, flags
);
2257 if ((borders
& B_LEFT_BORDER
) != 0 && (borders
& B_TOP_BORDER
) != 0
2258 && leftTopRadius
> 0) {
2259 // draw left top rounded corner
2260 BRect
leftTopCorner(floorf(rect
.left
), floorf(rect
.top
),
2261 floorf(rect
.left
+ leftTopRadius
),
2262 floorf(rect
.top
+ leftTopRadius
));
2263 clipping
.Exclude(leftTopCorner
);
2264 _DrawRoundCornerFrameLeftTop(view
, leftTopCorner
, updateRect
,
2265 cornerBgColor
, edgeShadowColor
, frameLightColor
);
2268 if ((borders
& B_TOP_BORDER
) != 0 && (borders
& B_RIGHT_BORDER
) != 0
2269 && rightTopRadius
> 0) {
2270 // draw right top rounded corner
2271 BRect
rightTopCorner(floorf(rect
.right
- rightTopRadius
),
2272 floorf(rect
.top
), floorf(rect
.right
),
2273 floorf(rect
.top
+ rightTopRadius
));
2274 clipping
.Exclude(rightTopCorner
);
2275 _DrawRoundCornerFrameRightTop(view
, rightTopCorner
, updateRect
,
2276 cornerBgColor
, edgeShadowColor
, edgeLightColor
,
2277 frameLightColor
, frameShadowColor
);
2280 if ((borders
& B_LEFT_BORDER
) != 0 && (borders
& B_BOTTOM_BORDER
) != 0
2281 && leftBottomRadius
> 0) {
2282 // draw left bottom rounded corner
2283 BRect
leftBottomCorner(floorf(rect
.left
),
2284 floorf(rect
.bottom
- leftBottomRadius
),
2285 floorf(rect
.left
+ leftBottomRadius
), floorf(rect
.bottom
));
2286 clipping
.Exclude(leftBottomCorner
);
2287 _DrawRoundCornerFrameLeftBottom(view
, leftBottomCorner
, updateRect
,
2288 cornerBgColor
, edgeShadowColor
, edgeLightColor
,
2289 frameLightColor
, frameShadowColor
);
2292 if ((borders
& B_RIGHT_BORDER
) != 0 && (borders
& B_BOTTOM_BORDER
) != 0
2293 && rightBottomRadius
> 0) {
2294 // draw right bottom rounded corner
2295 BRect
rightBottomCorner(floorf(rect
.right
- rightBottomRadius
),
2296 floorf(rect
.bottom
- rightBottomRadius
), floorf(rect
.right
),
2297 floorf(rect
.bottom
));
2298 clipping
.Exclude(rightBottomCorner
);
2299 _DrawRoundCornerFrameRightBottom(view
, rightBottomCorner
,
2300 updateRect
, cornerBgColor
, edgeLightColor
, frameShadowColor
);
2303 // clip out the corners
2304 view
->ConstrainClippingRegion(&clipping
);
2307 if ((flags
& B_DEFAULT_BUTTON
) != 0) {
2308 _DrawOuterResessedFrame(view
, rect
, defaultIndicatorColor
,
2309 contrast
* ((flags
& B_DISABLED
) != 0 ? 0.3 : 0.8),
2310 brightness
* ((flags
& B_DISABLED
) != 0 ? 1.0 : 0.9),
2313 _DrawOuterResessedFrame(view
, rect
, background
,
2314 contrast
* ((flags
& B_DISABLED
) != 0 ? 0.0 : 1.0),
2315 brightness
* 1.0, flags
, borders
);
2318 view
->SetDrawingMode(oldMode
);
2321 if ((flags
& B_BLEND_FRAME
) != 0) {
2322 drawing_mode oldDrawingMode
= view
->DrawingMode();
2323 view
->SetDrawingMode(B_OP_ALPHA
);
2325 _DrawFrame(view
, rect
, frameLightColor
, frameLightColor
,
2326 frameShadowColor
, frameShadowColor
, borders
);
2328 view
->SetDrawingMode(oldDrawingMode
);
2330 _DrawFrame(view
, rect
, frameLightColor
, frameLightColor
,
2331 frameShadowColor
, frameShadowColor
, borders
);
2334 // restore the clipping constraints of the view
2340 HaikuControlLook::_DrawOuterResessedFrame(BView
* view
, BRect
& rect
,
2341 const rgb_color
& base
, float contrast
, float brightness
, uint32 flags
,
2344 rgb_color edgeLightColor
= _EdgeLightColor(base
, contrast
,
2346 rgb_color edgeShadowColor
= _EdgeShadowColor(base
, contrast
,
2349 if ((flags
& B_BLEND_FRAME
) != 0) {
2350 // assumes the background has already been painted
2351 drawing_mode oldDrawingMode
= view
->DrawingMode();
2352 view
->SetDrawingMode(B_OP_ALPHA
);
2354 _DrawFrame(view
, rect
, edgeShadowColor
, edgeShadowColor
,
2355 edgeLightColor
, edgeLightColor
, borders
);
2357 view
->SetDrawingMode(oldDrawingMode
);
2359 _DrawFrame(view
, rect
, edgeShadowColor
, edgeShadowColor
,
2360 edgeLightColor
, edgeLightColor
, borders
);
2366 HaikuControlLook::_DrawFrame(BView
* view
, BRect
& rect
, const rgb_color
& left
,
2367 const rgb_color
& top
, const rgb_color
& right
, const rgb_color
& bottom
,
2370 view
->BeginLineArray(4);
2372 if (borders
& B_LEFT_BORDER
) {
2374 BPoint(rect
.left
, rect
.bottom
),
2375 BPoint(rect
.left
, rect
.top
), left
);
2378 if (borders
& B_TOP_BORDER
) {
2380 BPoint(rect
.left
, rect
.top
),
2381 BPoint(rect
.right
, rect
.top
), top
);
2384 if (borders
& B_RIGHT_BORDER
) {
2386 BPoint(rect
.right
, rect
.top
),
2387 BPoint(rect
.right
, rect
.bottom
), right
);
2390 if (borders
& B_BOTTOM_BORDER
) {
2392 BPoint(rect
.left
, rect
.bottom
),
2393 BPoint(rect
.right
, rect
.bottom
), bottom
);
2397 view
->EndLineArray();
2402 HaikuControlLook::_DrawFrame(BView
* view
, BRect
& rect
, const rgb_color
& left
,
2403 const rgb_color
& top
, const rgb_color
& right
, const rgb_color
& bottom
,
2404 const rgb_color
& rightTop
, const rgb_color
& leftBottom
, uint32 borders
)
2406 view
->BeginLineArray(6);
2408 if (borders
& B_TOP_BORDER
) {
2409 if (borders
& B_RIGHT_BORDER
) {
2411 BPoint(rect
.left
, rect
.top
),
2412 BPoint(rect
.right
- 1, rect
.top
), top
);
2414 BPoint(rect
.right
, rect
.top
),
2415 BPoint(rect
.right
, rect
.top
), rightTop
);
2418 BPoint(rect
.left
, rect
.top
),
2419 BPoint(rect
.right
, rect
.top
), top
);
2424 if (borders
& B_LEFT_BORDER
) {
2426 BPoint(rect
.left
, rect
.top
),
2427 BPoint(rect
.left
, rect
.bottom
- 1), left
);
2429 BPoint(rect
.left
, rect
.bottom
),
2430 BPoint(rect
.left
, rect
.bottom
), leftBottom
);
2434 if (borders
& B_BOTTOM_BORDER
) {
2436 BPoint(rect
.left
, rect
.bottom
),
2437 BPoint(rect
.right
, rect
.bottom
), bottom
);
2441 if (borders
& B_RIGHT_BORDER
) {
2443 BPoint(rect
.right
, rect
.bottom
),
2444 BPoint(rect
.right
, rect
.top
), right
);
2448 view
->EndLineArray();
2453 HaikuControlLook::_DrawButtonBackground(BView
* view
, BRect
& rect
,
2454 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
2455 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
2456 bool popupIndicator
, uint32 flags
, uint32 borders
, orientation orientation
)
2458 if (!rect
.IsValid())
2461 // save the clipping constraints of the view
2464 // set clipping constraints to updateRect
2465 BRegion
clipping(updateRect
);
2466 view
->ConstrainClippingRegion(&clipping
);
2468 // If the button is flat and neither activated nor otherwise highlighted
2469 // (mouse hovering or focussed), draw it flat.
2470 if ((flags
& B_FLAT
) != 0
2471 && (flags
& (B_ACTIVATED
| B_PARTIALLY_ACTIVATED
)) == 0
2472 && ((flags
& (B_HOVER
| B_FOCUSED
)) == 0
2473 || (flags
& B_DISABLED
) != 0)) {
2474 _DrawFlatButtonBackground(view
, rect
, updateRect
, base
, popupIndicator
,
2475 flags
, borders
, orientation
);
2477 _DrawNonFlatButtonBackground(view
, rect
, updateRect
, clipping
,
2478 leftTopRadius
, rightTopRadius
, leftBottomRadius
, rightBottomRadius
,
2479 base
, popupIndicator
, flags
, borders
, orientation
);
2482 // restore the clipping constraints of the view
2488 HaikuControlLook::_DrawFlatButtonBackground(BView
* view
, BRect
& rect
,
2489 const BRect
& updateRect
, const rgb_color
& base
, bool popupIndicator
,
2490 uint32 flags
, uint32 borders
, orientation orientation
)
2492 _DrawFrame(view
, rect
, base
, base
, base
, base
, borders
);
2493 // Not an actual frame, but the method insets our rect as needed.
2495 view
->SetHighColor(base
);
2496 view
->FillRect(rect
);
2498 if (popupIndicator
) {
2499 BRect
indicatorRect(rect
);
2500 rect
.right
-= kButtonPopUpIndicatorWidth
;
2501 indicatorRect
.left
= rect
.right
+ 3;
2502 // 2 pixels for the separator
2504 view
->SetHighColor(base
);
2505 view
->FillRect(indicatorRect
);
2507 _DrawPopUpMarker(view
, indicatorRect
, base
, flags
);
2513 HaikuControlLook::_DrawNonFlatButtonBackground(BView
* view
, BRect
& rect
,
2514 const BRect
& updateRect
, BRegion
& clipping
, float leftTopRadius
,
2515 float rightTopRadius
, float leftBottomRadius
, float rightBottomRadius
,
2516 const rgb_color
& base
, bool popupIndicator
, uint32 flags
, uint32 borders
,
2517 orientation orientation
)
2519 // inner bevel colors
2520 rgb_color bevelLightColor
= _BevelLightColor(base
, flags
);
2521 rgb_color bevelShadowColor
= _BevelShadowColor(base
, flags
);
2523 // button background color
2524 rgb_color buttonBgColor
;
2525 if ((flags
& B_DISABLED
) != 0)
2526 buttonBgColor
= tint_color(base
, 0.7);
2528 buttonBgColor
= tint_color(base
, B_LIGHTEN_1_TINT
);
2530 // surface top gradient
2531 BGradientLinear fillGradient
;
2532 _MakeButtonGradient(fillGradient
, rect
, base
, flags
, orientation
);
2536 if ((borders
& B_LEFT_BORDER
) != 0 && (borders
& B_TOP_BORDER
) != 0
2537 && leftTopRadius
> 0) {
2538 // draw left top rounded corner
2539 BRect
leftTopCorner(floorf(rect
.left
), floorf(rect
.top
),
2540 floorf(rect
.left
+ leftTopRadius
- 2.0),
2541 floorf(rect
.top
+ leftTopRadius
- 2.0));
2542 clipping
.Exclude(leftTopCorner
);
2543 _DrawRoundCornerBackgroundLeftTop(view
, leftTopCorner
, updateRect
,
2544 bevelLightColor
, fillGradient
);
2547 if ((borders
& B_TOP_BORDER
) != 0 && (borders
& B_RIGHT_BORDER
) != 0
2548 && rightTopRadius
> 0) {
2549 // draw right top rounded corner
2550 BRect
rightTopCorner(floorf(rect
.right
- rightTopRadius
+ 2.0),
2551 floorf(rect
.top
), floorf(rect
.right
),
2552 floorf(rect
.top
+ rightTopRadius
- 2.0));
2553 clipping
.Exclude(rightTopCorner
);
2554 _DrawRoundCornerBackgroundRightTop(view
, rightTopCorner
,
2555 updateRect
, bevelLightColor
, bevelShadowColor
, fillGradient
);
2558 if ((borders
& B_LEFT_BORDER
) != 0 && (borders
& B_BOTTOM_BORDER
) != 0
2559 && leftBottomRadius
> 0) {
2560 // draw left bottom rounded corner
2561 BRect
leftBottomCorner(floorf(rect
.left
),
2562 floorf(rect
.bottom
- leftBottomRadius
+ 2.0),
2563 floorf(rect
.left
+ leftBottomRadius
- 2.0),
2564 floorf(rect
.bottom
));
2565 clipping
.Exclude(leftBottomCorner
);
2566 _DrawRoundCornerBackgroundLeftBottom(view
, leftBottomCorner
,
2567 updateRect
, bevelLightColor
, bevelShadowColor
, fillGradient
);
2570 if ((borders
& B_RIGHT_BORDER
) != 0 && (borders
& B_BOTTOM_BORDER
) != 0
2571 && rightBottomRadius
> 0) {
2572 // draw right bottom rounded corner
2573 BRect
rightBottomCorner(floorf(rect
.right
- rightBottomRadius
+ 2.0),
2574 floorf(rect
.bottom
- rightBottomRadius
+ 2.0), floorf(rect
.right
),
2575 floorf(rect
.bottom
));
2576 clipping
.Exclude(rightBottomCorner
);
2577 _DrawRoundCornerBackgroundRightBottom(view
, rightBottomCorner
,
2578 updateRect
, bevelShadowColor
, fillGradient
);
2581 // clip out the corners
2582 view
->ConstrainClippingRegion(&clipping
);
2586 if ((flags
& B_ACTIVATED
) != 0) {
2587 view
->BeginLineArray(4);
2589 // shadow along left/top borders
2590 if (borders
& B_LEFT_BORDER
) {
2591 view
->AddLine(BPoint(rect
.left
, rect
.top
),
2592 BPoint(rect
.left
, rect
.bottom
), bevelLightColor
);
2595 if (borders
& B_TOP_BORDER
) {
2596 view
->AddLine(BPoint(rect
.left
, rect
.top
),
2597 BPoint(rect
.right
, rect
.top
), bevelLightColor
);
2601 // softer shadow along left/top borders
2602 if (borders
& B_LEFT_BORDER
) {
2603 view
->AddLine(BPoint(rect
.left
, rect
.top
),
2604 BPoint(rect
.left
, rect
.bottom
), bevelShadowColor
);
2607 if (borders
& B_TOP_BORDER
) {
2608 view
->AddLine(BPoint(rect
.left
, rect
.top
),
2609 BPoint(rect
.right
, rect
.top
), bevelShadowColor
);
2613 view
->EndLineArray();
2615 _DrawFrame(view
, rect
,
2616 bevelLightColor
, bevelLightColor
,
2617 bevelShadowColor
, bevelShadowColor
,
2618 buttonBgColor
, buttonBgColor
, borders
);
2621 if (popupIndicator
) {
2622 BRect
indicatorRect(rect
);
2623 rect
.right
-= kButtonPopUpIndicatorWidth
;
2624 indicatorRect
.left
= rect
.right
+ 3;
2625 // 2 pixels for the separator
2627 // Even when depressed we want the pop-up indicator background and
2628 // separator to cover the area up to the top.
2629 if ((flags
& B_ACTIVATED
) != 0)
2630 indicatorRect
.top
--;
2632 // draw the separator
2633 rgb_color separatorBaseColor
= base
;
2634 if ((flags
& B_ACTIVATED
) != 0)
2635 separatorBaseColor
= tint_color(base
, B_DARKEN_1_TINT
);
2637 rgb_color separatorLightColor
= _EdgeLightColor(separatorBaseColor
,
2638 (flags
& B_DISABLED
) != 0 ? 0.7 : 1.0, 1.0, flags
);
2639 rgb_color separatorShadowColor
= _EdgeShadowColor(separatorBaseColor
,
2640 (flags
& B_DISABLED
) != 0 ? 0.7 : 1.0, 1.0, flags
);
2642 view
->BeginLineArray(2);
2644 view
->AddLine(BPoint(indicatorRect
.left
- 2, indicatorRect
.top
),
2645 BPoint(indicatorRect
.left
- 2, indicatorRect
.bottom
),
2646 separatorShadowColor
);
2647 view
->AddLine(BPoint(indicatorRect
.left
- 1, indicatorRect
.top
),
2648 BPoint(indicatorRect
.left
- 1, indicatorRect
.bottom
),
2649 separatorLightColor
);
2651 view
->EndLineArray();
2653 // draw background and pop-up marker
2654 _DrawMenuFieldBackgroundInside(view
, indicatorRect
, updateRect
,
2655 0.0f
, rightTopRadius
, 0.0f
, rightBottomRadius
, base
, flags
, 0);
2657 if ((flags
& B_ACTIVATED
) != 0)
2658 indicatorRect
.top
++;
2660 _DrawPopUpMarker(view
, indicatorRect
, base
, flags
);
2663 // fill in the background
2664 view
->FillRect(rect
, fillGradient
);
2669 HaikuControlLook::_DrawPopUpMarker(BView
* view
, const BRect
& rect
,
2670 const rgb_color
& base
, uint32 flags
)
2672 BPoint
center(roundf((rect
.left
+ rect
.right
) / 2.0),
2673 roundf((rect
.top
+ rect
.bottom
) / 2.0));
2675 triangle
[0] = center
+ BPoint(-2.5, -0.5);
2676 triangle
[1] = center
+ BPoint(2.5, -0.5);
2677 triangle
[2] = center
+ BPoint(0.0, 2.0);
2679 uint32 viewFlags
= view
->Flags();
2680 view
->SetFlags(viewFlags
| B_SUBPIXEL_PRECISE
);
2682 rgb_color markColor
;
2683 if ((flags
& B_DISABLED
) != 0)
2684 markColor
= tint_color(base
, 1.35);
2686 markColor
= tint_color(base
, 1.65);
2688 view
->SetHighColor(markColor
);
2689 view
->FillTriangle(triangle
[0], triangle
[1], triangle
[2]);
2691 view
->SetFlags(viewFlags
);
2696 HaikuControlLook::_DrawMenuFieldBackgroundOutside(BView
* view
, BRect
& rect
,
2697 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
2698 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
2699 bool popupIndicator
, uint32 flags
)
2701 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
2704 if (popupIndicator
) {
2705 BRect
leftRect(rect
);
2706 leftRect
.right
-= 10;
2708 BRect
rightRect(rect
);
2709 rightRect
.left
= rightRect
.right
- 9;
2711 _DrawMenuFieldBackgroundInside(view
, leftRect
, updateRect
,
2712 leftTopRadius
, 0.0f
, leftBottomRadius
, 0.0f
, base
, flags
,
2713 B_LEFT_BORDER
| B_TOP_BORDER
| B_BOTTOM_BORDER
);
2715 _DrawMenuFieldBackgroundInside(view
, rightRect
, updateRect
,
2716 0.0f
, rightTopRadius
, 0.0f
, rightBottomRadius
, base
, flags
,
2717 B_TOP_BORDER
| B_RIGHT_BORDER
| B_BOTTOM_BORDER
);
2719 _DrawPopUpMarker(view
, rightRect
, base
, flags
);
2721 // draw a line on the left of the popup frame
2722 rgb_color bevelShadowColor
= _BevelShadowColor(base
, flags
);
2723 view
->SetHighColor(bevelShadowColor
);
2724 BPoint
leftTopCorner(floorf(rightRect
.left
- 1.0),
2725 floorf(rightRect
.top
- 1.0));
2726 BPoint
leftBottomCorner(floorf(rightRect
.left
- 1.0),
2727 floorf(rightRect
.bottom
+ 1.0));
2728 view
->StrokeLine(leftTopCorner
, leftBottomCorner
);
2732 _DrawMenuFieldBackgroundInside(view
, rect
, updateRect
, leftTopRadius
,
2733 rightTopRadius
, leftBottomRadius
, rightBottomRadius
, base
, flags
);
2739 HaikuControlLook::_DrawMenuFieldBackgroundInside(BView
* view
, BRect
& rect
,
2740 const BRect
& updateRect
, float leftTopRadius
, float rightTopRadius
,
2741 float leftBottomRadius
, float rightBottomRadius
, const rgb_color
& base
,
2742 uint32 flags
, uint32 borders
)
2744 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
2747 // save the clipping constraints of the view
2750 // set clipping constraints to updateRect
2751 BRegion
clipping(updateRect
);
2752 view
->ConstrainClippingRegion(&clipping
);
2755 rgb_color frameLightColor
= _FrameLightColor(base
, flags
);
2756 rgb_color frameShadowColor
= _FrameShadowColor(base
, flags
);
2758 // indicator background color
2759 rgb_color indicatorBase
;
2760 if ((borders
& B_LEFT_BORDER
) != 0)
2761 indicatorBase
= base
;
2763 if ((flags
& B_DISABLED
) != 0)
2764 indicatorBase
= tint_color(base
, 1.05);
2766 indicatorBase
= tint_color(base
, 1.12);
2770 rgb_color cornerColor
= tint_color(indicatorBase
, 0.85);
2771 rgb_color bevelColor1
= tint_color(indicatorBase
, 0.3);
2772 rgb_color bevelColor2
= tint_color(indicatorBase
, 0.5);
2773 rgb_color bevelColor3
= tint_color(indicatorBase
, 1.03);
2775 if ((flags
& B_DISABLED
) != 0) {
2776 cornerColor
= tint_color(indicatorBase
, 0.8);
2777 bevelColor1
= tint_color(indicatorBase
, 0.7);
2778 bevelColor2
= tint_color(indicatorBase
, 0.8);
2779 bevelColor3
= tint_color(indicatorBase
, 1.01);
2781 cornerColor
= tint_color(indicatorBase
, 0.85);
2782 bevelColor1
= tint_color(indicatorBase
, 0.3);
2783 bevelColor2
= tint_color(indicatorBase
, 0.5);
2784 bevelColor3
= tint_color(indicatorBase
, 1.03);
2787 // surface top gradient
2788 BGradientLinear fillGradient
;
2789 _MakeButtonGradient(fillGradient
, rect
, indicatorBase
, flags
);
2793 if ((borders
& B_LEFT_BORDER
) != 0 && (borders
& B_TOP_BORDER
) != 0
2794 && leftTopRadius
> 0) {
2795 // draw left top rounded corner
2796 BRect
leftTopCorner(floorf(rect
.left
), floorf(rect
.top
),
2797 floorf(rect
.left
+ leftTopRadius
- 2.0),
2798 floorf(rect
.top
+ leftTopRadius
- 2.0));
2799 clipping
.Exclude(leftTopCorner
);
2801 BRegion
cornerClipping(leftTopCorner
);
2802 view
->ConstrainClippingRegion(&cornerClipping
);
2804 BRect
ellipseRect(leftTopCorner
);
2805 ellipseRect
.InsetBy(-1.0, -1.0);
2806 ellipseRect
.right
= ellipseRect
.left
+ ellipseRect
.Width() * 2;
2807 ellipseRect
.bottom
= ellipseRect
.top
+ ellipseRect
.Height() * 2;
2809 // draw the frame (again)
2810 view
->SetHighColor(frameLightColor
);
2811 view
->FillEllipse(ellipseRect
);
2813 // draw the bevel and background
2814 _DrawRoundCornerBackgroundLeftTop(view
, leftTopCorner
, updateRect
,
2815 bevelColor1
, fillGradient
);
2818 if ((borders
& B_TOP_BORDER
) != 0 && (borders
& B_RIGHT_BORDER
) != 0
2819 && rightTopRadius
> 0) {
2820 // draw right top rounded corner
2821 BRect
rightTopCorner(floorf(rect
.right
- rightTopRadius
+ 2.0),
2822 floorf(rect
.top
), floorf(rect
.right
),
2823 floorf(rect
.top
+ rightTopRadius
- 2.0));
2824 clipping
.Exclude(rightTopCorner
);
2826 BRegion
cornerClipping(rightTopCorner
);
2827 view
->ConstrainClippingRegion(&cornerClipping
);
2829 BRect
ellipseRect(rightTopCorner
);
2830 ellipseRect
.InsetBy(-1.0, -1.0);
2831 ellipseRect
.left
= ellipseRect
.right
- ellipseRect
.Width() * 2;
2832 ellipseRect
.bottom
= ellipseRect
.top
+ ellipseRect
.Height() * 2;
2834 // draw the frame (again)
2835 if (frameLightColor
== frameShadowColor
) {
2836 view
->SetHighColor(frameLightColor
);
2837 view
->FillEllipse(ellipseRect
);
2839 BGradientLinear gradient
;
2840 gradient
.AddColor(frameLightColor
, 0);
2841 gradient
.AddColor(frameShadowColor
, 255);
2842 gradient
.SetStart(rightTopCorner
.LeftTop());
2843 gradient
.SetEnd(rightTopCorner
.RightBottom());
2844 view
->FillEllipse(ellipseRect
, gradient
);
2847 // draw the bevel and background
2848 _DrawRoundCornerBackgroundRightTop(view
, rightTopCorner
, updateRect
,
2849 bevelColor1
, bevelColor3
, fillGradient
);
2852 if ((borders
& B_LEFT_BORDER
) != 0 && (borders
& B_BOTTOM_BORDER
) != 0
2853 && leftBottomRadius
> 0) {
2854 // draw left bottom rounded corner
2855 BRect
leftBottomCorner(floorf(rect
.left
),
2856 floorf(rect
.bottom
- leftBottomRadius
+ 2.0),
2857 floorf(rect
.left
+ leftBottomRadius
- 2.0),
2858 floorf(rect
.bottom
));
2859 clipping
.Exclude(leftBottomCorner
);
2861 BRegion
cornerClipping(leftBottomCorner
);
2862 view
->ConstrainClippingRegion(&cornerClipping
);
2864 BRect
ellipseRect(leftBottomCorner
);
2865 ellipseRect
.InsetBy(-1.0, -1.0);
2866 ellipseRect
.right
= ellipseRect
.left
+ ellipseRect
.Width() * 2;
2867 ellipseRect
.top
= ellipseRect
.bottom
- ellipseRect
.Height() * 2;
2869 // draw the frame (again)
2870 if (frameLightColor
== frameShadowColor
) {
2871 view
->SetHighColor(frameLightColor
);
2872 view
->FillEllipse(ellipseRect
);
2874 BGradientLinear gradient
;
2875 gradient
.AddColor(frameLightColor
, 0);
2876 gradient
.AddColor(frameShadowColor
, 255);
2877 gradient
.SetStart(leftBottomCorner
.LeftTop());
2878 gradient
.SetEnd(leftBottomCorner
.RightBottom());
2879 view
->FillEllipse(ellipseRect
, gradient
);
2882 // draw the bevel and background
2883 _DrawRoundCornerBackgroundLeftBottom(view
, leftBottomCorner
,
2884 updateRect
, bevelColor2
, bevelColor3
, fillGradient
);
2887 if ((borders
& B_RIGHT_BORDER
) != 0 && (borders
& B_BOTTOM_BORDER
) != 0
2888 && rightBottomRadius
> 0) {
2889 // draw right bottom rounded corner
2890 BRect
rightBottomCorner(floorf(rect
.right
- rightBottomRadius
+ 2.0),
2891 floorf(rect
.bottom
- rightBottomRadius
+ 2.0), floorf(rect
.right
),
2892 floorf(rect
.bottom
));
2893 clipping
.Exclude(rightBottomCorner
);
2895 BRegion
cornerClipping(rightBottomCorner
);
2896 view
->ConstrainClippingRegion(&cornerClipping
);
2898 BRect
ellipseRect(rightBottomCorner
);
2899 ellipseRect
.InsetBy(-1.0, -1.0);
2900 ellipseRect
.left
= ellipseRect
.right
- ellipseRect
.Width() * 2;
2901 ellipseRect
.top
= ellipseRect
.bottom
- ellipseRect
.Height() * 2;
2903 // draw the frame (again)
2904 view
->SetHighColor(frameShadowColor
);
2905 view
->FillEllipse(ellipseRect
);
2907 // draw the bevel and background
2908 _DrawRoundCornerBackgroundRightBottom(view
, rightBottomCorner
,
2909 updateRect
, bevelColor3
, fillGradient
);
2912 // clip out the corners
2913 view
->ConstrainClippingRegion(&clipping
);
2916 _DrawFrame(view
, rect
,
2917 bevelColor2
, bevelColor1
,
2918 bevelColor3
, bevelColor3
,
2919 cornerColor
, cornerColor
,
2922 // fill in the background
2923 view
->FillRect(rect
, fillGradient
);
2925 // restore the clipping constraints of the view
2931 HaikuControlLook::_DrawRoundCornerLeftTop(BView
* view
, BRect
& cornerRect
,
2932 const BRect
& updateRect
, const rgb_color
& background
,
2933 const rgb_color
& edgeColor
, const rgb_color
& frameColor
,
2934 const rgb_color
& bevelColor
, const BGradientLinear
& fillGradient
)
2936 _DrawRoundCornerFrameLeftTop(view
, cornerRect
, updateRect
,
2937 background
, edgeColor
, frameColor
);
2938 _DrawRoundCornerBackgroundLeftTop(view
, cornerRect
, updateRect
,
2939 bevelColor
, fillGradient
);
2944 HaikuControlLook::_DrawRoundCornerFrameLeftTop(BView
* view
, BRect
& cornerRect
,
2945 const BRect
& updateRect
, const rgb_color
& background
,
2946 const rgb_color
& edgeColor
, const rgb_color
& frameColor
)
2948 // constrain clipping region to corner
2949 BRegion
clipping(cornerRect
);
2950 view
->ConstrainClippingRegion(&clipping
);
2953 view
->SetHighColor(background
);
2954 view
->FillRect(cornerRect
);
2957 BRect
ellipseRect(cornerRect
);
2958 ellipseRect
.right
= ellipseRect
.left
+ ellipseRect
.Width() * 2;
2959 ellipseRect
.bottom
= ellipseRect
.top
+ ellipseRect
.Height() * 2;
2961 view
->SetHighColor(edgeColor
);
2962 view
->FillEllipse(ellipseRect
);
2965 ellipseRect
.InsetBy(1, 1);
2968 view
->SetHighColor(frameColor
);
2969 view
->FillEllipse(ellipseRect
);
2971 // prepare for bevel
2978 HaikuControlLook::_DrawRoundCornerBackgroundLeftTop(BView
* view
, BRect
& cornerRect
,
2979 const BRect
& updateRect
, const rgb_color
& bevelColor
,
2980 const BGradientLinear
& fillGradient
)
2982 // constrain clipping region to corner
2983 BRegion
clipping(cornerRect
);
2984 view
->ConstrainClippingRegion(&clipping
);
2986 BRect
ellipseRect(cornerRect
);
2987 ellipseRect
.right
= ellipseRect
.left
+ ellipseRect
.Width() * 2;
2988 ellipseRect
.bottom
= ellipseRect
.top
+ ellipseRect
.Height() * 2;
2991 view
->SetHighColor(bevelColor
);
2992 view
->FillEllipse(ellipseRect
);
2995 ellipseRect
.InsetBy(1, 1);
2996 view
->FillEllipse(ellipseRect
, fillGradient
);
3001 HaikuControlLook::_DrawRoundCornerRightTop(BView
* view
, BRect
& cornerRect
,
3002 const BRect
& updateRect
, const rgb_color
& background
,
3003 const rgb_color
& edgeTopColor
, const rgb_color
& edgeRightColor
,
3004 const rgb_color
& frameTopColor
, const rgb_color
& frameRightColor
,
3005 const rgb_color
& bevelTopColor
, const rgb_color
& bevelRightColor
,
3006 const BGradientLinear
& fillGradient
)
3008 _DrawRoundCornerFrameRightTop(view
, cornerRect
, updateRect
,
3009 background
, edgeTopColor
, edgeRightColor
, frameTopColor
,
3011 _DrawRoundCornerBackgroundRightTop(view
, cornerRect
, updateRect
,
3012 bevelTopColor
, bevelRightColor
, fillGradient
);
3017 HaikuControlLook::_DrawRoundCornerFrameRightTop(BView
* view
, BRect
& cornerRect
,
3018 const BRect
& updateRect
, const rgb_color
& background
,
3019 const rgb_color
& edgeTopColor
, const rgb_color
& edgeRightColor
,
3020 const rgb_color
& frameTopColor
, const rgb_color
& frameRightColor
)
3022 // constrain clipping region to corner
3023 BRegion
clipping(cornerRect
);
3024 view
->ConstrainClippingRegion(&clipping
);
3027 view
->SetHighColor(background
);
3028 view
->FillRect(cornerRect
);
3031 BRect
ellipseRect(cornerRect
);
3032 ellipseRect
.left
= ellipseRect
.right
- ellipseRect
.Width() * 2;
3033 ellipseRect
.bottom
= ellipseRect
.top
+ ellipseRect
.Height() * 2;
3035 BGradientLinear gradient
;
3036 gradient
.AddColor(edgeTopColor
, 0);
3037 gradient
.AddColor(edgeRightColor
, 255);
3038 gradient
.SetStart(cornerRect
.LeftTop());
3039 gradient
.SetEnd(cornerRect
.RightBottom());
3040 view
->FillEllipse(ellipseRect
, gradient
);
3043 ellipseRect
.InsetBy(1, 1);
3046 if (frameTopColor
== frameRightColor
) {
3047 view
->SetHighColor(frameTopColor
);
3048 view
->FillEllipse(ellipseRect
);
3050 gradient
.SetColor(0, frameTopColor
);
3051 gradient
.SetColor(1, frameRightColor
);
3052 gradient
.SetStart(cornerRect
.LeftTop());
3053 gradient
.SetEnd(cornerRect
.RightBottom());
3054 view
->FillEllipse(ellipseRect
, gradient
);
3057 // prepare for bevel
3064 HaikuControlLook::_DrawRoundCornerBackgroundRightTop(BView
* view
, BRect
& cornerRect
,
3065 const BRect
& updateRect
, const rgb_color
& bevelTopColor
,
3066 const rgb_color
& bevelRightColor
, const BGradientLinear
& fillGradient
)
3068 // constrain clipping region to corner
3069 BRegion
clipping(cornerRect
);
3070 view
->ConstrainClippingRegion(&clipping
);
3072 BRect
ellipseRect(cornerRect
);
3073 ellipseRect
.left
= ellipseRect
.right
- ellipseRect
.Width() * 2;
3074 ellipseRect
.bottom
= ellipseRect
.top
+ ellipseRect
.Height() * 2;
3077 BGradientLinear gradient
;
3078 gradient
.AddColor(bevelTopColor
, 0);
3079 gradient
.AddColor(bevelRightColor
, 255);
3080 gradient
.SetStart(cornerRect
.LeftTop());
3081 gradient
.SetEnd(cornerRect
.RightBottom());
3082 view
->FillEllipse(ellipseRect
, gradient
);
3085 ellipseRect
.InsetBy(1, 1);
3086 view
->FillEllipse(ellipseRect
, fillGradient
);
3091 HaikuControlLook::_DrawRoundCornerLeftBottom(BView
* view
, BRect
& cornerRect
,
3092 const BRect
& updateRect
, const rgb_color
& background
,
3093 const rgb_color
& edgeLeftColor
, const rgb_color
& edgeBottomColor
,
3094 const rgb_color
& frameLeftColor
, const rgb_color
& frameBottomColor
,
3095 const rgb_color
& bevelLeftColor
, const rgb_color
& bevelBottomColor
,
3096 const BGradientLinear
& fillGradient
)
3098 _DrawRoundCornerFrameLeftBottom(view
, cornerRect
, updateRect
,
3099 background
, edgeLeftColor
, edgeBottomColor
, frameLeftColor
,
3101 _DrawRoundCornerBackgroundLeftBottom(view
, cornerRect
, updateRect
,
3102 bevelLeftColor
, bevelBottomColor
, fillGradient
);
3107 HaikuControlLook::_DrawRoundCornerFrameLeftBottom(BView
* view
, BRect
& cornerRect
,
3108 const BRect
& updateRect
, const rgb_color
& background
,
3109 const rgb_color
& edgeLeftColor
, const rgb_color
& edgeBottomColor
,
3110 const rgb_color
& frameLeftColor
, const rgb_color
& frameBottomColor
)
3112 // constrain clipping region to corner
3113 BRegion
clipping(cornerRect
);
3114 view
->ConstrainClippingRegion(&clipping
);
3117 view
->SetHighColor(background
);
3118 view
->FillRect(cornerRect
);
3121 BRect
ellipseRect(cornerRect
);
3122 ellipseRect
.right
= ellipseRect
.left
+ ellipseRect
.Width() * 2;
3123 ellipseRect
.top
= ellipseRect
.bottom
- ellipseRect
.Height() * 2;
3125 BGradientLinear gradient
;
3126 gradient
.AddColor(edgeLeftColor
, 0);
3127 gradient
.AddColor(edgeBottomColor
, 255);
3128 gradient
.SetStart(cornerRect
.LeftTop());
3129 gradient
.SetEnd(cornerRect
.RightBottom());
3130 view
->FillEllipse(ellipseRect
, gradient
);
3133 ellipseRect
.InsetBy(1, 1);
3135 cornerRect
.bottom
--;
3136 if (frameLeftColor
== frameBottomColor
) {
3137 view
->SetHighColor(frameLeftColor
);
3138 view
->FillEllipse(ellipseRect
);
3140 gradient
.SetColor(0, frameLeftColor
);
3141 gradient
.SetColor(1, frameBottomColor
);
3142 gradient
.SetStart(cornerRect
.LeftTop());
3143 gradient
.SetEnd(cornerRect
.RightBottom());
3144 view
->FillEllipse(ellipseRect
, gradient
);
3147 // prepare for bevel
3149 cornerRect
.bottom
--;
3154 HaikuControlLook::_DrawRoundCornerBackgroundLeftBottom(BView
* view
, BRect
& cornerRect
,
3155 const BRect
& updateRect
, const rgb_color
& bevelLeftColor
,
3156 const rgb_color
& bevelBottomColor
, const BGradientLinear
& fillGradient
)
3158 // constrain clipping region to corner
3159 BRegion
clipping(cornerRect
);
3160 view
->ConstrainClippingRegion(&clipping
);
3162 BRect
ellipseRect(cornerRect
);
3163 ellipseRect
.right
= ellipseRect
.left
+ ellipseRect
.Width() * 2;
3164 ellipseRect
.top
= ellipseRect
.bottom
- ellipseRect
.Height() * 2;
3167 BGradientLinear gradient
;
3168 gradient
.AddColor(bevelLeftColor
, 0);
3169 gradient
.AddColor(bevelBottomColor
, 255);
3170 gradient
.SetStart(cornerRect
.LeftTop());
3171 gradient
.SetEnd(cornerRect
.RightBottom());
3172 view
->FillEllipse(ellipseRect
, gradient
);
3175 ellipseRect
.InsetBy(1, 1);
3176 view
->FillEllipse(ellipseRect
, fillGradient
);
3181 HaikuControlLook::_DrawRoundCornerRightBottom(BView
* view
, BRect
& cornerRect
,
3182 const BRect
& updateRect
, const rgb_color
& background
,
3183 const rgb_color
& edgeColor
, const rgb_color
& frameColor
,
3184 const rgb_color
& bevelColor
, const BGradientLinear
& fillGradient
)
3186 _DrawRoundCornerFrameRightBottom(view
, cornerRect
, updateRect
,
3187 background
, edgeColor
, frameColor
);
3188 _DrawRoundCornerBackgroundRightBottom(view
, cornerRect
, updateRect
,
3189 bevelColor
, fillGradient
);
3194 HaikuControlLook::_DrawRoundCornerFrameRightBottom(BView
* view
, BRect
& cornerRect
,
3195 const BRect
& updateRect
, const rgb_color
& background
,
3196 const rgb_color
& edgeColor
, const rgb_color
& frameColor
)
3198 // constrain clipping region to corner
3199 BRegion
clipping(cornerRect
);
3200 view
->ConstrainClippingRegion(&clipping
);
3203 view
->SetHighColor(background
);
3204 view
->FillRect(cornerRect
);
3207 BRect
ellipseRect(cornerRect
);
3208 ellipseRect
.left
= ellipseRect
.right
- ellipseRect
.Width() * 2;
3209 ellipseRect
.top
= ellipseRect
.bottom
- ellipseRect
.Height() * 2;
3211 view
->SetHighColor(edgeColor
);
3212 view
->FillEllipse(ellipseRect
);
3215 ellipseRect
.InsetBy(1, 1);
3217 cornerRect
.bottom
--;
3218 view
->SetHighColor(frameColor
);
3219 view
->FillEllipse(ellipseRect
);
3221 // prepare for bevel
3223 cornerRect
.bottom
--;
3228 HaikuControlLook::_DrawRoundCornerBackgroundRightBottom(BView
* view
,
3229 BRect
& cornerRect
, const BRect
& updateRect
, const rgb_color
& bevelColor
,
3230 const BGradientLinear
& fillGradient
)
3232 // constrain clipping region to corner
3233 BRegion
clipping(cornerRect
);
3234 view
->ConstrainClippingRegion(&clipping
);
3236 BRect
ellipseRect(cornerRect
);
3237 ellipseRect
.left
= ellipseRect
.right
- ellipseRect
.Width() * 2;
3238 ellipseRect
.top
= ellipseRect
.bottom
- ellipseRect
.Height() * 2;
3241 view
->SetHighColor(bevelColor
);
3242 view
->FillEllipse(ellipseRect
);
3245 ellipseRect
.InsetBy(1, 1);
3246 view
->FillEllipse(ellipseRect
, fillGradient
);
3251 HaikuControlLook::_DrawRoundBarCorner(BView
* view
, BRect
& rect
,
3252 const BRect
& updateRect
,
3253 const rgb_color
& edgeLightColor
, const rgb_color
& edgeShadowColor
,
3254 const rgb_color
& frameLightColor
, const rgb_color
& frameShadowColor
,
3255 const rgb_color
& fillLightColor
, const rgb_color
& fillShadowColor
,
3256 float leftInset
, float topInset
, float rightInset
, float bottomInset
,
3257 orientation orientation
)
3259 if (!rect
.IsValid() || !rect
.Intersects(updateRect
))
3262 BGradientLinear gradient
;
3263 gradient
.AddColor(edgeShadowColor
, 0);
3264 gradient
.AddColor(edgeLightColor
, 255);
3265 gradient
.SetStart(rect
.LeftTop());
3266 if (orientation
== B_HORIZONTAL
)
3267 gradient
.SetEnd(rect
.LeftBottom());
3269 gradient
.SetEnd(rect
.RightTop());
3271 view
->FillEllipse(rect
, gradient
);
3273 rect
.left
+= leftInset
;
3274 rect
.top
+= topInset
;
3275 rect
.right
+= rightInset
;
3276 rect
.bottom
+= bottomInset
;
3278 gradient
.MakeEmpty();
3279 gradient
.AddColor(frameShadowColor
, 0);
3280 gradient
.AddColor(frameLightColor
, 255);
3281 gradient
.SetStart(rect
.LeftTop());
3282 if (orientation
== B_HORIZONTAL
)
3283 gradient
.SetEnd(rect
.LeftBottom());
3285 gradient
.SetEnd(rect
.RightTop());
3287 view
->FillEllipse(rect
, gradient
);
3289 rect
.left
+= leftInset
;
3290 rect
.top
+= topInset
;
3291 rect
.right
+= rightInset
;
3292 rect
.bottom
+= bottomInset
;
3294 gradient
.MakeEmpty();
3295 gradient
.AddColor(fillShadowColor
, 0);
3296 gradient
.AddColor(fillLightColor
, 255);
3297 gradient
.SetStart(rect
.LeftTop());
3298 if (orientation
== B_HORIZONTAL
)
3299 gradient
.SetEnd(rect
.LeftBottom());
3301 gradient
.SetEnd(rect
.RightTop());
3303 view
->FillEllipse(rect
, gradient
);
3308 HaikuControlLook::_EdgeLightColor(const rgb_color
& base
, float contrast
,
3309 float brightness
, uint32 flags
)
3311 rgb_color edgeLightColor
;
3313 if ((flags
& B_BLEND_FRAME
) != 0) {
3314 uint8 alpha
= uint8(20 * contrast
);
3315 uint8 white
= uint8(255 * brightness
);
3317 edgeLightColor
= (rgb_color
){ white
, white
, white
, alpha
};
3320 float tintLight
= kEdgeBevelLightTint
;
3322 if (contrast
== 0.0)
3323 tintLight
= B_NO_TINT
;
3324 else if (contrast
!= 1.0)
3325 tintLight
= B_NO_TINT
+ (tintLight
- B_NO_TINT
) * contrast
;
3327 edgeLightColor
= tint_color(base
, tintLight
);
3329 if (brightness
< 1.0) {
3330 edgeLightColor
.red
= uint8(edgeLightColor
.red
* brightness
);
3331 edgeLightColor
.green
= uint8(edgeLightColor
.green
* brightness
);
3332 edgeLightColor
.blue
= uint8(edgeLightColor
.blue
* brightness
);
3336 return edgeLightColor
;
3341 HaikuControlLook::_EdgeShadowColor(const rgb_color
& base
, float contrast
,
3342 float brightness
, uint32 flags
)
3344 rgb_color edgeShadowColor
;
3346 if ((flags
& B_BLEND_FRAME
) != 0) {
3347 uint8 alpha
= uint8(20 * contrast
);
3348 edgeShadowColor
= (rgb_color
){ 0, 0, 0, alpha
};
3350 float tintShadow
= kEdgeBevelShadowTint
;
3352 if (contrast
== 0.0)
3353 tintShadow
= B_NO_TINT
;
3354 else if (contrast
!= 1.0)
3355 tintShadow
= B_NO_TINT
+ (tintShadow
- B_NO_TINT
) * contrast
;
3357 edgeShadowColor
= tint_color(base
, tintShadow
);
3359 if (brightness
< 1.0) {
3360 edgeShadowColor
.red
= uint8(edgeShadowColor
.red
* brightness
);
3361 edgeShadowColor
.green
= uint8(edgeShadowColor
.green
* brightness
);
3362 edgeShadowColor
.blue
= uint8(edgeShadowColor
.blue
* brightness
);
3366 return edgeShadowColor
;
3371 HaikuControlLook::_FrameLightColor(const rgb_color
& base
, uint32 flags
)
3373 if ((flags
& B_FOCUSED
) != 0)
3374 return ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
3376 if ((flags
& B_ACTIVATED
) != 0)
3377 return _FrameShadowColor(base
, flags
& ~B_ACTIVATED
);
3379 rgb_color frameLightColor
;
3381 if ((flags
& B_DISABLED
) != 0) {
3382 // TODO: B_BLEND_FRAME
3383 frameLightColor
= tint_color(base
, 1.145);
3385 if ((flags
& B_DEFAULT_BUTTON
) != 0)
3386 frameLightColor
= tint_color(frameLightColor
, 1.14);
3388 if ((flags
& B_BLEND_FRAME
) != 0)
3389 frameLightColor
= (rgb_color
){ 0, 0, 0, 75 };
3391 frameLightColor
= tint_color(base
, 1.33);
3393 if ((flags
& B_DEFAULT_BUTTON
) != 0)
3394 frameLightColor
= tint_color(frameLightColor
, 1.35);
3397 return frameLightColor
;
3402 HaikuControlLook::_FrameShadowColor(const rgb_color
& base
, uint32 flags
)
3404 if ((flags
& B_FOCUSED
) != 0)
3405 return ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
3407 if ((flags
& B_ACTIVATED
) != 0)
3408 return _FrameLightColor(base
, flags
& ~B_ACTIVATED
);
3410 rgb_color frameShadowColor
;
3412 if ((flags
& B_DISABLED
) != 0) {
3413 // TODO: B_BLEND_FRAME
3414 frameShadowColor
= tint_color(base
, 1.24);
3416 if ((flags
& B_DEFAULT_BUTTON
) != 0) {
3417 frameShadowColor
= tint_color(base
, 1.145);
3418 frameShadowColor
= tint_color(frameShadowColor
, 1.12);
3421 if ((flags
& B_DEFAULT_BUTTON
) != 0) {
3422 if ((flags
& B_BLEND_FRAME
) != 0)
3423 frameShadowColor
= (rgb_color
){ 0, 0, 0, 75 };
3425 frameShadowColor
= tint_color(base
, 1.33);
3427 frameShadowColor
= tint_color(frameShadowColor
, 1.5);
3429 if ((flags
& B_BLEND_FRAME
) != 0)
3430 frameShadowColor
= (rgb_color
){ 0, 0, 0, 95 };
3432 frameShadowColor
= tint_color(base
, 1.47);
3436 return frameShadowColor
;
3441 HaikuControlLook::_BevelLightColor(const rgb_color
& base
, uint32 flags
)
3443 rgb_color bevelLightColor
= tint_color(base
, 0.2);
3445 if ((flags
& B_DISABLED
) != 0)
3446 bevelLightColor
= tint_color(base
, B_LIGHTEN_1_TINT
);
3448 if ((flags
& B_ACTIVATED
) != 0)
3449 bevelLightColor
= tint_color(base
, B_DARKEN_1_TINT
);
3451 return bevelLightColor
;
3456 HaikuControlLook::_BevelShadowColor(const rgb_color
& base
, uint32 flags
)
3458 rgb_color bevelShadowColor
= tint_color(base
, 1.08);
3460 if ((flags
& B_DISABLED
) != 0)
3461 bevelShadowColor
= base
;
3463 if ((flags
& B_ACTIVATED
) != 0)
3464 bevelShadowColor
= tint_color(base
, B_DARKEN_1_TINT
);
3466 return bevelShadowColor
;
3471 HaikuControlLook::_FillGradient(BView
* view
, const BRect
& rect
,
3472 const rgb_color
& base
, float topTint
, float bottomTint
,
3473 orientation orientation
)
3475 BGradientLinear gradient
;
3476 _MakeGradient(gradient
, rect
, base
, topTint
, bottomTint
, orientation
);
3477 view
->FillRect(rect
, gradient
);
3482 HaikuControlLook::_FillGlossyGradient(BView
* view
, const BRect
& rect
,
3483 const rgb_color
& base
, float topTint
, float middle1Tint
,
3484 float middle2Tint
, float bottomTint
, orientation orientation
)
3486 BGradientLinear gradient
;
3487 _MakeGlossyGradient(gradient
, rect
, base
, topTint
, middle1Tint
,
3488 middle2Tint
, bottomTint
, orientation
);
3489 view
->FillRect(rect
, gradient
);
3494 HaikuControlLook::_MakeGradient(BGradientLinear
& gradient
, const BRect
& rect
,
3495 const rgb_color
& base
, float topTint
, float bottomTint
,
3496 orientation orientation
) const
3498 gradient
.AddColor(tint_color(base
, topTint
), 0);
3499 gradient
.AddColor(tint_color(base
, bottomTint
), 255);
3500 gradient
.SetStart(rect
.LeftTop());
3501 if (orientation
== B_HORIZONTAL
)
3502 gradient
.SetEnd(rect
.LeftBottom());
3504 gradient
.SetEnd(rect
.RightTop());
3509 HaikuControlLook::_MakeGlossyGradient(BGradientLinear
& gradient
, const BRect
& rect
,
3510 const rgb_color
& base
, float topTint
, float middle1Tint
,
3511 float middle2Tint
, float bottomTint
,
3512 orientation orientation
) const
3514 gradient
.AddColor(tint_color(base
, topTint
), 0);
3515 gradient
.AddColor(tint_color(base
, middle1Tint
), 132);
3516 gradient
.AddColor(tint_color(base
, middle2Tint
), 136);
3517 gradient
.AddColor(tint_color(base
, bottomTint
), 255);
3518 gradient
.SetStart(rect
.LeftTop());
3519 if (orientation
== B_HORIZONTAL
)
3520 gradient
.SetEnd(rect
.LeftBottom());
3522 gradient
.SetEnd(rect
.RightTop());
3527 HaikuControlLook::_MakeButtonGradient(BGradientLinear
& gradient
, BRect
& rect
,
3528 const rgb_color
& base
, uint32 flags
, orientation orientation
) const
3530 float topTint
= 0.49;
3531 float middleTint1
= 0.62;
3532 float middleTint2
= 0.76;
3533 float bottomTint
= 0.90;
3535 if ((flags
& B_ACTIVATED
) != 0) {
3540 if ((flags
& B_DISABLED
) != 0) {
3541 topTint
= (topTint
+ B_NO_TINT
) / 2;
3542 middleTint1
= (middleTint1
+ B_NO_TINT
) / 2;
3543 middleTint2
= (middleTint2
+ B_NO_TINT
) / 2;
3544 bottomTint
= (bottomTint
+ B_NO_TINT
) / 2;
3545 } else if ((flags
& B_HOVER
) != 0) {
3546 topTint
*= kHoverTintFactor
;
3547 middleTint1
*= kHoverTintFactor
;
3548 middleTint2
*= kHoverTintFactor
;
3549 bottomTint
*= kHoverTintFactor
;
3552 if ((flags
& B_ACTIVATED
) != 0) {
3553 _MakeGradient(gradient
, rect
, base
, topTint
, bottomTint
, orientation
);
3555 _MakeGlossyGradient(gradient
, rect
, base
, topTint
, middleTint1
,
3556 middleTint2
, bottomTint
, orientation
);
3563 HaikuControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color
& base
,
3564 rgb_color
& color
, uint32 flags
) const
3566 if ((flags
& (B_ACTIVATED
| B_PARTIALLY_ACTIVATED
| B_CLICKED
)) == 0) {
3567 // no mark to be drawn at all
3571 color
= ui_color(B_CONTROL_MARK_COLOR
);
3575 if ((flags
& B_DISABLED
) != 0) {
3576 // activated, but disabled
3578 } else if ((flags
& B_CLICKED
) != 0) {
3579 if ((flags
& B_ACTIVATED
) != 0) {
3580 // losing activation
3583 // becoming activated (or losing partial activation)
3586 } else if ((flags
& B_PARTIALLY_ACTIVATED
) != 0) {
3587 // partially activated
3593 color
.red
= uint8(color
.red
* mix
+ base
.red
* (1.0 - mix
));
3594 color
.green
= uint8(color
.green
* mix
+ base
.green
* (1.0 - mix
));
3595 color
.blue
= uint8(color
.blue
* mix
+ base
.blue
* (1.0 - mix
));
3601 } // namespace BPrivate