2 * Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
11 #include <MessageRunner.h>
14 const uint32 kMsgPulse
= 'puls';
16 const bigtime_t kMinPulseInterval
= 100000;
17 const bigtime_t kMaxPulseInterval
= 300000;
18 const float kMinStep
= 3.f
;
21 RadioView::RadioView(BRect frame
, const char* name
, int32 resizingMode
)
23 BView(frame
, name
, resizingMode
,
24 B_FULL_UPDATE_ON_RESIZE
| B_WILL_DRAW
| B_FRAME_EVENTS
),
33 RadioView::~RadioView()
39 RadioView::SetPercent(int32 percent
)
46 if (percent
== fPercent
)
55 RadioView::SetMax(int32 max
)
70 RadioView::StartPulsing()
78 RadioView::StopPulsing()
91 RadioView::Draw(BView
* view
, BRect rect
, int32 percent
, int32 maxCount
)
98 _Compute(rect
, center
, count
, maxCount
, step
);
100 for (int32 i
= 0; i
< count
; i
++) {
101 _SetColor(view
, percent
, 0, i
, count
);
102 _DrawBow(view
, i
, center
, count
, step
);
109 RadioView::DefaultMax()
116 RadioView::AttachedToWindow()
118 if (Parent() != NULL
)
119 SetViewColor(Parent()->ViewColor());
121 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
126 RadioView::DetachedFromWindow()
133 RadioView::MessageReceived(BMessage
* message
)
135 switch (message
->what
) {
142 BView::MessageReceived(message
);
149 RadioView::Draw(BRect updateRect
)
151 SetLowColor(ViewColor());
156 _Compute(Bounds(), center
, count
, fMax
, step
);
158 for (int32 i
= 0; i
< count
; i
++) {
159 _SetColor(this, fPercent
, fPhase
, i
, count
);
160 if (step
== kMinStep
&& _IsDisabled(fPercent
, i
, count
))
163 _DrawBow(this, i
, center
, count
, step
);
169 RadioView::FrameResized(float /*width*/, float /*height*/)
177 RadioView::_RestartPulsing()
181 // The pulse speed depends on the size of the view
185 _Compute(Bounds(), center
, count
, fMax
, step
);
187 BMessage
message(kMsgPulse
);
188 fPulse
= new BMessageRunner(this, &message
, (bigtime_t
)(kMinPulseInterval
189 + (kMaxPulseInterval
- kMinPulseInterval
) / step
), -1);
194 RadioView::_Compute(const BRect
& bounds
, BPoint
& center
, int32
& count
,
195 int32 max
, float& step
)
197 center
.Set(roundf(bounds
.Width() / 2), bounds
.bottom
);
198 float size
= min_c(center
.x
* 3 / 2, center
.y
);
199 step
= floorf(size
/ max
);
200 if (step
< kMinStep
) {
201 count
= (int32
)(size
/ kMinStep
);
206 center
.x
+= bounds
.left
;
211 RadioView::_DrawBow(BView
* view
, int32 index
, const BPoint
& center
,
212 int32 count
, float step
)
214 float radius
= step
* index
+ 1;
217 view
->SetPenSize(step
/ 2);
219 view
->SetPenSize(step
* 2 / 3);
221 view
->SetLineMode(B_ROUND_CAP
, B_ROUND_JOIN
);
222 view
->StrokeArc(center
, radius
, radius
, 50, 80);
227 RadioView::_SetColor(BView
* view
, int32 percent
, int32 phase
, int32 index
,
230 if (_IsDisabled(percent
, index
, count
)) {
232 view
->SetHighColor(tint_color(view
->LowColor(), B_DARKEN_1_TINT
));
233 } else if (phase
== 0 || phase
% count
!= index
) {
235 view
->SetHighColor(tint_color(view
->LowColor(), B_DARKEN_3_TINT
));
238 view
->SetHighColor(tint_color(view
->LowColor(), B_DARKEN_2_TINT
));
244 RadioView::_IsDisabled(int32 percent
, int32 index
, int32 count
)
246 return percent
< 100 * index
/ count
;