1 /*
2 * Copyright 2010, Stephan Aßmus <superstippi@gmx.de>.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include "PlayPauseButton.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
PlayPauseButton(const char * name,BShape * playSymbolShape,BShape * pauseSymbolShape,BMessage * message,uint32 borders)18 PlayPauseButton::PlayPauseButton(const char* name,
19 BShape* playSymbolShape, BShape* pauseSymbolShape, BMessage* message,
20 uint32 borders)
21 :
22 SymbolButton(name, NULL, message, borders),
23 fPlaySymbol(playSymbolShape),
24 fPauseSymbol(pauseSymbolShape),
25 fPlaybackState(kStopped)
26 {
27 }
28
29
~PlayPauseButton()30 PlayPauseButton::~PlayPauseButton()
31 {
32 delete fPlaySymbol;
33 delete fPauseSymbol;
34 }
35
36
37 void
Draw(BRect updateRect)38 PlayPauseButton::Draw(BRect updateRect)
39 {
40 SymbolButton::Draw(updateRect);
41
42 rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
43 rgb_color active = (rgb_color){ 116, 224, 0, 255 };
44
45 if (IsEnabled()) {
46 if (Value() == B_CONTROL_ON)
47 base = tint_color(base, (B_DARKEN_4_TINT + B_DARKEN_MAX_TINT) / 2);
48 else
49 base = tint_color(base, B_DARKEN_4_TINT);
50 } else {
51 if (Value() == B_CONTROL_ON)
52 base = tint_color(base, B_DARKEN_2_TINT);
53 else
54 base = tint_color(base, B_DARKEN_1_TINT);
55 }
56 BRect bounds(Bounds());
57 BRect pauseBounds = fPauseSymbol->Bounds();
58 BRect playBounds = fPlaySymbol->Bounds();
59
60 BPoint offset;
61 float spacing = pauseBounds.Height() / 4;
62 offset.x = (bounds.left + bounds.right) / 2;
63 offset.y = (bounds.top + bounds.bottom) / 2;
64 offset.x -= (pauseBounds.Width() + playBounds.Width() + spacing) / 2;
65 offset.y -= pauseBounds.Height() / 2;
66 offset.x = floorf(offset.x - playBounds.left + 0.5);
67 offset.y = ceilf(offset.y - pauseBounds.top);
68 if (Value() == B_CONTROL_ON) {
69 offset.x += 1;
70 offset.y += 1;
71 }
72
73 bool playActive = IsEnabled()
74 && ((fPlaybackState == kPlaying && Value() == B_CONTROL_OFF)
75 || (fPlaybackState == kPaused && Value() == B_CONTROL_ON));
76 bool pauseActive = IsEnabled()
77 && ((fPlaybackState == kPaused && Value() == B_CONTROL_OFF)
78 || (fPlaybackState == kPlaying && Value() == B_CONTROL_ON));
79
80 MovePenTo(offset);
81 BGradientLinear gradient;
82 if (playActive) {
83 gradient.AddColor(active, 0);
84 gradient.AddColor(tint_color(active, B_LIGHTEN_1_TINT), 255);
85 } else {
86 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0);
87 gradient.AddColor(base, 255);
88 }
89 gradient.SetStart(offset);
90 offset.y += playBounds.Height();
91 gradient.SetEnd(offset);
92 FillShape(fPlaySymbol, gradient);
93 if (playActive) {
94 SetHighColor(tint_color(active, B_DARKEN_3_TINT));
95 MovePenBy(0.5, 0.5);
96 StrokeShape(fPlaySymbol);
97 }
98
99 offset.y -= playBounds.Height();
100 offset.x += ceilf(playBounds.Width() + spacing);
101 MovePenTo(offset);
102 gradient.MakeEmpty();
103 if (pauseActive) {
104 gradient.AddColor(active, 0);
105 gradient.AddColor(tint_color(active, B_LIGHTEN_1_TINT), 255);
106 } else {
107 gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0);
108 gradient.AddColor(base, 255);
109 }
110 gradient.SetStart(offset);
111 offset.y += playBounds.Height();
112 gradient.SetEnd(offset);
113 FillShape(fPauseSymbol, gradient);
114 if (pauseActive) {
115 SetHighColor(tint_color(active, B_DARKEN_3_TINT));
116 MovePenBy(0.5, 0.5);
117 StrokeShape(fPauseSymbol);
118 }
119 }
120
121
122 BSize
MinSize()123 PlayPauseButton::MinSize()
124 {
125 if (fPauseSymbol == NULL || fPlaySymbol == NULL)
126 return BButton::MinSize();
127
128 BSize size;
129 size.width = ceilf(
130 (fPlaySymbol->Bounds().Width() + fPauseSymbol->Bounds().Width())
131 * 2.5f);
132 size.height = ceilf(fPauseSymbol->Bounds().Height() * 2.5f);
133 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
134 }
135
136
137 BSize
MaxSize()138 PlayPauseButton::MaxSize()
139 {
140 BSize size(MinSize());
141 size.width = ceilf(size.width * 1.5f);
142 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
143 }
144
145
146 void
SetPlaying()147 PlayPauseButton::SetPlaying()
148 {
149 _SetPlaybackState(kPlaying);
150 }
151
152
153 void
SetPaused()154 PlayPauseButton::SetPaused()
155 {
156 _SetPlaybackState(kPaused);
157 }
158
159
160 void
SetStopped()161 PlayPauseButton::SetStopped()
162 {
163 _SetPlaybackState(kStopped);
164 }
165
166
167 void
SetSymbols(BShape * playSymbolShape,BShape * pauseSymbolShape)168 PlayPauseButton::SetSymbols(BShape* playSymbolShape, BShape* pauseSymbolShape)
169 {
170 BSize oldSize = MinSize();
171
172 delete fPlaySymbol;
173 fPlaySymbol = playSymbolShape;
174 delete fPauseSymbol;
175 fPauseSymbol = pauseSymbolShape;
176
177 if (MinSize() != oldSize)
178 InvalidateLayout();
179
180 Invalidate();
181 }
182
183
184 void
_SetPlaybackState(uint32 state)185 PlayPauseButton::_SetPlaybackState(uint32 state)
186 {
187 if (fPlaybackState == state)
188 return;
189 fPlaybackState = state;
190 Invalidate();
191 }
192