1 /*
2 * Copyright 2010, Stephan Aßmus <superstippi@gmx.de>.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include "SymbolButton.h"
8
9 #include <GradientLinear.h>
10 #include <LayoutUtils.h>
11 #include <Shape.h>
12
13
14 static const rgb_color kGreen = (rgb_color){ 116, 224, 0, 255 };
15
16
17 // constructor
SymbolButton(const char * name,BShape * symbolShape,BMessage * message,uint32 borders)18 SymbolButton::SymbolButton(const char* name, BShape* symbolShape,
19 BMessage* message, uint32 borders)
20 :
21 BButton(name, NULL, message),
22 fSymbol(symbolShape),
23 fBorders(borders)
24 {
25 }
26
27
~SymbolButton()28 SymbolButton::~SymbolButton()
29 {
30 delete fSymbol;
31 }
32
33
34 void
Draw(BRect updateRect)35 SymbolButton::Draw(BRect updateRect)
36 {
37 uint32 flags = be_control_look->Flags(this);
38 rgb_color base = LowColor();
39 BRect bounds(Bounds());
40
41 if (fBorders != 0) {
42 be_control_look->DrawButtonFrame(this, bounds, updateRect, base,
43 base, flags & ~BControlLook::B_DISABLED, fBorders);
44 be_control_look->DrawButtonBackground(this, bounds, updateRect, base,
45 flags);
46 }
47
48 if (fSymbol == NULL)
49 return;
50
51 if (IsEnabled()) {
52 if (Value() == B_CONTROL_ON)
53 base = tint_color(base, (B_DARKEN_4_TINT + B_DARKEN_MAX_TINT) / 2);
54 else
55 base = tint_color(base, B_DARKEN_4_TINT);
56 } else {
57 if (Value() == B_CONTROL_ON)
58 base = tint_color(base, B_DARKEN_2_TINT);
59 else
60 base = tint_color(base, B_DARKEN_1_TINT);
61 }
62
63 BPoint offset;
64 offset.x = (bounds.left + bounds.right) / 2;
65 offset.y = (bounds.top + bounds.bottom) / 2;
66 offset.x -= fSymbol->Bounds().Width() / 2;
67 offset.y -= fSymbol->Bounds().Height() / 2;
68 offset.x = floorf(offset.x - fSymbol->Bounds().left);
69 offset.y = ceilf(offset.y - fSymbol->Bounds().top);
70
71 MovePenTo(offset);
72 BGradientLinear gradient;
73 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0);
74 gradient.AddColor(base, 255);
75 gradient.SetStart(offset);
76 offset.y += fSymbol->Bounds().Height();
77 gradient.SetEnd(offset);
78 FillShape(fSymbol, gradient);
79 }
80
81
82 BSize
MinSize()83 SymbolButton::MinSize()
84 {
85 if (fSymbol == NULL)
86 return BButton::MinSize();
87
88 float scale = fBorders != 0 ? 2.5f : 1.0f;
89
90 BSize size;
91 size.width = ceilf(fSymbol->Bounds().Width() * scale);
92 size.height = ceilf(fSymbol->Bounds().Height() * scale);
93 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
94 }
95
96
97 BSize
MaxSize()98 SymbolButton::MaxSize()
99 {
100 BSize size(MinSize());
101 if (fBorders != 0)
102 size.width = ceilf(size.width * 1.5f);
103 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
104 }
105
106
107 void
SetSymbol(BShape * symbolShape)108 SymbolButton::SetSymbol(BShape* symbolShape)
109 {
110 BSize oldSize = MinSize();
111
112 delete fSymbol;
113 fSymbol = symbolShape;
114
115 if (MinSize() != oldSize)
116 InvalidateLayout();
117
118 Invalidate();
119 }
120
121