xref: /haiku/src/apps/mediaplayer/interface/PlayPauseButton.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
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
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 
30 PlayPauseButton::~PlayPauseButton()
31 {
32 	delete fPlaySymbol;
33 	delete fPauseSymbol;
34 }
35 
36 
37 void
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
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
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
147 PlayPauseButton::SetPlaying()
148 {
149 	_SetPlaybackState(kPlaying);
150 }
151 
152 
153 void
154 PlayPauseButton::SetPaused()
155 {
156 	_SetPlaybackState(kPaused);
157 }
158 
159 
160 void
161 PlayPauseButton::SetStopped()
162 {
163 	_SetPlaybackState(kStopped);
164 }
165 
166 
167 void
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
185 PlayPauseButton::_SetPlaybackState(uint32 state)
186 {
187 	if (fPlaybackState == state)
188 		return;
189 	fPlaybackState = state;
190 	Invalidate();
191 }
192