xref: /haiku/src/kits/interface/StatusBar.cpp (revision 7ee23666445626826430849982dd8655773b1f00)
199f695c9SAxel Dörfler /*
289208c77SStephan Aßmus  * Copyright 2001-2008, Haiku, Inc. All Rights Reserved.
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)
7075e65c7SAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
8f466d35dSStephan Aßmus  *		Stephan Aßmus <superstippi@gmx.de>
999f695c9SAxel Dörfler  */
1099f695c9SAxel Dörfler 
1199f695c9SAxel Dörfler /*! BStatusBar displays a "percentage-of-completion" gauge. */
12f466d35dSStephan Aßmus #include <StatusBar.h>
13f466d35dSStephan Aßmus 
14f466d35dSStephan Aßmus #include <stdio.h>
15f466d35dSStephan Aßmus #include <stdlib.h>
16f466d35dSStephan Aßmus #include <string.h>
1752a38012Sejakowatz 
182f86ba45SStephan Aßmus #include <ControlLook.h>
19d23c4822SIngo Weinhold #include <Layout.h>
20d23c4822SIngo Weinhold #include <LayoutUtils.h>
212f86ba45SStephan Aßmus #include <Message.h>
222f86ba45SStephan Aßmus #include <Region.h>
23d23c4822SIngo Weinhold 
2439fbf550SOliver Tappe #include <binary_compatibility/Interface.h>
2539fbf550SOliver Tappe 
2652a38012Sejakowatz 
27075e65c7SAxel Dörfler static const rgb_color kDefaultBarColor = {50, 150, 255, 255};
28075e65c7SAxel Dörfler 
29075e65c7SAxel Dörfler 
3052a38012Sejakowatz BStatusBar::BStatusBar(BRect frame, const char *name, const char *label,
3152a38012Sejakowatz 		const char *trailingLabel)
3289208c77SStephan Aßmus 	:
3389208c77SStephan Aßmus 	BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
34075e65c7SAxel Dörfler 	fLabel(label),
35075e65c7SAxel Dörfler 	fTrailingLabel(trailingLabel)
3652a38012Sejakowatz {
37075e65c7SAxel Dörfler 	_InitObject();
3852a38012Sejakowatz }
393583227cSStefano Ceccherini 
403583227cSStefano Ceccherini 
41d23c4822SIngo Weinhold BStatusBar::BStatusBar(const char *name, const char *label,
42d23c4822SIngo Weinhold 		const char *trailingLabel)
4389208c77SStephan Aßmus 	:
4489208c77SStephan Aßmus 	BView(BRect(0, 0, -1, -1), name, B_FOLLOW_LEFT | B_FOLLOW_TOP,
45d23c4822SIngo Weinhold 		B_WILL_DRAW | B_SUPPORTS_LAYOUT),
46d23c4822SIngo Weinhold 	fLabel(label),
47d23c4822SIngo Weinhold 	fTrailingLabel(trailingLabel)
48d23c4822SIngo Weinhold {
49d23c4822SIngo Weinhold 	_InitObject();
50d23c4822SIngo Weinhold }
51d23c4822SIngo Weinhold 
52d23c4822SIngo Weinhold 
5352a38012Sejakowatz BStatusBar::BStatusBar(BMessage *archive)
5489208c77SStephan Aßmus 	:
5589208c77SStephan Aßmus 	BView(archive)
5652a38012Sejakowatz {
57075e65c7SAxel Dörfler 	_InitObject();
583583227cSStefano Ceccherini 
59075e65c7SAxel Dörfler 	archive->FindString("_label", &fLabel);
60075e65c7SAxel Dörfler 	archive->FindString("_tlabel", &fTrailingLabel);
613583227cSStefano Ceccherini 
62075e65c7SAxel Dörfler 	archive->FindString("_text", &fText);
63075e65c7SAxel Dörfler 	archive->FindString("_ttext", &fTrailingText);
6452a38012Sejakowatz 
65075e65c7SAxel Dörfler 	float floatValue;
66075e65c7SAxel Dörfler 	if (archive->FindFloat("_high", &floatValue) == B_OK) {
67075e65c7SAxel Dörfler 		fBarHeight = floatValue;
68075e65c7SAxel Dörfler 		fCustomBarHeight = true;
69075e65c7SAxel Dörfler 	}
7052a38012Sejakowatz 
71075e65c7SAxel Dörfler 	int32 color;
72075e65c7SAxel Dörfler 	if (archive->FindInt32("_bcolor", (int32 *)&color) == B_OK)
73075e65c7SAxel Dörfler 		fBarColor = *(rgb_color *)&color;
7452a38012Sejakowatz 
75075e65c7SAxel Dörfler 	if (archive->FindFloat("_val", &floatValue) == B_OK)
76075e65c7SAxel Dörfler 		fCurrent = floatValue;
77075e65c7SAxel Dörfler 	if (archive->FindFloat("_max", &floatValue) == B_OK)
78075e65c7SAxel Dörfler 		fMax = floatValue;
7952a38012Sejakowatz }
803583227cSStefano Ceccherini 
813583227cSStefano Ceccherini 
8252a38012Sejakowatz BStatusBar::~BStatusBar()
8352a38012Sejakowatz {
84075e65c7SAxel Dörfler }
85075e65c7SAxel Dörfler 
86075e65c7SAxel Dörfler 
873583227cSStefano Ceccherini BArchivable *
883583227cSStefano Ceccherini BStatusBar::Instantiate(BMessage *archive)
8952a38012Sejakowatz {
9052a38012Sejakowatz 	if (validate_instantiation(archive, "BStatusBar"))
9152a38012Sejakowatz 		return new BStatusBar(archive);
9252a38012Sejakowatz 
9352a38012Sejakowatz 	return NULL;
9452a38012Sejakowatz }
953583227cSStefano Ceccherini 
963583227cSStefano Ceccherini 
973583227cSStefano Ceccherini status_t
983583227cSStefano Ceccherini BStatusBar::Archive(BMessage *archive, bool deep) const
9952a38012Sejakowatz {
1008f3e1554SMarc Flerackers 	status_t err = BView::Archive(archive, deep);
1013583227cSStefano Ceccherini 	if (err < B_OK)
1028f3e1554SMarc Flerackers 		return err;
10352a38012Sejakowatz 
104075e65c7SAxel Dörfler 	if (fCustomBarHeight)
1058f3e1554SMarc Flerackers 		err = archive->AddFloat("_high", fBarHeight);
1068f3e1554SMarc Flerackers 
107075e65c7SAxel Dörfler 	if (err == B_OK && fBarColor != kDefaultBarColor)
10830d24296SMarcus Overhagen 		err = archive->AddInt32("_bcolor", (const uint32 &)fBarColor);
1098f3e1554SMarc Flerackers 
110f466d35dSStephan Aßmus 	if (err == B_OK && fCurrent != 0)
1118f3e1554SMarc Flerackers 		err = archive->AddFloat("_val", fCurrent);
112f466d35dSStephan Aßmus 	if (err == B_OK && fMax != 100 )
1138f3e1554SMarc Flerackers 		err = archive->AddFloat("_max", fMax);
1148f3e1554SMarc Flerackers 
115075e65c7SAxel Dörfler 	if (err == B_OK && fText.Length())
1168f3e1554SMarc Flerackers 		err = archive->AddString("_text", fText);
117075e65c7SAxel Dörfler 	if (err == B_OK && fTrailingText.Length())
1188f3e1554SMarc Flerackers 		err = archive->AddString("_ttext", fTrailingText);
1198f3e1554SMarc Flerackers 
120075e65c7SAxel Dörfler 	if (err == B_OK && fLabel.Length())
1218f3e1554SMarc Flerackers 		err = archive->AddString("_label", fLabel);
122075e65c7SAxel Dörfler 	if (err == B_OK && fTrailingLabel.Length())
1238f3e1554SMarc Flerackers 		err = archive->AddString ("_tlabel", fTrailingLabel);
12452a38012Sejakowatz 
1258f3e1554SMarc Flerackers 	return err;
12652a38012Sejakowatz }
1273583227cSStefano Ceccherini 
1283583227cSStefano Ceccherini 
12989208c77SStephan Aßmus // #pragma mark -
13089208c77SStephan Aßmus 
13189208c77SStephan Aßmus 
1323583227cSStefano Ceccherini void
1333583227cSStefano Ceccherini BStatusBar::AttachedToWindow()
13452a38012Sejakowatz {
135075e65c7SAxel Dörfler 	// resize so that the height fits
13652a38012Sejakowatz 	float width, height;
13752a38012Sejakowatz 	GetPreferredSize(&width, &height);
138075e65c7SAxel Dörfler 	ResizeTo(Bounds().Width(), height);
13952a38012Sejakowatz 
140075e65c7SAxel Dörfler 	SetViewColor(B_TRANSPARENT_COLOR);
14154badb1fSStephan Aßmus 	rgb_color lowColor = B_TRANSPARENT_COLOR;
142075e65c7SAxel Dörfler 
14354badb1fSStephan Aßmus 	BView* parent = Parent();
14454badb1fSStephan Aßmus 	if (parent != NULL)
14554badb1fSStephan Aßmus 		lowColor = parent->ViewColor();
14654badb1fSStephan Aßmus 
14754badb1fSStephan Aßmus 	if (lowColor == B_TRANSPARENT_COLOR)
14854badb1fSStephan Aßmus 		lowColor = ui_color(B_PANEL_BACKGROUND_COLOR);
14954badb1fSStephan Aßmus 
15054badb1fSStephan Aßmus 	SetLowColor(lowColor);
151075e65c7SAxel Dörfler 
152f466d35dSStephan Aßmus 	fTextDivider = Bounds().Width();
15352a38012Sejakowatz }
1543583227cSStefano Ceccherini 
1553583227cSStefano Ceccherini 
1563583227cSStefano Ceccherini void
15789208c77SStephan Aßmus BStatusBar::DetachedFromWindow()
15852a38012Sejakowatz {
15989208c77SStephan Aßmus 	BView::DetachedFromWindow();
16089208c77SStephan Aßmus }
16189208c77SStephan Aßmus 
16289208c77SStephan Aßmus 
16389208c77SStephan Aßmus void
16489208c77SStephan Aßmus BStatusBar::AllAttached()
16552a38012Sejakowatz {
16689208c77SStephan Aßmus 	BView::AllAttached();
16752a38012Sejakowatz }
1683583227cSStefano Ceccherini 
16989208c77SStephan Aßmus 
17089208c77SStephan Aßmus void
17189208c77SStephan Aßmus BStatusBar::AllDetached()
17252a38012Sejakowatz {
17389208c77SStephan Aßmus 	BView::AllDetached();
17452a38012Sejakowatz }
1753583227cSStefano Ceccherini 
17689208c77SStephan Aßmus 
17789208c77SStephan Aßmus // #pragma mark -
17889208c77SStephan Aßmus 
17989208c77SStephan Aßmus 
18089208c77SStephan Aßmus void
18189208c77SStephan Aßmus BStatusBar::WindowActivated(bool state)
18289208c77SStephan Aßmus {
18389208c77SStephan Aßmus 	BView::WindowActivated(state);
18489208c77SStephan Aßmus }
18589208c77SStephan Aßmus 
18689208c77SStephan Aßmus 
18789208c77SStephan Aßmus void
18889208c77SStephan Aßmus BStatusBar::MakeFocus(bool state)
18989208c77SStephan Aßmus {
19089208c77SStephan Aßmus 	BView::MakeFocus(state);
19189208c77SStephan Aßmus }
19289208c77SStephan Aßmus 
19389208c77SStephan Aßmus 
19489208c77SStephan Aßmus // #pragma mark -
19589208c77SStephan Aßmus 
19689208c77SStephan Aßmus 
19789208c77SStephan Aßmus void
19889208c77SStephan Aßmus BStatusBar::GetPreferredSize(float* _width, float* _height)
19989208c77SStephan Aßmus {
20089208c77SStephan Aßmus 	if (_width) {
20189208c77SStephan Aßmus 		// AttachedToWindow() might not have been called yet
20289208c77SStephan Aßmus 		*_width = ceilf(StringWidth(fLabel.String()))
20389208c77SStephan Aßmus 			+ ceilf(StringWidth(fTrailingLabel.String()))
20489208c77SStephan Aßmus 			+ ceilf(StringWidth(fText.String()))
20589208c77SStephan Aßmus 			+ ceilf(StringWidth(fTrailingText.String()))
20689208c77SStephan Aßmus 			+ 5;
20789208c77SStephan Aßmus 	}
20889208c77SStephan Aßmus 
20989208c77SStephan Aßmus 	if (_height) {
210a487da80SStephan Aßmus 		float labelHeight = 0;
211a487da80SStephan Aßmus 		if (_HasText()) {
21289208c77SStephan Aßmus 			font_height fontHeight;
21389208c77SStephan Aßmus 			GetFontHeight(&fontHeight);
214a487da80SStephan Aßmus 			labelHeight = ceilf(fontHeight.ascent + fontHeight.descent) + 6;
215a487da80SStephan Aßmus 		}
21689208c77SStephan Aßmus 
217a487da80SStephan Aßmus 		*_height = labelHeight + BarHeight();
21852a38012Sejakowatz 	}
21952a38012Sejakowatz }
2203583227cSStefano Ceccherini 
2213583227cSStefano Ceccherini 
22289208c77SStephan Aßmus BSize
22389208c77SStephan Aßmus BStatusBar::MinSize()
22489208c77SStephan Aßmus {
22589208c77SStephan Aßmus 	float width, height;
22689208c77SStephan Aßmus 	GetPreferredSize(&width, &height);
22789208c77SStephan Aßmus 
22889208c77SStephan Aßmus 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), BSize(width, height));
22989208c77SStephan Aßmus }
23089208c77SStephan Aßmus 
23189208c77SStephan Aßmus 
23289208c77SStephan Aßmus BSize
23389208c77SStephan Aßmus BStatusBar::MaxSize()
23489208c77SStephan Aßmus {
23589208c77SStephan Aßmus 	float width, height;
23689208c77SStephan Aßmus 	GetPreferredSize(&width, &height);
23789208c77SStephan Aßmus 
23889208c77SStephan Aßmus 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
23989208c77SStephan Aßmus 			BSize(B_SIZE_UNLIMITED, height));
24089208c77SStephan Aßmus }
24189208c77SStephan Aßmus 
24289208c77SStephan Aßmus 
24389208c77SStephan Aßmus BSize
24489208c77SStephan Aßmus BStatusBar::PreferredSize()
24589208c77SStephan Aßmus {
24689208c77SStephan Aßmus 	float width, height;
24789208c77SStephan Aßmus 	GetPreferredSize(&width, &height);
24889208c77SStephan Aßmus 
24989208c77SStephan Aßmus 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), BSize(width, height));
25089208c77SStephan Aßmus }
25189208c77SStephan Aßmus 
25289208c77SStephan Aßmus 
25389208c77SStephan Aßmus void
25489208c77SStephan Aßmus BStatusBar::ResizeToPreferred()
25589208c77SStephan Aßmus {
25689208c77SStephan Aßmus 	BView::ResizeToPreferred();
25789208c77SStephan Aßmus }
25889208c77SStephan Aßmus 
25989208c77SStephan Aßmus 
26089208c77SStephan Aßmus void
26189208c77SStephan Aßmus BStatusBar::FrameMoved(BPoint newPosition)
26289208c77SStephan Aßmus {
26389208c77SStephan Aßmus 	BView::FrameMoved(newPosition);
26489208c77SStephan Aßmus }
26589208c77SStephan Aßmus 
26689208c77SStephan Aßmus 
26789208c77SStephan Aßmus void
26889208c77SStephan Aßmus BStatusBar::FrameResized(float newWidth, float newHeight)
26989208c77SStephan Aßmus {
27089208c77SStephan Aßmus 	BView::FrameResized(newWidth, newHeight);
27189208c77SStephan Aßmus 	Invalidate();
27289208c77SStephan Aßmus }
27389208c77SStephan Aßmus 
27489208c77SStephan Aßmus 
27589208c77SStephan Aßmus // #pragma mark -
27689208c77SStephan Aßmus 
27789208c77SStephan Aßmus 
2783583227cSStefano Ceccherini void
2793583227cSStefano Ceccherini BStatusBar::Draw(BRect updateRect)
28052a38012Sejakowatz {
281861e4437SStephan Aßmus 	rgb_color backgroundColor = LowColor();
28252a38012Sejakowatz 
283075e65c7SAxel Dörfler 	font_height fontHeight;
284075e65c7SAxel Dörfler 	GetFontHeight(&fontHeight);
285075e65c7SAxel Dörfler 	BRect barFrame = _BarFrame(&fontHeight);
286f466d35dSStephan Aßmus 	BRect outerFrame = barFrame.InsetByCopy(-2, -2);
2870dc199a5SMarc Flerackers 
288075e65c7SAxel Dörfler 	BRegion background(updateRect);
289075e65c7SAxel Dörfler 	background.Exclude(outerFrame);
290075e65c7SAxel Dörfler 	FillRegion(&background, B_SOLID_LOW);
2910dc199a5SMarc Flerackers 
292075e65c7SAxel Dörfler 	// Draw labels/texts
293075e65c7SAxel Dörfler 
294075e65c7SAxel Dörfler 	BRect rect = outerFrame;
295f466d35dSStephan Aßmus 	rect.top = 0;
296f466d35dSStephan Aßmus 	rect.bottom = outerFrame.top - 1;
297075e65c7SAxel Dörfler 
298075e65c7SAxel Dörfler 	if (updateRect.Intersects(rect)) {
299075e65c7SAxel Dörfler 		// update labels
300f466d35dSStephan Aßmus 		BString leftText;
301f466d35dSStephan Aßmus 		leftText << fLabel << fText;
302075e65c7SAxel Dörfler 
303f466d35dSStephan Aßmus 		BString rightText;
304f466d35dSStephan Aßmus 		rightText << fTrailingText << fTrailingLabel;
305075e65c7SAxel Dörfler 
306f466d35dSStephan Aßmus 		float baseLine = ceilf(fontHeight.ascent) + 1;
307f466d35dSStephan Aßmus 		fTextDivider = rect.right;
308075e65c7SAxel Dörfler 
309f466d35dSStephan Aßmus 		BFont font;
310f466d35dSStephan Aßmus 		GetFont(&font);
311075e65c7SAxel Dörfler 
312f466d35dSStephan Aßmus 		if (rightText.Length()) {
313f466d35dSStephan Aßmus 			font.TruncateString(&rightText, B_TRUNCATE_BEGINNING, rect.Width());
314f466d35dSStephan Aßmus 			fTextDivider -= StringWidth(rightText.String());
315075e65c7SAxel Dörfler 		}
316f466d35dSStephan Aßmus 
317f466d35dSStephan Aßmus 		if (leftText.Length()) {
318f466d35dSStephan Aßmus 			float width = max_c(0.0, fTextDivider - rect.left);
319f466d35dSStephan Aßmus 			font.TruncateString(&leftText, B_TRUNCATE_END, width);
320f466d35dSStephan Aßmus 		}
321f466d35dSStephan Aßmus 
322f466d35dSStephan Aßmus 		SetHighColor(ui_color(B_CONTROL_TEXT_COLOR));
323f466d35dSStephan Aßmus 
324f466d35dSStephan Aßmus 		if (leftText.Length())
325f466d35dSStephan Aßmus 			DrawString(leftText.String(), BPoint(rect.left, baseLine));
326f466d35dSStephan Aßmus 
327f466d35dSStephan Aßmus 		if (rightText.Length())
328f466d35dSStephan Aßmus 			DrawString(rightText.String(), BPoint(fTextDivider, baseLine));
329f466d35dSStephan Aßmus 
33052a38012Sejakowatz 	}
33152a38012Sejakowatz 
332075e65c7SAxel Dörfler 	// Draw bar
3330dc199a5SMarc Flerackers 
334075e65c7SAxel Dörfler 	if (!updateRect.Intersects(outerFrame))
335075e65c7SAxel Dörfler 		return;
336075e65c7SAxel Dörfler 
337075e65c7SAxel Dörfler 	rect = outerFrame;
33852a38012Sejakowatz 
3392f86ba45SStephan Aßmus 	if (be_control_look != NULL) {
3402f86ba45SStephan Aßmus 		be_control_look->DrawStatusBar(this, rect, updateRect,
3412f86ba45SStephan Aßmus 			backgroundColor, fBarColor, _BarPosition(barFrame));
3422f86ba45SStephan Aßmus 		return;
3432f86ba45SStephan Aßmus 	}
3442f86ba45SStephan Aßmus 
34552a38012Sejakowatz 	// First bevel
34652a38012Sejakowatz 	SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT));
347075e65c7SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
348075e65c7SAxel Dörfler 	StrokeLine(rect.RightTop());
34952a38012Sejakowatz 
35052a38012Sejakowatz 	SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
351f466d35dSStephan Aßmus 	StrokeLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom());
352f466d35dSStephan Aßmus 	StrokeLine(BPoint(rect.right, rect.top + 1));
35352a38012Sejakowatz 
354f466d35dSStephan Aßmus 	rect.InsetBy(1, 1);
35552a38012Sejakowatz 
35652a38012Sejakowatz 	// Second bevel
35752a38012Sejakowatz 	SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT));
358075e65c7SAxel Dörfler 	StrokeLine(rect.LeftBottom(), rect.LeftTop());
359075e65c7SAxel Dörfler 	StrokeLine(rect.RightTop());
36052a38012Sejakowatz 
36152a38012Sejakowatz 	SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
362f466d35dSStephan Aßmus 	StrokeLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom());
363f466d35dSStephan Aßmus 	StrokeLine(BPoint(rect.right, rect.top + 1));
36452a38012Sejakowatz 
365075e65c7SAxel Dörfler 	rect = barFrame;
366075e65c7SAxel Dörfler 	rect.right = _BarPosition(barFrame);
36752a38012Sejakowatz 
368075e65c7SAxel Dörfler 	// draw bar itself
36952a38012Sejakowatz 
370075e65c7SAxel Dörfler 	if (rect.right >= rect.left) {
37152a38012Sejakowatz 		// Bevel
37252a38012Sejakowatz 		SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT));
373075e65c7SAxel Dörfler 		StrokeLine(rect.LeftBottom(), rect.LeftTop());
374075e65c7SAxel Dörfler 		StrokeLine(rect.RightTop());
37552a38012Sejakowatz 
37652a38012Sejakowatz 		SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT));
377f466d35dSStephan Aßmus 		StrokeLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom());
378f466d35dSStephan Aßmus 		StrokeLine(BPoint(rect.right, rect.top + 1));
37952a38012Sejakowatz 
380075e65c7SAxel Dörfler 		// filling
38152a38012Sejakowatz 		SetHighColor(fBarColor);
382f466d35dSStephan Aßmus 		FillRect(rect.InsetByCopy(1, 1));
383075e65c7SAxel Dörfler 	}
384075e65c7SAxel Dörfler 
385075e65c7SAxel Dörfler 	if (rect.right < barFrame.right) {
386075e65c7SAxel Dörfler 		// empty space
387f466d35dSStephan Aßmus 		rect.left = rect.right + 1;
388075e65c7SAxel Dörfler 		rect.right = barFrame.right;
389075e65c7SAxel Dörfler 		SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT));
39052a38012Sejakowatz 		FillRect(rect);
39152a38012Sejakowatz 	}
39252a38012Sejakowatz }
3933583227cSStefano Ceccherini 
3943583227cSStefano Ceccherini 
3953583227cSStefano Ceccherini void
39689208c77SStephan Aßmus BStatusBar::MessageReceived(BMessage *message)
39789208c77SStephan Aßmus {
39889208c77SStephan Aßmus 	switch(message->what) {
39989208c77SStephan Aßmus 		case B_UPDATE_STATUS_BAR:
40089208c77SStephan Aßmus 		{
40189208c77SStephan Aßmus 			float delta;
40289208c77SStephan Aßmus 			const char *text = NULL, *trailing_text = NULL;
40389208c77SStephan Aßmus 
40489208c77SStephan Aßmus 			message->FindFloat("delta", &delta);
40589208c77SStephan Aßmus 			message->FindString("text", &text);
40689208c77SStephan Aßmus 			message->FindString("trailing_text", &trailing_text);
40789208c77SStephan Aßmus 
40889208c77SStephan Aßmus 			Update(delta, text, trailing_text);
40989208c77SStephan Aßmus 
41089208c77SStephan Aßmus 			break;
41189208c77SStephan Aßmus 		}
41289208c77SStephan Aßmus 
41389208c77SStephan Aßmus 		case B_RESET_STATUS_BAR:
41489208c77SStephan Aßmus 		{
41589208c77SStephan Aßmus 			const char *label = NULL, *trailing_label = NULL;
41689208c77SStephan Aßmus 
41789208c77SStephan Aßmus 			message->FindString("label", &label);
41889208c77SStephan Aßmus 			message->FindString("trailing_label", &trailing_label);
41989208c77SStephan Aßmus 
42089208c77SStephan Aßmus 			Reset(label, trailing_label);
42189208c77SStephan Aßmus 
42289208c77SStephan Aßmus 			break;
42389208c77SStephan Aßmus 		}
42489208c77SStephan Aßmus 
42589208c77SStephan Aßmus 		default:
42689208c77SStephan Aßmus 			BView::MessageReceived(message);
42789208c77SStephan Aßmus 			break;
42889208c77SStephan Aßmus 	}
42989208c77SStephan Aßmus }
43089208c77SStephan Aßmus 
43189208c77SStephan Aßmus 
43289208c77SStephan Aßmus void
43389208c77SStephan Aßmus BStatusBar::MouseDown(BPoint point)
43489208c77SStephan Aßmus {
43589208c77SStephan Aßmus 	BView::MouseDown(point);
43689208c77SStephan Aßmus }
43789208c77SStephan Aßmus 
43889208c77SStephan Aßmus 
43989208c77SStephan Aßmus void
44089208c77SStephan Aßmus BStatusBar::MouseUp(BPoint point)
44189208c77SStephan Aßmus {
44289208c77SStephan Aßmus 	BView::MouseUp(point);
44389208c77SStephan Aßmus }
44489208c77SStephan Aßmus 
44589208c77SStephan Aßmus 
44689208c77SStephan Aßmus void
44789208c77SStephan Aßmus BStatusBar::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
44889208c77SStephan Aßmus {
44989208c77SStephan Aßmus 	BView::MouseMoved(point, transit, message);
45089208c77SStephan Aßmus }
45189208c77SStephan Aßmus 
45289208c77SStephan Aßmus 
45389208c77SStephan Aßmus // #pragma mark -
45489208c77SStephan Aßmus 
45589208c77SStephan Aßmus 
45689208c77SStephan Aßmus void
4573583227cSStefano Ceccherini BStatusBar::SetBarColor(rgb_color color)
45852a38012Sejakowatz {
45930d24296SMarcus Overhagen 	fBarColor = color;
46052a38012Sejakowatz 
46152a38012Sejakowatz 	Invalidate();
46252a38012Sejakowatz }
4633583227cSStefano Ceccherini 
4643583227cSStefano Ceccherini 
4653583227cSStefano Ceccherini void
466075e65c7SAxel Dörfler BStatusBar::SetBarHeight(float barHeight)
46752a38012Sejakowatz {
468075e65c7SAxel Dörfler 	float oldHeight = BarHeight();
46952a38012Sejakowatz 
47052a38012Sejakowatz 	fCustomBarHeight = true;
471075e65c7SAxel Dörfler 	fBarHeight = barHeight;
472075e65c7SAxel Dörfler 
473075e65c7SAxel Dörfler 	if (barHeight == oldHeight)
474075e65c7SAxel Dörfler 		return;
475075e65c7SAxel Dörfler 
476075e65c7SAxel Dörfler 	// resize so that the height fits
477a487da80SStephan Aßmus 	if ((Flags() & B_SUPPORTS_LAYOUT) != 0) {
478a487da80SStephan Aßmus 		InvalidateLayout();
479a487da80SStephan Aßmus 	} else {
480075e65c7SAxel Dörfler 		float width, height;
481075e65c7SAxel Dörfler 		GetPreferredSize(&width, &height);
482075e65c7SAxel Dörfler 		ResizeTo(Bounds().Width(), height);
48352a38012Sejakowatz 	}
484a487da80SStephan Aßmus }
48552a38012Sejakowatz 
4863583227cSStefano Ceccherini 
4873583227cSStefano Ceccherini void
4883583227cSStefano Ceccherini BStatusBar::SetText(const char* string)
4893583227cSStefano Ceccherini {
490f466d35dSStephan Aßmus 	_SetTextData(fText, string, fLabel, false);
49152a38012Sejakowatz }
49252a38012Sejakowatz 
4933583227cSStefano Ceccherini 
4943583227cSStefano Ceccherini void
4953583227cSStefano Ceccherini BStatusBar::SetTrailingText(const char* string)
4963583227cSStefano Ceccherini {
497f466d35dSStephan Aßmus 	_SetTextData(fTrailingText, string, fTrailingLabel, true);
49852a38012Sejakowatz }
4993583227cSStefano Ceccherini 
5003583227cSStefano Ceccherini 
5013583227cSStefano Ceccherini void
5023583227cSStefano Ceccherini BStatusBar::SetMaxValue(float max)
50352a38012Sejakowatz {
504e51a01a5SRene Gollent 	// R5 and/or Zeta's SetMaxValue does not trigger an invalidate here.
505e51a01a5SRene Gollent 	// this is probably not ideal behavior, but it does break apps in some cases
506e51a01a5SRene Gollent 	// as observed with SpaceMonitor.
507e51a01a5SRene Gollent 	// TODO: revisit this when we break binary compatibility
50852a38012Sejakowatz 	fMax = max;
50952a38012Sejakowatz }
5103583227cSStefano Ceccherini 
5113583227cSStefano Ceccherini 
5123583227cSStefano Ceccherini void
5133583227cSStefano Ceccherini BStatusBar::Update(float delta, const char* text, const char* trailingText)
51452a38012Sejakowatz {
515ea1b25f5SStephan Aßmus 	// If any of these are NULL, the existing text remains (BeBook)
516ea1b25f5SStephan Aßmus 	if (text == NULL)
517ea1b25f5SStephan Aßmus 		text = fText.String();
518ea1b25f5SStephan Aßmus 	if (trailingText == NULL)
519ea1b25f5SStephan Aßmus 		trailingText = fTrailingText.String();
520075e65c7SAxel Dörfler 	BStatusBar::SetTo(fCurrent + delta, text, trailingText);
521075e65c7SAxel Dörfler }
52252a38012Sejakowatz 
523f45d1cc7SMarc Flerackers 
524075e65c7SAxel Dörfler void
52589208c77SStephan Aßmus BStatusBar::Reset(const char *label, const char *trailingLabel)
52689208c77SStephan Aßmus {
52789208c77SStephan Aßmus 	// Reset replaces the label and trailing label with copies of the
52889208c77SStephan Aßmus 	// strings passed as arguments. If either argument is NULL, the
52989208c77SStephan Aßmus 	// label or trailing label will be deleted and erased.
53089208c77SStephan Aßmus 	fLabel = label ? label : "";
53189208c77SStephan Aßmus 	fTrailingLabel = trailingLabel ? trailingLabel : "";
53289208c77SStephan Aßmus 
53389208c77SStephan Aßmus 	// Reset deletes and erases any text or trailing text
53489208c77SStephan Aßmus 	fText = "";
53589208c77SStephan Aßmus 	fTrailingText = "";
53689208c77SStephan Aßmus 
53789208c77SStephan Aßmus 	fCurrent = 0;
53889208c77SStephan Aßmus 	fMax = 100;
53989208c77SStephan Aßmus 
54089208c77SStephan Aßmus 	Invalidate();
54189208c77SStephan Aßmus }
54289208c77SStephan Aßmus 
54389208c77SStephan Aßmus 
54489208c77SStephan Aßmus void
545075e65c7SAxel Dörfler BStatusBar::SetTo(float value, const char* text, const char* trailingText)
546075e65c7SAxel Dörfler {
547a788be67SStephan Aßmus 	SetText(text);
548a788be67SStephan Aßmus 	SetTrailingText(trailingText);
54952a38012Sejakowatz 
550075e65c7SAxel Dörfler 	if (value > fMax)
551075e65c7SAxel Dörfler 		value = fMax;
552f466d35dSStephan Aßmus 	else if (value < 0)
553f466d35dSStephan Aßmus 		value = 0;
554075e65c7SAxel Dörfler 	if (value == fCurrent)
555075e65c7SAxel Dörfler 		return;
55652a38012Sejakowatz 
557075e65c7SAxel Dörfler 	BRect barFrame = _BarFrame();
558075e65c7SAxel Dörfler 	float oldPosition = _BarPosition(barFrame);
559075e65c7SAxel Dörfler 
560075e65c7SAxel Dörfler 	fCurrent = value;
561f466d35dSStephan Aßmus 
562075e65c7SAxel Dörfler 	float newPosition = _BarPosition(barFrame);
563075e65c7SAxel Dörfler 	if (oldPosition == newPosition)
564075e65c7SAxel Dörfler 		return;
565075e65c7SAxel Dörfler 
566f466d35dSStephan Aßmus 	// update only the part of the status bar with actual changes
567075e65c7SAxel Dörfler 	BRect update = barFrame;
568075e65c7SAxel Dörfler 	if (oldPosition < newPosition) {
569f466d35dSStephan Aßmus 		update.left = floorf(max_c(oldPosition - 1, update.left));
570f466d35dSStephan Aßmus 		update.right = ceilf(newPosition);
571075e65c7SAxel Dörfler 	} else {
572f466d35dSStephan Aßmus 		update.left = floorf(max_c(newPosition - 1, update.left));
573f466d35dSStephan Aßmus 		update.right = ceilf(oldPosition);
574075e65c7SAxel Dörfler 	}
575075e65c7SAxel Dörfler 
5762f86ba45SStephan Aßmus 	// TODO: Ask the BControlLook in the first place about dirty rect.
5772f86ba45SStephan Aßmus 	if (be_control_look)
5782f86ba45SStephan Aßmus 		update.InsetBy(-1, -1);
5792f86ba45SStephan Aßmus 
580075e65c7SAxel Dörfler 	Invalidate(update);
58152a38012Sejakowatz }
5823583227cSStefano Ceccherini 
5833583227cSStefano Ceccherini 
5843583227cSStefano Ceccherini float
5853583227cSStefano Ceccherini BStatusBar::CurrentValue() const
58652a38012Sejakowatz {
58752a38012Sejakowatz 	return fCurrent;
58852a38012Sejakowatz }
5893583227cSStefano Ceccherini 
5903583227cSStefano Ceccherini 
5913583227cSStefano Ceccherini float
5923583227cSStefano Ceccherini BStatusBar::MaxValue() const
59352a38012Sejakowatz {
59452a38012Sejakowatz 	return fMax;
59552a38012Sejakowatz }
5963583227cSStefano Ceccherini 
5973583227cSStefano Ceccherini 
5983583227cSStefano Ceccherini rgb_color
5993583227cSStefano Ceccherini BStatusBar::BarColor() const
60052a38012Sejakowatz {
60152a38012Sejakowatz 	return fBarColor;
60252a38012Sejakowatz }
6033583227cSStefano Ceccherini 
6043583227cSStefano Ceccherini 
6053583227cSStefano Ceccherini float
6063583227cSStefano Ceccherini BStatusBar::BarHeight() const
60752a38012Sejakowatz {
608f466d35dSStephan Aßmus 	if (!fCustomBarHeight && fBarHeight == -1) {
609075e65c7SAxel Dörfler 		// the default bar height is as height as the label
610075e65c7SAxel Dörfler 		font_height fontHeight;
611075e65c7SAxel Dörfler 		GetFontHeight(&fontHeight);
612075e65c7SAxel Dörfler 		const_cast<BStatusBar *>(this)->fBarHeight = fontHeight.ascent
613f466d35dSStephan Aßmus 			+ fontHeight.descent + 5;
61452a38012Sejakowatz 	}
61552a38012Sejakowatz 
616f466d35dSStephan Aßmus 	return ceilf(fBarHeight);
61752a38012Sejakowatz }
6183583227cSStefano Ceccherini 
6193583227cSStefano Ceccherini 
6203583227cSStefano Ceccherini const char *
6213583227cSStefano Ceccherini BStatusBar::Text() const
62252a38012Sejakowatz {
623075e65c7SAxel Dörfler 	return fText.String();
62452a38012Sejakowatz }
6253583227cSStefano Ceccherini 
6263583227cSStefano Ceccherini 
6273583227cSStefano Ceccherini const char *
6283583227cSStefano Ceccherini BStatusBar::TrailingText() const
62952a38012Sejakowatz {
630075e65c7SAxel Dörfler 	return fTrailingText.String();
63152a38012Sejakowatz }
6323583227cSStefano Ceccherini 
6333583227cSStefano Ceccherini 
6343583227cSStefano Ceccherini const char *
6353583227cSStefano Ceccherini BStatusBar::Label() const
63652a38012Sejakowatz {
637075e65c7SAxel Dörfler 	return fLabel.String();
63852a38012Sejakowatz }
6393583227cSStefano Ceccherini 
6403583227cSStefano Ceccherini 
6413583227cSStefano Ceccherini const char *
6423583227cSStefano Ceccherini BStatusBar::TrailingLabel() const
64352a38012Sejakowatz {
644075e65c7SAxel Dörfler 	return fTrailingLabel.String();
64552a38012Sejakowatz }
6463583227cSStefano Ceccherini 
6473583227cSStefano Ceccherini 
64889208c77SStephan Aßmus // #pragma mark -
6493583227cSStefano Ceccherini 
6503583227cSStefano Ceccherini 
6513583227cSStefano Ceccherini BHandler *
6523583227cSStefano Ceccherini BStatusBar::ResolveSpecifier(BMessage* message, int32 index,
653075e65c7SAxel Dörfler 	BMessage* specifier, int32 what, const char *property)
65452a38012Sejakowatz {
65552a38012Sejakowatz 	return BView::ResolveSpecifier(message, index, specifier, what, property);
65652a38012Sejakowatz }
6573583227cSStefano Ceccherini 
6583583227cSStefano Ceccherini 
6593583227cSStefano Ceccherini status_t
6603583227cSStefano Ceccherini BStatusBar::GetSupportedSuites(BMessage* data)
66152a38012Sejakowatz {
66252a38012Sejakowatz 	return BView::GetSupportedSuites(data);
66352a38012Sejakowatz }
6643583227cSStefano Ceccherini 
6653583227cSStefano Ceccherini 
6663583227cSStefano Ceccherini status_t
66739fbf550SOliver Tappe BStatusBar::Perform(perform_code code, void* _data)
66852a38012Sejakowatz {
66939fbf550SOliver Tappe 	switch (code) {
67039fbf550SOliver Tappe 		case PERFORM_CODE_MIN_SIZE:
67139fbf550SOliver Tappe 			((perform_data_min_size*)_data)->return_value
67239fbf550SOliver Tappe 				= BStatusBar::MinSize();
67339fbf550SOliver Tappe 			return B_OK;
67439fbf550SOliver Tappe 		case PERFORM_CODE_MAX_SIZE:
67539fbf550SOliver Tappe 			((perform_data_max_size*)_data)->return_value
67639fbf550SOliver Tappe 				= BStatusBar::MaxSize();
67739fbf550SOliver Tappe 			return B_OK;
67839fbf550SOliver Tappe 		case PERFORM_CODE_PREFERRED_SIZE:
67939fbf550SOliver Tappe 			((perform_data_preferred_size*)_data)->return_value
68039fbf550SOliver Tappe 				= BStatusBar::PreferredSize();
68139fbf550SOliver Tappe 			return B_OK;
68239fbf550SOliver Tappe 		case PERFORM_CODE_LAYOUT_ALIGNMENT:
68339fbf550SOliver Tappe 			((perform_data_layout_alignment*)_data)->return_value
68439fbf550SOliver Tappe 				= BStatusBar::LayoutAlignment();
68539fbf550SOliver Tappe 			return B_OK;
68639fbf550SOliver Tappe 		case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH:
68739fbf550SOliver Tappe 			((perform_data_has_height_for_width*)_data)->return_value
68839fbf550SOliver Tappe 				= BStatusBar::HasHeightForWidth();
68939fbf550SOliver Tappe 			return B_OK;
69039fbf550SOliver Tappe 		case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH:
69139fbf550SOliver Tappe 		{
69239fbf550SOliver Tappe 			perform_data_get_height_for_width* data
69339fbf550SOliver Tappe 				= (perform_data_get_height_for_width*)_data;
69439fbf550SOliver Tappe 			BStatusBar::GetHeightForWidth(data->width, &data->min, &data->max,
69539fbf550SOliver Tappe 				&data->preferred);
69639fbf550SOliver Tappe 			return B_OK;
69739fbf550SOliver Tappe 		}
69839fbf550SOliver Tappe 		case PERFORM_CODE_SET_LAYOUT:
69939fbf550SOliver Tappe 		{
70039fbf550SOliver Tappe 			perform_data_set_layout* data = (perform_data_set_layout*)_data;
70139fbf550SOliver Tappe 			BStatusBar::SetLayout(data->layout);
70239fbf550SOliver Tappe 			return B_OK;
70339fbf550SOliver Tappe 		}
70439fbf550SOliver Tappe 		case PERFORM_CODE_INVALIDATE_LAYOUT:
70539fbf550SOliver Tappe 		{
70639fbf550SOliver Tappe 			perform_data_invalidate_layout* data
70739fbf550SOliver Tappe 				= (perform_data_invalidate_layout*)_data;
70839fbf550SOliver Tappe 			BStatusBar::InvalidateLayout(data->descendants);
70939fbf550SOliver Tappe 			return B_OK;
71039fbf550SOliver Tappe 		}
71139fbf550SOliver Tappe 		case PERFORM_CODE_DO_LAYOUT:
71239fbf550SOliver Tappe 		{
71339fbf550SOliver Tappe 			BStatusBar::DoLayout();
71439fbf550SOliver Tappe 			return B_OK;
71539fbf550SOliver Tappe 		}
71639fbf550SOliver Tappe 	}
71739fbf550SOliver Tappe 
71839fbf550SOliver Tappe 	return BView::Perform(code, _data);
71952a38012Sejakowatz }
7203583227cSStefano Ceccherini 
7213583227cSStefano Ceccherini 
72289208c77SStephan Aßmus // #pragma mark -
72389208c77SStephan Aßmus 
72489208c77SStephan Aßmus 
725b5a071bcSStephan Aßmus extern "C" void
726075e65c7SAxel Dörfler _ReservedStatusBar1__10BStatusBar(BStatusBar* self, float value,
727075e65c7SAxel Dörfler 	const char* text, const char* trailingText)
728075e65c7SAxel Dörfler {
729075e65c7SAxel Dörfler 	self->BStatusBar::SetTo(value, text, trailingText);
730075e65c7SAxel Dörfler }
731075e65c7SAxel Dörfler 
732075e65c7SAxel Dörfler 
73352a38012Sejakowatz void BStatusBar::_ReservedStatusBar2() {}
73452a38012Sejakowatz void BStatusBar::_ReservedStatusBar3() {}
73552a38012Sejakowatz void BStatusBar::_ReservedStatusBar4() {}
73652a38012Sejakowatz 
7373583227cSStefano Ceccherini 
7383583227cSStefano Ceccherini BStatusBar &
739075e65c7SAxel Dörfler BStatusBar::operator=(const BStatusBar& other)
74052a38012Sejakowatz {
74152a38012Sejakowatz 	return *this;
74252a38012Sejakowatz }
74352a38012Sejakowatz 
7443583227cSStefano Ceccherini 
74589208c77SStephan Aßmus // #pragma mark -
74689208c77SStephan Aßmus 
74789208c77SStephan Aßmus 
74889208c77SStephan Aßmus void
74989208c77SStephan Aßmus BStatusBar::_InitObject()
75089208c77SStephan Aßmus {
75189208c77SStephan Aßmus 	fMax = 100.0;
75289208c77SStephan Aßmus 	fCurrent = 0.0;
75389208c77SStephan Aßmus 
75489208c77SStephan Aßmus 	fBarHeight = -1.0;
75589208c77SStephan Aßmus 	fTextDivider = Bounds().Width();
75689208c77SStephan Aßmus 
75789208c77SStephan Aßmus 	fBarColor = kDefaultBarColor;
75889208c77SStephan Aßmus 	fCustomBarHeight = false;
75989208c77SStephan Aßmus 
76089208c77SStephan Aßmus 	SetFlags(Flags() | B_FRAME_EVENTS);
76189208c77SStephan Aßmus }
76289208c77SStephan Aßmus 
76389208c77SStephan Aßmus 
7643583227cSStefano Ceccherini void
765f466d35dSStephan Aßmus BStatusBar::_SetTextData(BString& text, const char* source,
766f466d35dSStephan Aßmus 	const BString& combineWith, bool rightAligned)
7673583227cSStefano Ceccherini {
768a788be67SStephan Aßmus 	if (source == NULL)
769a788be67SStephan Aßmus 		source = "";
770a788be67SStephan Aßmus 
771075e65c7SAxel Dörfler 	// If there were no changes, we don't have to do anything
772075e65c7SAxel Dörfler 	if (text == source)
773075e65c7SAxel Dörfler 		return;
774075e65c7SAxel Dörfler 
775f466d35dSStephan Aßmus 	float oldWidth;
776f466d35dSStephan Aßmus 	if (rightAligned)
777f466d35dSStephan Aßmus 		oldWidth = Bounds().right - fTextDivider;
778f466d35dSStephan Aßmus 	else
779f466d35dSStephan Aßmus 		oldWidth = fTextDivider;
780f466d35dSStephan Aßmus 
781*7ee23666SStephan Aßmus 	bool oldHasText = _HasText();
782*7ee23666SStephan Aßmus 
783075e65c7SAxel Dörfler 	text = source;
784f466d35dSStephan Aßmus 
785f466d35dSStephan Aßmus 	BString newString;
786f466d35dSStephan Aßmus 	if (rightAligned)
787f466d35dSStephan Aßmus 		newString << text << combineWith;
788f466d35dSStephan Aßmus 	else
789f466d35dSStephan Aßmus 		newString << combineWith << text;
790f466d35dSStephan Aßmus 
791f466d35dSStephan Aßmus 	float newWidth = ceilf(StringWidth(newString.String()));
792f466d35dSStephan Aßmus 		// might still be smaller in Draw(), but we use it
793f466d35dSStephan Aßmus 		// only for the invalidation rect here
794075e65c7SAxel Dörfler 
795075e65c7SAxel Dörfler 	// determine which part of the view needs an update
796f466d35dSStephan Aßmus 	float invalidateWidth = max_c(newWidth, oldWidth);
797075e65c7SAxel Dörfler 
798f466d35dSStephan Aßmus 	float position = 0.0;
799075e65c7SAxel Dörfler 	if (rightAligned)
800f466d35dSStephan Aßmus 		position = Bounds().right - invalidateWidth;
801075e65c7SAxel Dörfler 
802*7ee23666SStephan Aßmus 	if (oldHasText != _HasText())
803*7ee23666SStephan Aßmus 		InvalidateLayout();
804*7ee23666SStephan Aßmus 
805075e65c7SAxel Dörfler 	font_height fontHeight;
806075e65c7SAxel Dörfler 	GetFontHeight(&fontHeight);
807075e65c7SAxel Dörfler 
808f466d35dSStephan Aßmus //	Invalidate(BRect(position, 0, position + invalidateWidth,
809f466d35dSStephan Aßmus //		ceilf(fontHeight.ascent) + ceilf(fontHeight.descent)));
810f466d35dSStephan Aßmus // TODO: redrawing the entire area takes care of the edge case
811f466d35dSStephan Aßmus // where the left side string changes because of truncation and
812f466d35dSStephan Aßmus // part of it needs to be redrawn as well.
813f466d35dSStephan Aßmus 	Invalidate(BRect(0, 0, Bounds().right,
814f466d35dSStephan Aßmus 		ceilf(fontHeight.ascent) + ceilf(fontHeight.descent)));
8153583227cSStefano Ceccherini }
8163583227cSStefano Ceccherini 
8173583227cSStefano Ceccherini 
818075e65c7SAxel Dörfler /*!
819075e65c7SAxel Dörfler 	Returns the inner bar frame without the surrounding bevel.
820075e65c7SAxel Dörfler */
821075e65c7SAxel Dörfler BRect
822075e65c7SAxel Dörfler BStatusBar::_BarFrame(const font_height* fontHeight) const
8233583227cSStefano Ceccherini {
824a487da80SStephan Aßmus 	float top = 2;
825a487da80SStephan Aßmus 	if (_HasText()) {
826075e65c7SAxel Dörfler 		if (fontHeight == NULL) {
827075e65c7SAxel Dörfler 			font_height height;
828075e65c7SAxel Dörfler 			GetFontHeight(&height);
829f466d35dSStephan Aßmus 			top = ceilf(height.ascent + height.descent) + 6;
830075e65c7SAxel Dörfler 		} else
831f466d35dSStephan Aßmus 			top = ceilf(fontHeight->ascent + fontHeight->descent) + 6;
832a487da80SStephan Aßmus 	}
8333583227cSStefano Ceccherini 
834f466d35dSStephan Aßmus 	return BRect(2, top, Bounds().right - 2, top + BarHeight() - 4);
8353583227cSStefano Ceccherini }
8363583227cSStefano Ceccherini 
8373583227cSStefano Ceccherini 
838075e65c7SAxel Dörfler float
839075e65c7SAxel Dörfler BStatusBar::_BarPosition(const BRect& barFrame) const
8403583227cSStefano Ceccherini {
841f466d35dSStephan Aßmus 	if (fCurrent == 0)
842f466d35dSStephan Aßmus 		return barFrame.left - 1;
843075e65c7SAxel Dörfler 
8442f86ba45SStephan Aßmus 	return roundf(barFrame.left - 1
8452f86ba45SStephan Aßmus 		+ (fCurrent * (barFrame.Width() + 3) / fMax));
8463583227cSStefano Ceccherini }
8473583227cSStefano Ceccherini 
848a487da80SStephan Aßmus 
849a487da80SStephan Aßmus bool
850a487da80SStephan Aßmus BStatusBar::_HasText() const
851a487da80SStephan Aßmus {
852*7ee23666SStephan Aßmus 	// Force BeOS behavior where the size of the BStatusBar always included
853*7ee23666SStephan Aßmus 	// room for labels, even when there weren't any.
854*7ee23666SStephan Aßmus 	if ((Flags() & B_SUPPORTS_LAYOUT) == 0)
855*7ee23666SStephan Aßmus 		return true;
856a487da80SStephan Aßmus 	return fLabel.Length() > 0 || fTrailingLabel.Length() > 0
857a487da80SStephan Aßmus 		|| fTrailingText.Length() > 0 || fText.Length() > 0;
858a487da80SStephan Aßmus }
859