xref: /haiku/src/kits/interface/StatusBar.cpp (revision 075e65c78c3e3d3ead275359deeb108b61a665ee)
199f695c9SAxel Dörfler /*
299f695c9SAxel Dörfler  * Copyright 2001-2006, Haiku.
399f695c9SAxel Dörfler  * Distributed under the terms of the MIT License.
499f695c9SAxel Dörfler  *
599f695c9SAxel Dörfler  * Authors:
699f695c9SAxel Dörfler  *		Marc Flerackers (mflerackers@androme.be)
7*075e65c7SAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
899f695c9SAxel Dörfler  */
999f695c9SAxel Dörfler 
1099f695c9SAxel Dörfler /*! BStatusBar displays a "percentage-of-completion" gauge. */
1152a38012Sejakowatz 
1252a38012Sejakowatz #include <Message.h>
13*075e65c7SAxel Dörfler #include <Region.h>
143583227cSStefano Ceccherini #include <StatusBar.h>
1552a38012Sejakowatz 
1699f695c9SAxel Dörfler #include <stdlib.h>
1799f695c9SAxel Dörfler #include <string.h>
1899f695c9SAxel Dörfler 
1952a38012Sejakowatz 
20*075e65c7SAxel Dörfler static const rgb_color kDefaultBarColor = {50, 150, 255, 255};
21*075e65c7SAxel Dörfler 
22*075e65c7SAxel Dörfler 
2352a38012Sejakowatz BStatusBar::BStatusBar(BRect frame, const char *name, const char *label,
2452a38012Sejakowatz 					   const char *trailingLabel)
25eb997429SMarc Flerackers 	: BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
26*075e65c7SAxel Dörfler 	fLabel(label),
27*075e65c7SAxel Dörfler 	fTrailingLabel(trailingLabel)
2852a38012Sejakowatz {
29*075e65c7SAxel Dörfler 	_InitObject();
3052a38012Sejakowatz }
313583227cSStefano Ceccherini 
323583227cSStefano Ceccherini 
3352a38012Sejakowatz BStatusBar::BStatusBar(BMessage *archive)
34*075e65c7SAxel Dörfler 	: BView(archive)
3552a38012Sejakowatz {
36*075e65c7SAxel Dörfler 	_InitObject();
373583227cSStefano Ceccherini 
38*075e65c7SAxel Dörfler 	archive->FindString("_label", &fLabel);
39*075e65c7SAxel Dörfler 	archive->FindString("_tlabel", &fTrailingLabel);
403583227cSStefano Ceccherini 
41*075e65c7SAxel Dörfler 	archive->FindString("_text", &fText);
42*075e65c7SAxel Dörfler 	archive->FindString("_ttext", &fTrailingText);
4352a38012Sejakowatz 
44*075e65c7SAxel Dörfler 	float floatValue;
45*075e65c7SAxel Dörfler 	if (archive->FindFloat("_high", &floatValue) == B_OK) {
46*075e65c7SAxel Dörfler 		fBarHeight = floatValue;
47*075e65c7SAxel Dörfler 		fCustomBarHeight = true;
48*075e65c7SAxel Dörfler 	}
4952a38012Sejakowatz 
50*075e65c7SAxel Dörfler 	int32 color;
51*075e65c7SAxel Dörfler 	if (archive->FindInt32("_bcolor", (int32 *)&color) == B_OK)
52*075e65c7SAxel Dörfler 		fBarColor = *(rgb_color *)&color;
5352a38012Sejakowatz 
54*075e65c7SAxel Dörfler 	if (archive->FindFloat("_val", &floatValue) == B_OK)
55*075e65c7SAxel Dörfler 		fCurrent = floatValue;
56*075e65c7SAxel Dörfler 	if (archive->FindFloat("_max", &floatValue) == B_OK)
57*075e65c7SAxel Dörfler 		fMax = floatValue;
5852a38012Sejakowatz }
593583227cSStefano Ceccherini 
603583227cSStefano Ceccherini 
6152a38012Sejakowatz BStatusBar::~BStatusBar()
6252a38012Sejakowatz {
63*075e65c7SAxel Dörfler }
64*075e65c7SAxel Dörfler 
65*075e65c7SAxel Dörfler 
66*075e65c7SAxel Dörfler void
67*075e65c7SAxel Dörfler BStatusBar::_InitObject()
68*075e65c7SAxel Dörfler {
69*075e65c7SAxel Dörfler 	fMax = 100.0f;
70*075e65c7SAxel Dörfler 	fCurrent = 0.0f;
71*075e65c7SAxel Dörfler 
72*075e65c7SAxel Dörfler 	fBarHeight = -1.0f;
73*075e65c7SAxel Dörfler 	fTextWidth = 0.0f;
74*075e65c7SAxel Dörfler 	fLabelWidth = 0.0f;
75*075e65c7SAxel Dörfler 	fTrailingTextWidth = 0.0f;
76*075e65c7SAxel Dörfler 	fTrailingLabelWidth = 0.0f;
77*075e65c7SAxel Dörfler 
78*075e65c7SAxel Dörfler 	fBarColor = kDefaultBarColor;
79*075e65c7SAxel Dörfler 	fCustomBarHeight = false;
8052a38012Sejakowatz }
813583227cSStefano Ceccherini 
823583227cSStefano Ceccherini 
833583227cSStefano Ceccherini BArchivable *
843583227cSStefano Ceccherini BStatusBar::Instantiate(BMessage *archive)
8552a38012Sejakowatz {
8652a38012Sejakowatz 	if (validate_instantiation(archive, "BStatusBar"))
8752a38012Sejakowatz 		return new BStatusBar(archive);
8852a38012Sejakowatz 
8952a38012Sejakowatz 	return NULL;
9052a38012Sejakowatz }
913583227cSStefano Ceccherini 
923583227cSStefano Ceccherini 
933583227cSStefano Ceccherini status_t
943583227cSStefano Ceccherini BStatusBar::Archive(BMessage *archive, bool deep) const
9552a38012Sejakowatz {
968f3e1554SMarc Flerackers 	status_t err = BView::Archive(archive, deep);
973583227cSStefano Ceccherini 	if (err < B_OK)
988f3e1554SMarc Flerackers 		return err;
9952a38012Sejakowatz 
100*075e65c7SAxel Dörfler 	if (fCustomBarHeight)
1018f3e1554SMarc Flerackers 		err = archive->AddFloat("_high", fBarHeight);
1028f3e1554SMarc Flerackers 
103*075e65c7SAxel Dörfler 	if (err == B_OK && fBarColor != kDefaultBarColor)
10430d24296SMarcus Overhagen 		err = archive->AddInt32("_bcolor", (const uint32 &)fBarColor);
1058f3e1554SMarc Flerackers 
106*075e65c7SAxel Dörfler 	if (err == B_OK && fCurrent != 0.0f)
1078f3e1554SMarc Flerackers 		err = archive->AddFloat("_val", fCurrent);
108*075e65c7SAxel Dörfler 	if (err == B_OK && fMax != 100.0f )
1098f3e1554SMarc Flerackers 		err = archive->AddFloat("_max", fMax);
1108f3e1554SMarc Flerackers 
111*075e65c7SAxel Dörfler 	if (err == B_OK && fText.Length())
1128f3e1554SMarc Flerackers 		err = archive->AddString("_text", fText);
113*075e65c7SAxel Dörfler 	if (err == B_OK && fTrailingText.Length())
1148f3e1554SMarc Flerackers 		err = archive->AddString("_ttext", fTrailingText);
1158f3e1554SMarc Flerackers 
116*075e65c7SAxel Dörfler 	if (err == B_OK && fLabel.Length())
1178f3e1554SMarc Flerackers 		err = archive->AddString("_label", fLabel);
118*075e65c7SAxel Dörfler 	if (err == B_OK && fTrailingLabel.Length())
1198f3e1554SMarc Flerackers 		err = archive->AddString ("_tlabel", fTrailingLabel);
12052a38012Sejakowatz 
1218f3e1554SMarc Flerackers 	return err;
12252a38012Sejakowatz }
1233583227cSStefano Ceccherini 
1243583227cSStefano Ceccherini 
1253583227cSStefano Ceccherini void
1263583227cSStefano Ceccherini BStatusBar::AttachedToWindow()
12752a38012Sejakowatz {
128*075e65c7SAxel Dörfler 	// resize so that the height fits
12952a38012Sejakowatz 	float width, height;
13052a38012Sejakowatz 	GetPreferredSize(&width, &height);
131*075e65c7SAxel Dörfler 	ResizeTo(Bounds().Width(), height);
13252a38012Sejakowatz 
133*075e65c7SAxel Dörfler 	SetViewColor(B_TRANSPARENT_COLOR);
134*075e65c7SAxel Dörfler 
135*075e65c7SAxel Dörfler 	if (Parent())
136b7b28df0Shaydentech 		SetLowColor(Parent()->ViewColor());
137*075e65c7SAxel Dörfler 
138*075e65c7SAxel Dörfler 	fLabelWidth = ceilf(StringWidth(fLabel.String()));
139*075e65c7SAxel Dörfler 	fTrailingLabelWidth = ceilf(StringWidth(fTrailingLabel.String()));
140*075e65c7SAxel Dörfler 	fTextWidth = ceilf(StringWidth(fText.String()));
141*075e65c7SAxel Dörfler 	fTrailingTextWidth = ceilf(StringWidth(fTrailingText.String()));
14252a38012Sejakowatz }
1433583227cSStefano Ceccherini 
1443583227cSStefano Ceccherini 
1453583227cSStefano Ceccherini void
1463583227cSStefano Ceccherini BStatusBar::MessageReceived(BMessage *message)
14752a38012Sejakowatz {
1483583227cSStefano Ceccherini 	switch(message->what) {
14952a38012Sejakowatz 		case B_UPDATE_STATUS_BAR:
15052a38012Sejakowatz 		{
15152a38012Sejakowatz 			float delta;
15252a38012Sejakowatz 			const char *text = NULL, *trailing_text = NULL;
15352a38012Sejakowatz 
15452a38012Sejakowatz 			message->FindFloat("delta", &delta);
15552a38012Sejakowatz 			message->FindString("text", &text);
156ec053666SStefano Ceccherini 			message->FindString("trailing_text", &trailing_text);
15752a38012Sejakowatz 
15852a38012Sejakowatz 			Update(delta, text, trailing_text);
15952a38012Sejakowatz 
16052a38012Sejakowatz 			break;
16152a38012Sejakowatz 		}
1623583227cSStefano Ceccherini 
16352a38012Sejakowatz 		case B_RESET_STATUS_BAR:
16452a38012Sejakowatz 		{
16552a38012Sejakowatz 			const char *label = NULL, *trailing_label = NULL;
16652a38012Sejakowatz 
16752a38012Sejakowatz 			message->FindString("label", &label);
168ec053666SStefano Ceccherini 			message->FindString("trailing_label", &trailing_label);
16952a38012Sejakowatz 
17052a38012Sejakowatz 			Reset(label, trailing_label);
17152a38012Sejakowatz 
17252a38012Sejakowatz 			break;
17352a38012Sejakowatz 		}
1743583227cSStefano Ceccherini 
17552a38012Sejakowatz 		default:
17652a38012Sejakowatz 			BView::MessageReceived(message);
1773583227cSStefano Ceccherini 			break;
17852a38012Sejakowatz 	}
17952a38012Sejakowatz }
1803583227cSStefano Ceccherini 
1813583227cSStefano Ceccherini 
1823583227cSStefano Ceccherini void
1833583227cSStefano Ceccherini BStatusBar::Draw(BRect updateRect)
18452a38012Sejakowatz {
185*075e65c7SAxel Dörfler 	rgb_color backgroundColor;
186*075e65c7SAxel Dörfler 	if (Parent())
187*075e65c7SAxel Dörfler 		backgroundColor = Parent()->ViewColor();
188*075e65c7SAxel Dörfler 	else
189*075e65c7SAxel Dörfler 		backgroundColor = ui_color(B_PANEL_BACKGROUND_COLOR);
19052a38012Sejakowatz 
191*075e65c7SAxel Dörfler 	font_height fontHeight;
192*075e65c7SAxel Dörfler 	GetFontHeight(&fontHeight);
193*075e65c7SAxel Dörfler 	BRect barFrame = _BarFrame(&fontHeight);
194*075e65c7SAxel Dörfler 	BRect outerFrame = barFrame.InsetByCopy(-2.0f, -2.0f);
1950dc199a5SMarc Flerackers 
196*075e65c7SAxel Dörfler 	BRegion background(updateRect);
197*075e65c7SAxel Dörfler 	background.Exclude(outerFrame);
198*075e65c7SAxel Dörfler 	FillRegion(&background, B_SOLID_LOW);
1990dc199a5SMarc Flerackers 
200*075e65c7SAxel Dörfler 	// Draw labels/texts
201*075e65c7SAxel Dörfler 
202*075e65c7SAxel Dörfler 	BRect rect = outerFrame;
203*075e65c7SAxel Dörfler 	rect.top = 0.0f;
204*075e65c7SAxel Dörfler 	rect.bottom = outerFrame.top - 1.0f;
205*075e65c7SAxel Dörfler 
206*075e65c7SAxel Dörfler 	if (updateRect.Intersects(rect)) {
207*075e65c7SAxel Dörfler 		// update labels
208*075e65c7SAxel Dörfler 		SetHighColor(ui_color(B_CONTROL_TEXT_COLOR));
209*075e65c7SAxel Dörfler 		MovePenTo(0.0f, ceilf(fontHeight.ascent) + 1.0f);
210*075e65c7SAxel Dörfler 
211*075e65c7SAxel Dörfler 		if (fLabel.Length())
212*075e65c7SAxel Dörfler 			DrawString(fLabel.String());
213*075e65c7SAxel Dörfler 		if (fText.Length())
214*075e65c7SAxel Dörfler 			DrawString(fText.String());
215*075e65c7SAxel Dörfler 
216*075e65c7SAxel Dörfler 		if (fTrailingText.Length() || fTrailingLabel.Length()) {
217*075e65c7SAxel Dörfler 			MovePenTo(rect.right - fTrailingTextWidth - fTrailingLabelWidth,
218*075e65c7SAxel Dörfler 				ceilf(fontHeight.ascent) + 1.0f);
219*075e65c7SAxel Dörfler 
220*075e65c7SAxel Dörfler 			if (fTrailingText.Length())
221*075e65c7SAxel Dörfler 				DrawString(fTrailingText.String());
222*075e65c7SAxel Dörfler 
223*075e65c7SAxel Dörfler 			if (fTrailingLabel.Length())
224*075e65c7SAxel Dörfler 				DrawString(fTrailingLabel.String());
225*075e65c7SAxel Dörfler 		}
22652a38012Sejakowatz 	}
22752a38012Sejakowatz 
228*075e65c7SAxel Dörfler 	// Draw bar
2290dc199a5SMarc Flerackers 
230*075e65c7SAxel Dörfler 	if (!updateRect.Intersects(outerFrame))
231*075e65c7SAxel Dörfler 		return;
232*075e65c7SAxel Dörfler 
233*075e65c7SAxel Dörfler 	rect = outerFrame;
23452a38012Sejakowatz 
23552a38012Sejakowatz 	// First bevel
23652a38012Sejakowatz 	SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT));
237*075e65c7SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
238*075e65c7SAxel Dörfler 	StrokeLine(rect.RightTop());
23952a38012Sejakowatz 
24052a38012Sejakowatz 	SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
241*075e65c7SAxel Dörfler 	StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
24252a38012Sejakowatz 	StrokeLine(BPoint(rect.right, rect.top + 1.0f));
24352a38012Sejakowatz 
24452a38012Sejakowatz 	rect.InsetBy(1.0f, 1.0f);
24552a38012Sejakowatz 
24652a38012Sejakowatz 	// Second bevel
24752a38012Sejakowatz 	SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT));
248*075e65c7SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
249*075e65c7SAxel Dörfler 	StrokeLine(rect.RightTop());
25052a38012Sejakowatz 
25152a38012Sejakowatz 	SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
252*075e65c7SAxel Dörfler 	StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
25352a38012Sejakowatz 	StrokeLine(BPoint(rect.right, rect.top + 1.0f));
25452a38012Sejakowatz 
255*075e65c7SAxel Dörfler 	rect = barFrame;
256*075e65c7SAxel Dörfler 	rect.right = _BarPosition(barFrame);
25752a38012Sejakowatz 
258*075e65c7SAxel Dörfler 	// draw bar itself
25952a38012Sejakowatz 
260*075e65c7SAxel Dörfler 	if (rect.right >= rect.left) {
26152a38012Sejakowatz 		// Bevel
26252a38012Sejakowatz 		SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT));
263*075e65c7SAxel Dörfler 		StrokeLine(rect.LeftBottom(), rect.LeftTop());
264*075e65c7SAxel Dörfler 		StrokeLine(rect.RightTop());
26552a38012Sejakowatz 
26652a38012Sejakowatz 		SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT));
267*075e65c7SAxel Dörfler 		StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom());
268*075e65c7SAxel Dörfler 		StrokeLine(BPoint(rect.right, rect.top + 1.0f));
26952a38012Sejakowatz 
270*075e65c7SAxel Dörfler 		// filling
27152a38012Sejakowatz 		SetHighColor(fBarColor);
272*075e65c7SAxel Dörfler 		FillRect(rect.InsetByCopy(1.0f, 1.0f));
273*075e65c7SAxel Dörfler 	}
274*075e65c7SAxel Dörfler 
275*075e65c7SAxel Dörfler 	if (rect.right < barFrame.right) {
276*075e65c7SAxel Dörfler 		// empty space
277*075e65c7SAxel Dörfler 		rect.left = rect.right + 1.0f;
278*075e65c7SAxel Dörfler 		rect.right = barFrame.right;
279*075e65c7SAxel Dörfler 		SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT));
28052a38012Sejakowatz 		FillRect(rect);
28152a38012Sejakowatz 	}
28252a38012Sejakowatz }
2833583227cSStefano Ceccherini 
2843583227cSStefano Ceccherini 
2853583227cSStefano Ceccherini void
2863583227cSStefano Ceccherini BStatusBar::SetBarColor(rgb_color color)
28752a38012Sejakowatz {
28830d24296SMarcus Overhagen 	fBarColor = color;
28952a38012Sejakowatz 
29052a38012Sejakowatz 	Invalidate();
29152a38012Sejakowatz }
2923583227cSStefano Ceccherini 
2933583227cSStefano Ceccherini 
2943583227cSStefano Ceccherini void
295*075e65c7SAxel Dörfler BStatusBar::SetBarHeight(float barHeight)
29652a38012Sejakowatz {
297*075e65c7SAxel Dörfler 	float oldHeight = BarHeight();
29852a38012Sejakowatz 
29952a38012Sejakowatz 	fCustomBarHeight = true;
300*075e65c7SAxel Dörfler 	fBarHeight = barHeight;
301*075e65c7SAxel Dörfler 
302*075e65c7SAxel Dörfler 	if (barHeight == oldHeight)
303*075e65c7SAxel Dörfler 		return;
304*075e65c7SAxel Dörfler 
305*075e65c7SAxel Dörfler 	// resize so that the height fits
306*075e65c7SAxel Dörfler 	float width, height;
307*075e65c7SAxel Dörfler 	GetPreferredSize(&width, &height);
308*075e65c7SAxel Dörfler 	ResizeTo(Bounds().Width(), height);
30952a38012Sejakowatz }
31052a38012Sejakowatz 
3113583227cSStefano Ceccherini 
3123583227cSStefano Ceccherini void
3133583227cSStefano Ceccherini BStatusBar::SetText(const char* string)
3143583227cSStefano Ceccherini {
315*075e65c7SAxel Dörfler 	_SetTextData(fText, fTextWidth, string, fLabelWidth, false);
31652a38012Sejakowatz }
31752a38012Sejakowatz 
3183583227cSStefano Ceccherini 
3193583227cSStefano Ceccherini void
3203583227cSStefano Ceccherini BStatusBar::SetTrailingText(const char* string)
3213583227cSStefano Ceccherini {
322*075e65c7SAxel Dörfler 	_SetTextData(fTrailingText, fTrailingTextWidth, string,
323*075e65c7SAxel Dörfler 		fTrailingLabelWidth, true);
32452a38012Sejakowatz }
3253583227cSStefano Ceccherini 
3263583227cSStefano Ceccherini 
3273583227cSStefano Ceccherini void
3283583227cSStefano Ceccherini BStatusBar::SetMaxValue(float max)
32952a38012Sejakowatz {
33052a38012Sejakowatz 	fMax = max;
331*075e65c7SAxel Dörfler 	Invalidate(_BarFrame());
33252a38012Sejakowatz }
3333583227cSStefano Ceccherini 
3343583227cSStefano Ceccherini 
3353583227cSStefano Ceccherini void
3363583227cSStefano Ceccherini BStatusBar::Update(float delta, const char* text, const char* trailingText)
33752a38012Sejakowatz {
338*075e65c7SAxel Dörfler 	BStatusBar::SetTo(fCurrent + delta, text, trailingText);
339*075e65c7SAxel Dörfler }
34052a38012Sejakowatz 
341f45d1cc7SMarc Flerackers 
342*075e65c7SAxel Dörfler void
343*075e65c7SAxel Dörfler BStatusBar::SetTo(float value, const char* text, const char* trailingText)
344*075e65c7SAxel Dörfler {
345*075e65c7SAxel Dörfler 	if (text != NULL)
346*075e65c7SAxel Dörfler 		_SetTextData(fText, fTextWidth, text, fLabelWidth, false);
347*075e65c7SAxel Dörfler 	if (trailingText != NULL) {
348*075e65c7SAxel Dörfler 		_SetTextData(fTrailingText, fTrailingTextWidth, trailingText,
349*075e65c7SAxel Dörfler 			fTrailingLabelWidth, true);
350*075e65c7SAxel Dörfler 	}
35152a38012Sejakowatz 
352*075e65c7SAxel Dörfler 	if (value > fMax)
353*075e65c7SAxel Dörfler 		value = fMax;
354*075e65c7SAxel Dörfler 	else if (value < 0.0f)
355*075e65c7SAxel Dörfler 		value = 0.0f;
356*075e65c7SAxel Dörfler 	if (value == fCurrent)
357*075e65c7SAxel Dörfler 		return;
35852a38012Sejakowatz 
359*075e65c7SAxel Dörfler 	BRect barFrame = _BarFrame();
360*075e65c7SAxel Dörfler 	float oldPosition = _BarPosition(barFrame);
361*075e65c7SAxel Dörfler 
362*075e65c7SAxel Dörfler 	fCurrent = value;
363*075e65c7SAxel Dörfler 	float newPosition = _BarPosition(barFrame);
364*075e65c7SAxel Dörfler 
365*075e65c7SAxel Dörfler 	// update only the part of the status bar with actual changes
366*075e65c7SAxel Dörfler 
367*075e65c7SAxel Dörfler 	if (oldPosition == newPosition)
368*075e65c7SAxel Dörfler 		return;
369*075e65c7SAxel Dörfler 
370*075e65c7SAxel Dörfler 	BRect update = barFrame;
371*075e65c7SAxel Dörfler 	update.InsetBy(-1, -1);
372*075e65c7SAxel Dörfler 		// TODO: this shouldn't be necessary, investigate - app_server bug?!
373*075e65c7SAxel Dörfler 
374*075e65c7SAxel Dörfler 	if (oldPosition < newPosition) {
375*075e65c7SAxel Dörfler 		update.left = max_c(oldPosition - 1, update.left);
376*075e65c7SAxel Dörfler 		update.right = newPosition;
377*075e65c7SAxel Dörfler 	} else {
378*075e65c7SAxel Dörfler 		update.left = max_c(newPosition - 1, update.left);
379*075e65c7SAxel Dörfler 		update.right = oldPosition;
380*075e65c7SAxel Dörfler 	}
381*075e65c7SAxel Dörfler 
382*075e65c7SAxel Dörfler 	Invalidate(update);
38352a38012Sejakowatz }
3843583227cSStefano Ceccherini 
3853583227cSStefano Ceccherini 
3863583227cSStefano Ceccherini void
3873583227cSStefano Ceccherini BStatusBar::Reset(const char *label, const char *trailingLabel)
38852a38012Sejakowatz {
38997c93182Shaydentech 	// Reset replaces the label and trailing label with copies of the
39097c93182Shaydentech 	// strings passed as arguments. If either argument is NULL, the
39197c93182Shaydentech 	// label or trailing label will be deleted and erased.
392*075e65c7SAxel Dörfler 	_SetTextData(fLabel, fLabelWidth, label, 0.0f, false);
393*075e65c7SAxel Dörfler 	_SetTextData(fTrailingLabel, fTrailingLabelWidth, trailingLabel, 0.0f, true);
39452a38012Sejakowatz 
39597c93182Shaydentech 	// Reset deletes and erases any text or trailing text
396*075e65c7SAxel Dörfler 	_SetTextData(fText, fTextWidth, NULL, fLabelWidth, false);
397*075e65c7SAxel Dörfler 	_SetTextData(fTrailingText, fTrailingTextWidth, NULL, fTrailingLabelWidth, true);
398b7b28df0Shaydentech 
39952a38012Sejakowatz 	fCurrent = 0.0f;
400b7b28df0Shaydentech 	fMax = 100.0f;
40152a38012Sejakowatz 
40252a38012Sejakowatz 	Invalidate();
40352a38012Sejakowatz }
4043583227cSStefano Ceccherini 
4053583227cSStefano Ceccherini 
4063583227cSStefano Ceccherini float
4073583227cSStefano Ceccherini BStatusBar::CurrentValue() const
40852a38012Sejakowatz {
40952a38012Sejakowatz 	return fCurrent;
41052a38012Sejakowatz }
4113583227cSStefano Ceccherini 
4123583227cSStefano Ceccherini 
4133583227cSStefano Ceccherini float
4143583227cSStefano Ceccherini BStatusBar::MaxValue() const
41552a38012Sejakowatz {
41652a38012Sejakowatz 	return fMax;
41752a38012Sejakowatz }
4183583227cSStefano Ceccherini 
4193583227cSStefano Ceccherini 
4203583227cSStefano Ceccherini rgb_color
4213583227cSStefano Ceccherini BStatusBar::BarColor() const
42252a38012Sejakowatz {
42352a38012Sejakowatz 	return fBarColor;
42452a38012Sejakowatz }
4253583227cSStefano Ceccherini 
4263583227cSStefano Ceccherini 
4273583227cSStefano Ceccherini float
4283583227cSStefano Ceccherini BStatusBar::BarHeight() const
42952a38012Sejakowatz {
4303583227cSStefano Ceccherini 	if (!fCustomBarHeight && fBarHeight == -1.0f) {
431*075e65c7SAxel Dörfler 		// the default bar height is as height as the label
432*075e65c7SAxel Dörfler 		font_height fontHeight;
433*075e65c7SAxel Dörfler 		GetFontHeight(&fontHeight);
434*075e65c7SAxel Dörfler 		const_cast<BStatusBar *>(this)->fBarHeight = fontHeight.ascent
435*075e65c7SAxel Dörfler 			+ fontHeight.descent + 5.0f;
43652a38012Sejakowatz 	}
43752a38012Sejakowatz 
43852a38012Sejakowatz 	return fBarHeight;
43952a38012Sejakowatz }
4403583227cSStefano Ceccherini 
4413583227cSStefano Ceccherini 
4423583227cSStefano Ceccherini const char *
4433583227cSStefano Ceccherini BStatusBar::Text() const
44452a38012Sejakowatz {
445*075e65c7SAxel Dörfler 	return fText.String();
44652a38012Sejakowatz }
4473583227cSStefano Ceccherini 
4483583227cSStefano Ceccherini 
4493583227cSStefano Ceccherini const char *
4503583227cSStefano Ceccherini BStatusBar::TrailingText() const
45152a38012Sejakowatz {
452*075e65c7SAxel Dörfler 	return fTrailingText.String();
45352a38012Sejakowatz }
4543583227cSStefano Ceccherini 
4553583227cSStefano Ceccherini 
4563583227cSStefano Ceccherini const char *
4573583227cSStefano Ceccherini BStatusBar::Label() const
45852a38012Sejakowatz {
459*075e65c7SAxel Dörfler 	return fLabel.String();
46052a38012Sejakowatz }
4613583227cSStefano Ceccherini 
4623583227cSStefano Ceccherini 
4633583227cSStefano Ceccherini const char *
4643583227cSStefano Ceccherini BStatusBar::TrailingLabel() const
46552a38012Sejakowatz {
466*075e65c7SAxel Dörfler 	return fTrailingLabel.String();
46752a38012Sejakowatz }
4683583227cSStefano Ceccherini 
4693583227cSStefano Ceccherini 
4703583227cSStefano Ceccherini void
4713583227cSStefano Ceccherini BStatusBar::MouseDown(BPoint point)
47252a38012Sejakowatz {
47352a38012Sejakowatz 	BView::MouseDown(point);
47452a38012Sejakowatz }
4753583227cSStefano Ceccherini 
4763583227cSStefano Ceccherini 
4773583227cSStefano Ceccherini void
4783583227cSStefano Ceccherini BStatusBar::MouseUp(BPoint point)
47952a38012Sejakowatz {
48052a38012Sejakowatz 	BView::MouseUp(point);
48152a38012Sejakowatz }
4823583227cSStefano Ceccherini 
4833583227cSStefano Ceccherini 
4843583227cSStefano Ceccherini void
4853583227cSStefano Ceccherini BStatusBar::WindowActivated(bool state)
48652a38012Sejakowatz {
48752a38012Sejakowatz 	BView::WindowActivated(state);
48852a38012Sejakowatz }
4893583227cSStefano Ceccherini 
4903583227cSStefano Ceccherini 
4913583227cSStefano Ceccherini void
4923583227cSStefano Ceccherini BStatusBar::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
49352a38012Sejakowatz {
49452a38012Sejakowatz 	BView::MouseMoved(point, transit, message);
49552a38012Sejakowatz }
4963583227cSStefano Ceccherini 
4973583227cSStefano Ceccherini 
4983583227cSStefano Ceccherini void
4993583227cSStefano Ceccherini BStatusBar::DetachedFromWindow()
50052a38012Sejakowatz {
50152a38012Sejakowatz 	BView::DetachedFromWindow();
50252a38012Sejakowatz }
5033583227cSStefano Ceccherini 
5043583227cSStefano Ceccherini 
5053583227cSStefano Ceccherini void
5063583227cSStefano Ceccherini BStatusBar::FrameMoved(BPoint newPosition)
50752a38012Sejakowatz {
5083583227cSStefano Ceccherini 	BView::FrameMoved(newPosition);
50952a38012Sejakowatz }
5103583227cSStefano Ceccherini 
5113583227cSStefano Ceccherini 
5123583227cSStefano Ceccherini void
5133583227cSStefano Ceccherini BStatusBar::FrameResized(float newWidth, float newHeight)
51452a38012Sejakowatz {
5153583227cSStefano Ceccherini 	BView::FrameResized(newWidth, newHeight);
51652a38012Sejakowatz }
5173583227cSStefano Ceccherini 
5183583227cSStefano Ceccherini 
5193583227cSStefano Ceccherini BHandler *
5203583227cSStefano Ceccherini BStatusBar::ResolveSpecifier(BMessage* message, int32 index,
521*075e65c7SAxel Dörfler 	BMessage* specifier, int32 what, const char *property)
52252a38012Sejakowatz {
52352a38012Sejakowatz 	return BView::ResolveSpecifier(message, index, specifier, what, property);
52452a38012Sejakowatz }
5253583227cSStefano Ceccherini 
5263583227cSStefano Ceccherini 
5273583227cSStefano Ceccherini void
5283583227cSStefano Ceccherini BStatusBar::ResizeToPreferred()
52952a38012Sejakowatz {
53052a38012Sejakowatz 	BView::ResizeToPreferred();
53152a38012Sejakowatz }
5323583227cSStefano Ceccherini 
5333583227cSStefano Ceccherini 
5343583227cSStefano Ceccherini void
5358643b098SAxel Dörfler BStatusBar::GetPreferredSize(float* _width, float* _height)
53652a38012Sejakowatz {
5378643b098SAxel Dörfler 	if (_width) {
538*075e65c7SAxel Dörfler 		// AttachedToWindow() might not have been called yet
539*075e65c7SAxel Dörfler 		*_width = ceilf(StringWidth(fLabel.String()))
540*075e65c7SAxel Dörfler 			+ ceilf(StringWidth(fTrailingLabel.String()))
541*075e65c7SAxel Dörfler 			+ ceilf(StringWidth(fText.String()))
542*075e65c7SAxel Dörfler 			+ ceilf(StringWidth(fTrailingText.String()))
543*075e65c7SAxel Dörfler 			+ 5.0f;
5448643b098SAxel Dörfler 	}
54552a38012Sejakowatz 
5468643b098SAxel Dörfler 	if (_height) {
5478643b098SAxel Dörfler 		font_height fontHeight;
5488643b098SAxel Dörfler 		GetFontHeight(&fontHeight);
5498643b098SAxel Dörfler 
550*075e65c7SAxel Dörfler 		*_height = ceilf(fontHeight.ascent + fontHeight.descent) + 6.0f + BarHeight();
5518643b098SAxel Dörfler 	}
55252a38012Sejakowatz }
5533583227cSStefano Ceccherini 
5543583227cSStefano Ceccherini 
5553583227cSStefano Ceccherini void
5563583227cSStefano Ceccherini BStatusBar::MakeFocus(bool state)
55752a38012Sejakowatz {
55852a38012Sejakowatz 	BView::MakeFocus(state);
55952a38012Sejakowatz }
5603583227cSStefano Ceccherini 
5613583227cSStefano Ceccherini 
5623583227cSStefano Ceccherini void
5633583227cSStefano Ceccherini BStatusBar::AllAttached()
56452a38012Sejakowatz {
56552a38012Sejakowatz 	BView::AllAttached();
56652a38012Sejakowatz }
5673583227cSStefano Ceccherini 
5683583227cSStefano Ceccherini 
5693583227cSStefano Ceccherini void
5703583227cSStefano Ceccherini BStatusBar::AllDetached()
57152a38012Sejakowatz {
57252a38012Sejakowatz 	BView::AllDetached();
57352a38012Sejakowatz }
5743583227cSStefano Ceccherini 
5753583227cSStefano Ceccherini 
5763583227cSStefano Ceccherini status_t
5773583227cSStefano Ceccherini BStatusBar::GetSupportedSuites(BMessage* data)
57852a38012Sejakowatz {
57952a38012Sejakowatz 	return BView::GetSupportedSuites(data);
58052a38012Sejakowatz }
5813583227cSStefano Ceccherini 
5823583227cSStefano Ceccherini 
5833583227cSStefano Ceccherini status_t
5843583227cSStefano Ceccherini BStatusBar::Perform(perform_code d, void* arg)
58552a38012Sejakowatz {
5863583227cSStefano Ceccherini 	return BView::Perform(d, arg);
58752a38012Sejakowatz }
5883583227cSStefano Ceccherini 
5893583227cSStefano Ceccherini 
590*075e65c7SAxel Dörfler void
591*075e65c7SAxel Dörfler _ReservedStatusBar1__10BStatusBar(BStatusBar* self, float value,
592*075e65c7SAxel Dörfler 	const char* text, const char* trailingText)
593*075e65c7SAxel Dörfler {
594*075e65c7SAxel Dörfler 	self->BStatusBar::SetTo(value, text, trailingText);
595*075e65c7SAxel Dörfler }
596*075e65c7SAxel Dörfler 
597*075e65c7SAxel Dörfler 
59852a38012Sejakowatz void BStatusBar::_ReservedStatusBar2() {}
59952a38012Sejakowatz void BStatusBar::_ReservedStatusBar3() {}
60052a38012Sejakowatz void BStatusBar::_ReservedStatusBar4() {}
60152a38012Sejakowatz 
6023583227cSStefano Ceccherini 
6033583227cSStefano Ceccherini BStatusBar &
604*075e65c7SAxel Dörfler BStatusBar::operator=(const BStatusBar& other)
60552a38012Sejakowatz {
60652a38012Sejakowatz 	return *this;
60752a38012Sejakowatz }
60852a38012Sejakowatz 
6093583227cSStefano Ceccherini 
6103583227cSStefano Ceccherini void
611*075e65c7SAxel Dörfler BStatusBar::_SetTextData(BString& text, float& width, const char* source,
612*075e65c7SAxel Dörfler 	float position, bool rightAligned)
6133583227cSStefano Ceccherini {
614*075e65c7SAxel Dörfler 	// If there were no changes, we don't have to do anything
615*075e65c7SAxel Dörfler 	if (text == source)
616*075e65c7SAxel Dörfler 		return;
617*075e65c7SAxel Dörfler 
618*075e65c7SAxel Dörfler 	float oldWidth = width;
619*075e65c7SAxel Dörfler 	text = source;
620*075e65c7SAxel Dörfler 	width = ceilf(StringWidth(text.String()));
621*075e65c7SAxel Dörfler 
622*075e65c7SAxel Dörfler 	// determine which part of the view needs an update
623*075e65c7SAxel Dörfler 
624*075e65c7SAxel Dörfler 	// if a label changed, we also need to update the texts
625*075e65c7SAxel Dörfler 	float invalidateWidth = max_c(width, oldWidth);
626*075e65c7SAxel Dörfler 	if (&text == &fLabel)
627*075e65c7SAxel Dörfler 		invalidateWidth += fTextWidth;
628*075e65c7SAxel Dörfler 	if (&text == &fTrailingLabel)
629*075e65c7SAxel Dörfler 		invalidateWidth += fTrailingTextWidth;
630*075e65c7SAxel Dörfler 
631*075e65c7SAxel Dörfler 	if (rightAligned)
632*075e65c7SAxel Dörfler 		position = Bounds().Width() - position - invalidateWidth;
633*075e65c7SAxel Dörfler 
634*075e65c7SAxel Dörfler 	font_height fontHeight;
635*075e65c7SAxel Dörfler 	GetFontHeight(&fontHeight);
636*075e65c7SAxel Dörfler 
637*075e65c7SAxel Dörfler 	Invalidate(BRect(position, 1.0f, position + invalidateWidth,
638*075e65c7SAxel Dörfler 		ceilf(fontHeight.ascent + fontHeight.descent)));
6393583227cSStefano Ceccherini }
6403583227cSStefano Ceccherini 
6413583227cSStefano Ceccherini 
642*075e65c7SAxel Dörfler /*!
643*075e65c7SAxel Dörfler 	Returns the inner bar frame without the surrounding bevel.
644*075e65c7SAxel Dörfler */
645*075e65c7SAxel Dörfler BRect
646*075e65c7SAxel Dörfler BStatusBar::_BarFrame(const font_height* fontHeight) const
6473583227cSStefano Ceccherini {
648*075e65c7SAxel Dörfler 	float top;
649*075e65c7SAxel Dörfler 	if (fontHeight == NULL) {
650*075e65c7SAxel Dörfler 		font_height height;
651*075e65c7SAxel Dörfler 		GetFontHeight(&height);
652*075e65c7SAxel Dörfler 		top = ceilf(height.ascent + height.descent) + 6.0f;
653*075e65c7SAxel Dörfler 	} else
654*075e65c7SAxel Dörfler 		top = ceilf(fontHeight->ascent + fontHeight->descent) + 6.0f;
6553583227cSStefano Ceccherini 
656*075e65c7SAxel Dörfler 	return BRect(2.0f, top, Bounds().right - 2.0f, top + BarHeight() - 4.0f);
6573583227cSStefano Ceccherini }
6583583227cSStefano Ceccherini 
6593583227cSStefano Ceccherini 
660*075e65c7SAxel Dörfler float
661*075e65c7SAxel Dörfler BStatusBar::_BarPosition(const BRect& barFrame) const
6623583227cSStefano Ceccherini {
663*075e65c7SAxel Dörfler 	if (fCurrent == 0.0f)
664*075e65c7SAxel Dörfler 		return barFrame.left - 1.0f;
665*075e65c7SAxel Dörfler 
666*075e65c7SAxel Dörfler 	return roundf(barFrame.left + ceilf(fCurrent * barFrame.Width() / fMax));
6673583227cSStefano Ceccherini }
6683583227cSStefano Ceccherini 
669