199f695c9SAxel Dörfler /*
27a96554cSlooncraz * Copyright 2001-2015, 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>
97a96554cSlooncraz * Joseph Groover <looncraz@looncraz.net>
1099f695c9SAxel Dörfler */
1199f695c9SAxel Dörfler
1299f695c9SAxel Dörfler /*! BStatusBar displays a "percentage-of-completion" gauge. */
13f466d35dSStephan Aßmus #include <StatusBar.h>
14f466d35dSStephan Aßmus
15f466d35dSStephan Aßmus #include <stdio.h>
16f466d35dSStephan Aßmus #include <stdlib.h>
17f466d35dSStephan Aßmus #include <string.h>
1852a38012Sejakowatz
192f86ba45SStephan Aßmus #include <ControlLook.h>
20d23c4822SIngo Weinhold #include <Layout.h>
21d23c4822SIngo Weinhold #include <LayoutUtils.h>
222f86ba45SStephan Aßmus #include <Message.h>
232f86ba45SStephan Aßmus #include <Region.h>
24d23c4822SIngo Weinhold
2539fbf550SOliver Tappe #include <binary_compatibility/Interface.h>
2639fbf550SOliver Tappe
277a96554cSlooncraz enum internalFlags {
287a96554cSlooncraz kCustomBarColor = 1
297a96554cSlooncraz };
30075e65c7SAxel Dörfler
31075e65c7SAxel Dörfler
BStatusBar(BRect frame,const char * name,const char * label,const char * trailingLabel)3252a38012Sejakowatz BStatusBar::BStatusBar(BRect frame, const char *name, const char *label,
3352a38012Sejakowatz const char *trailingLabel)
3489208c77SStephan Aßmus :
3589208c77SStephan Aßmus BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
36075e65c7SAxel Dörfler fLabel(label),
37075e65c7SAxel Dörfler fTrailingLabel(trailingLabel)
3852a38012Sejakowatz {
39075e65c7SAxel Dörfler _InitObject();
4052a38012Sejakowatz }
413583227cSStefano Ceccherini
423583227cSStefano Ceccherini
BStatusBar(const char * name,const char * label,const char * trailingLabel)43d23c4822SIngo Weinhold BStatusBar::BStatusBar(const char *name, const char *label,
44d23c4822SIngo Weinhold const char *trailingLabel)
4589208c77SStephan Aßmus :
4689208c77SStephan Aßmus BView(BRect(0, 0, -1, -1), name, B_FOLLOW_LEFT | B_FOLLOW_TOP,
47d23c4822SIngo Weinhold B_WILL_DRAW | B_SUPPORTS_LAYOUT),
48d23c4822SIngo Weinhold fLabel(label),
49d23c4822SIngo Weinhold fTrailingLabel(trailingLabel)
50d23c4822SIngo Weinhold {
51d23c4822SIngo Weinhold _InitObject();
52d23c4822SIngo Weinhold }
53d23c4822SIngo Weinhold
54d23c4822SIngo Weinhold
BStatusBar(BMessage * archive)5552a38012Sejakowatz BStatusBar::BStatusBar(BMessage *archive)
5689208c77SStephan Aßmus :
5789208c77SStephan Aßmus BView(archive)
5852a38012Sejakowatz {
59075e65c7SAxel Dörfler _InitObject();
603583227cSStefano Ceccherini
61075e65c7SAxel Dörfler archive->FindString("_label", &fLabel);
62075e65c7SAxel Dörfler archive->FindString("_tlabel", &fTrailingLabel);
633583227cSStefano Ceccherini
64075e65c7SAxel Dörfler archive->FindString("_text", &fText);
65075e65c7SAxel Dörfler archive->FindString("_ttext", &fTrailingText);
6652a38012Sejakowatz
67075e65c7SAxel Dörfler float floatValue;
68075e65c7SAxel Dörfler if (archive->FindFloat("_high", &floatValue) == B_OK) {
69075e65c7SAxel Dörfler fBarHeight = floatValue;
70075e65c7SAxel Dörfler fCustomBarHeight = true;
71075e65c7SAxel Dörfler }
7252a38012Sejakowatz
73075e65c7SAxel Dörfler int32 color;
747a96554cSlooncraz if (archive->FindInt32("_bcolor", (int32 *)&color) == B_OK) {
75075e65c7SAxel Dörfler fBarColor = *(rgb_color *)&color;
767a96554cSlooncraz fInternalFlags |= kCustomBarColor;
777a96554cSlooncraz }
7852a38012Sejakowatz
79075e65c7SAxel Dörfler if (archive->FindFloat("_val", &floatValue) == B_OK)
80075e65c7SAxel Dörfler fCurrent = floatValue;
81075e65c7SAxel Dörfler if (archive->FindFloat("_max", &floatValue) == B_OK)
82075e65c7SAxel Dörfler fMax = floatValue;
8352a38012Sejakowatz }
843583227cSStefano Ceccherini
853583227cSStefano Ceccherini
~BStatusBar()8652a38012Sejakowatz BStatusBar::~BStatusBar()
8752a38012Sejakowatz {
88075e65c7SAxel Dörfler }
89075e65c7SAxel Dörfler
90075e65c7SAxel Dörfler
913583227cSStefano Ceccherini BArchivable *
Instantiate(BMessage * archive)923583227cSStefano Ceccherini BStatusBar::Instantiate(BMessage *archive)
9352a38012Sejakowatz {
9452a38012Sejakowatz if (validate_instantiation(archive, "BStatusBar"))
9552a38012Sejakowatz return new BStatusBar(archive);
9652a38012Sejakowatz
9752a38012Sejakowatz return NULL;
9852a38012Sejakowatz }
993583227cSStefano Ceccherini
1003583227cSStefano Ceccherini
1013583227cSStefano Ceccherini status_t
Archive(BMessage * archive,bool deep) const1023583227cSStefano Ceccherini BStatusBar::Archive(BMessage *archive, bool deep) const
10352a38012Sejakowatz {
1048f3e1554SMarc Flerackers status_t err = BView::Archive(archive, deep);
1053583227cSStefano Ceccherini if (err < B_OK)
1068f3e1554SMarc Flerackers return err;
10752a38012Sejakowatz
108075e65c7SAxel Dörfler if (fCustomBarHeight)
1098f3e1554SMarc Flerackers err = archive->AddFloat("_high", fBarHeight);
1108f3e1554SMarc Flerackers
1117a96554cSlooncraz if (err == B_OK && fInternalFlags & kCustomBarColor)
11230d24296SMarcus Overhagen err = archive->AddInt32("_bcolor", (const uint32 &)fBarColor);
1138f3e1554SMarc Flerackers
114f466d35dSStephan Aßmus if (err == B_OK && fCurrent != 0)
1158f3e1554SMarc Flerackers err = archive->AddFloat("_val", fCurrent);
116f466d35dSStephan Aßmus if (err == B_OK && fMax != 100 )
1178f3e1554SMarc Flerackers err = archive->AddFloat("_max", fMax);
1188f3e1554SMarc Flerackers
119075e65c7SAxel Dörfler if (err == B_OK && fText.Length())
1208f3e1554SMarc Flerackers err = archive->AddString("_text", fText);
121075e65c7SAxel Dörfler if (err == B_OK && fTrailingText.Length())
1228f3e1554SMarc Flerackers err = archive->AddString("_ttext", fTrailingText);
1238f3e1554SMarc Flerackers
124075e65c7SAxel Dörfler if (err == B_OK && fLabel.Length())
1258f3e1554SMarc Flerackers err = archive->AddString("_label", fLabel);
126075e65c7SAxel Dörfler if (err == B_OK && fTrailingLabel.Length())
1278f3e1554SMarc Flerackers err = archive->AddString ("_tlabel", fTrailingLabel);
12852a38012Sejakowatz
1298f3e1554SMarc Flerackers return err;
13052a38012Sejakowatz }
1313583227cSStefano Ceccherini
1323583227cSStefano Ceccherini
13389208c77SStephan Aßmus // #pragma mark -
13489208c77SStephan Aßmus
13589208c77SStephan Aßmus
1363583227cSStefano Ceccherini void
AttachedToWindow()1373583227cSStefano Ceccherini BStatusBar::AttachedToWindow()
13852a38012Sejakowatz {
139075e65c7SAxel Dörfler // resize so that the height fits
14052a38012Sejakowatz float width, height;
14152a38012Sejakowatz GetPreferredSize(&width, &height);
142075e65c7SAxel Dörfler ResizeTo(Bounds().Width(), height);
14352a38012Sejakowatz
144075e65c7SAxel Dörfler SetViewColor(B_TRANSPARENT_COLOR);
145075e65c7SAxel Dörfler
1467a96554cSlooncraz AdoptParentColors();
147075e65c7SAxel Dörfler
148f466d35dSStephan Aßmus fTextDivider = Bounds().Width();
1497a96554cSlooncraz
1507a96554cSlooncraz if ((fInternalFlags & kCustomBarColor) == 0)
15180bc632aSAugustin Cavalier fBarColor = ui_color(B_STATUS_BAR_COLOR);
15252a38012Sejakowatz }
1533583227cSStefano Ceccherini
1543583227cSStefano Ceccherini
1553583227cSStefano Ceccherini void
DetachedFromWindow()15689208c77SStephan Aßmus BStatusBar::DetachedFromWindow()
15752a38012Sejakowatz {
15889208c77SStephan Aßmus BView::DetachedFromWindow();
15989208c77SStephan Aßmus }
16089208c77SStephan Aßmus
16189208c77SStephan Aßmus
16289208c77SStephan Aßmus void
AllAttached()16389208c77SStephan Aßmus BStatusBar::AllAttached()
16452a38012Sejakowatz {
16589208c77SStephan Aßmus BView::AllAttached();
16652a38012Sejakowatz }
1673583227cSStefano Ceccherini
16889208c77SStephan Aßmus
16989208c77SStephan Aßmus void
AllDetached()17089208c77SStephan Aßmus BStatusBar::AllDetached()
17152a38012Sejakowatz {
17289208c77SStephan Aßmus BView::AllDetached();
17352a38012Sejakowatz }
1743583227cSStefano Ceccherini
17589208c77SStephan Aßmus
17689208c77SStephan Aßmus // #pragma mark -
17789208c77SStephan Aßmus
17889208c77SStephan Aßmus
17989208c77SStephan Aßmus void
WindowActivated(bool state)18089208c77SStephan Aßmus BStatusBar::WindowActivated(bool state)
18189208c77SStephan Aßmus {
18289208c77SStephan Aßmus BView::WindowActivated(state);
18389208c77SStephan Aßmus }
18489208c77SStephan Aßmus
18589208c77SStephan Aßmus
18689208c77SStephan Aßmus void
MakeFocus(bool state)18789208c77SStephan Aßmus BStatusBar::MakeFocus(bool state)
18889208c77SStephan Aßmus {
18989208c77SStephan Aßmus BView::MakeFocus(state);
19089208c77SStephan Aßmus }
19189208c77SStephan Aßmus
19289208c77SStephan Aßmus
19389208c77SStephan Aßmus // #pragma mark -
19489208c77SStephan Aßmus
19589208c77SStephan Aßmus
19689208c77SStephan Aßmus void
GetPreferredSize(float * _width,float * _height)19789208c77SStephan Aßmus BStatusBar::GetPreferredSize(float* _width, float* _height)
19889208c77SStephan Aßmus {
19989208c77SStephan Aßmus if (_width) {
20089208c77SStephan Aßmus // AttachedToWindow() might not have been called yet
20189208c77SStephan Aßmus *_width = ceilf(StringWidth(fLabel.String()))
20289208c77SStephan Aßmus + ceilf(StringWidth(fTrailingLabel.String()))
20389208c77SStephan Aßmus + ceilf(StringWidth(fText.String()))
20489208c77SStephan Aßmus + ceilf(StringWidth(fTrailingText.String()))
20589208c77SStephan Aßmus + 5;
20689208c77SStephan Aßmus }
20789208c77SStephan Aßmus
20889208c77SStephan Aßmus if (_height) {
209a487da80SStephan Aßmus float labelHeight = 0;
210a487da80SStephan Aßmus if (_HasText()) {
21189208c77SStephan Aßmus font_height fontHeight;
21289208c77SStephan Aßmus GetFontHeight(&fontHeight);
213a487da80SStephan Aßmus labelHeight = ceilf(fontHeight.ascent + fontHeight.descent) + 6;
214a487da80SStephan Aßmus }
21589208c77SStephan Aßmus
216a487da80SStephan Aßmus *_height = labelHeight + BarHeight();
21752a38012Sejakowatz }
21852a38012Sejakowatz }
2193583227cSStefano Ceccherini
2203583227cSStefano Ceccherini
22189208c77SStephan Aßmus BSize
MinSize()22289208c77SStephan Aßmus BStatusBar::MinSize()
22389208c77SStephan Aßmus {
22489208c77SStephan Aßmus float width, height;
22589208c77SStephan Aßmus GetPreferredSize(&width, &height);
22689208c77SStephan Aßmus
2278e80f8ccSczeidler return BLayoutUtils::ComposeSize(ExplicitMinSize(), BSize(width, height));
22889208c77SStephan Aßmus }
22989208c77SStephan Aßmus
23089208c77SStephan Aßmus
23189208c77SStephan Aßmus BSize
MaxSize()23289208c77SStephan Aßmus BStatusBar::MaxSize()
23389208c77SStephan Aßmus {
23489208c77SStephan Aßmus float width, height;
23589208c77SStephan Aßmus GetPreferredSize(&width, &height);
23689208c77SStephan Aßmus
23789208c77SStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
23889208c77SStephan Aßmus BSize(B_SIZE_UNLIMITED, height));
23989208c77SStephan Aßmus }
24089208c77SStephan Aßmus
24189208c77SStephan Aßmus
24289208c77SStephan Aßmus BSize
PreferredSize()24389208c77SStephan Aßmus BStatusBar::PreferredSize()
24489208c77SStephan Aßmus {
24589208c77SStephan Aßmus float width, height;
24689208c77SStephan Aßmus GetPreferredSize(&width, &height);
24789208c77SStephan Aßmus
2488e80f8ccSczeidler return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
2498e80f8ccSczeidler BSize(width, height));
25089208c77SStephan Aßmus }
25189208c77SStephan Aßmus
25289208c77SStephan Aßmus
25389208c77SStephan Aßmus void
ResizeToPreferred()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
FrameMoved(BPoint newPosition)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
FrameResized(float newWidth,float newHeight)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
Draw(BRect updateRect)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()) {
3137a96554cSlooncraz font.TruncateString(&rightText, B_TRUNCATE_BEGINNING,
3147a96554cSlooncraz rect.Width());
315f466d35dSStephan Aßmus fTextDivider -= StringWidth(rightText.String());
316075e65c7SAxel Dörfler }
317f466d35dSStephan Aßmus
318f466d35dSStephan Aßmus if (leftText.Length()) {
319f466d35dSStephan Aßmus float width = max_c(0.0, fTextDivider - rect.left);
320f466d35dSStephan Aßmus font.TruncateString(&leftText, B_TRUNCATE_END, width);
321f466d35dSStephan Aßmus }
322f466d35dSStephan Aßmus
3237a96554cSlooncraz rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
3247a96554cSlooncraz
3257a96554cSlooncraz if (backgroundColor != ui_color(B_PANEL_BACKGROUND_COLOR)) {
326*9c274ccdSPascal Abresch if (backgroundColor.IsLight())
3277a96554cSlooncraz textColor = make_color(0, 0, 0, 255);
3287a96554cSlooncraz else
3297a96554cSlooncraz textColor = make_color(255, 255, 255, 255);
3307a96554cSlooncraz }
3317a96554cSlooncraz
3327a96554cSlooncraz SetHighColor(textColor);
333f466d35dSStephan Aßmus
334f466d35dSStephan Aßmus if (leftText.Length())
335f466d35dSStephan Aßmus DrawString(leftText.String(), BPoint(rect.left, baseLine));
336f466d35dSStephan Aßmus
337f466d35dSStephan Aßmus if (rightText.Length())
338f466d35dSStephan Aßmus DrawString(rightText.String(), BPoint(fTextDivider, baseLine));
33952a38012Sejakowatz }
34052a38012Sejakowatz
341075e65c7SAxel Dörfler // Draw bar
3420dc199a5SMarc Flerackers
343075e65c7SAxel Dörfler if (!updateRect.Intersects(outerFrame))
344075e65c7SAxel Dörfler return;
345075e65c7SAxel Dörfler
346075e65c7SAxel Dörfler rect = outerFrame;
34752a38012Sejakowatz
3482f86ba45SStephan Aßmus be_control_look->DrawStatusBar(this, rect, updateRect,
3492f86ba45SStephan Aßmus backgroundColor, fBarColor, _BarPosition(barFrame));
35052a38012Sejakowatz }
3513583227cSStefano Ceccherini
3523583227cSStefano Ceccherini
3533583227cSStefano Ceccherini void
MessageReceived(BMessage * message)35489208c77SStephan Aßmus BStatusBar::MessageReceived(BMessage *message)
35589208c77SStephan Aßmus {
35689208c77SStephan Aßmus switch(message->what) {
35789208c77SStephan Aßmus case B_UPDATE_STATUS_BAR:
35889208c77SStephan Aßmus {
35989208c77SStephan Aßmus float delta;
36089208c77SStephan Aßmus const char *text = NULL, *trailing_text = NULL;
36189208c77SStephan Aßmus
36289208c77SStephan Aßmus message->FindFloat("delta", &delta);
36389208c77SStephan Aßmus message->FindString("text", &text);
36489208c77SStephan Aßmus message->FindString("trailing_text", &trailing_text);
36589208c77SStephan Aßmus
36689208c77SStephan Aßmus Update(delta, text, trailing_text);
36789208c77SStephan Aßmus
36889208c77SStephan Aßmus break;
36989208c77SStephan Aßmus }
37089208c77SStephan Aßmus
37189208c77SStephan Aßmus case B_RESET_STATUS_BAR:
37289208c77SStephan Aßmus {
37389208c77SStephan Aßmus const char *label = NULL, *trailing_label = NULL;
37489208c77SStephan Aßmus
37589208c77SStephan Aßmus message->FindString("label", &label);
37689208c77SStephan Aßmus message->FindString("trailing_label", &trailing_label);
37789208c77SStephan Aßmus
37889208c77SStephan Aßmus Reset(label, trailing_label);
37989208c77SStephan Aßmus
38089208c77SStephan Aßmus break;
38189208c77SStephan Aßmus }
38289208c77SStephan Aßmus
3837a96554cSlooncraz case B_COLORS_UPDATED:
3847a96554cSlooncraz {
3857a96554cSlooncraz // Change the bar color IF we don't have an application-set color.
3867a96554cSlooncraz if ((fInternalFlags & kCustomBarColor) == 0) {
38780bc632aSAugustin Cavalier message->FindColor(ui_color_name(B_STATUS_BAR_COLOR),
3887a96554cSlooncraz &fBarColor);
3897a96554cSlooncraz }
3907a96554cSlooncraz
3917a96554cSlooncraz break;
3927a96554cSlooncraz }
3937a96554cSlooncraz
39489208c77SStephan Aßmus default:
39589208c77SStephan Aßmus BView::MessageReceived(message);
39689208c77SStephan Aßmus break;
39789208c77SStephan Aßmus }
39889208c77SStephan Aßmus }
39989208c77SStephan Aßmus
40089208c77SStephan Aßmus
40189208c77SStephan Aßmus void
MouseDown(BPoint point)40289208c77SStephan Aßmus BStatusBar::MouseDown(BPoint point)
40389208c77SStephan Aßmus {
40489208c77SStephan Aßmus BView::MouseDown(point);
40589208c77SStephan Aßmus }
40689208c77SStephan Aßmus
40789208c77SStephan Aßmus
40889208c77SStephan Aßmus void
MouseUp(BPoint point)40989208c77SStephan Aßmus BStatusBar::MouseUp(BPoint point)
41089208c77SStephan Aßmus {
41189208c77SStephan Aßmus BView::MouseUp(point);
41289208c77SStephan Aßmus }
41389208c77SStephan Aßmus
41489208c77SStephan Aßmus
41589208c77SStephan Aßmus void
MouseMoved(BPoint point,uint32 transit,const BMessage * message)41689208c77SStephan Aßmus BStatusBar::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
41789208c77SStephan Aßmus {
41889208c77SStephan Aßmus BView::MouseMoved(point, transit, message);
41989208c77SStephan Aßmus }
42089208c77SStephan Aßmus
42189208c77SStephan Aßmus
42289208c77SStephan Aßmus // #pragma mark -
42389208c77SStephan Aßmus
42489208c77SStephan Aßmus
42589208c77SStephan Aßmus void
SetBarColor(rgb_color color)4263583227cSStefano Ceccherini BStatusBar::SetBarColor(rgb_color color)
42752a38012Sejakowatz {
4287a96554cSlooncraz fInternalFlags |= kCustomBarColor;
42930d24296SMarcus Overhagen fBarColor = color;
43052a38012Sejakowatz
43152a38012Sejakowatz Invalidate();
43252a38012Sejakowatz }
4333583227cSStefano Ceccherini
4343583227cSStefano Ceccherini
4353583227cSStefano Ceccherini void
SetBarHeight(float barHeight)436075e65c7SAxel Dörfler BStatusBar::SetBarHeight(float barHeight)
43752a38012Sejakowatz {
438075e65c7SAxel Dörfler float oldHeight = BarHeight();
43952a38012Sejakowatz
44052a38012Sejakowatz fCustomBarHeight = true;
441075e65c7SAxel Dörfler fBarHeight = barHeight;
442075e65c7SAxel Dörfler
443075e65c7SAxel Dörfler if (barHeight == oldHeight)
444075e65c7SAxel Dörfler return;
445075e65c7SAxel Dörfler
446075e65c7SAxel Dörfler // resize so that the height fits
44726fe4141SStephan Aßmus if ((Flags() & B_SUPPORTS_LAYOUT) != 0)
448a487da80SStephan Aßmus InvalidateLayout();
44926fe4141SStephan Aßmus else {
450075e65c7SAxel Dörfler float width, height;
451075e65c7SAxel Dörfler GetPreferredSize(&width, &height);
452075e65c7SAxel Dörfler ResizeTo(Bounds().Width(), height);
45352a38012Sejakowatz }
454a487da80SStephan Aßmus }
45552a38012Sejakowatz
4563583227cSStefano Ceccherini
4573583227cSStefano Ceccherini void
SetText(const char * string)4583583227cSStefano Ceccherini BStatusBar::SetText(const char* string)
4593583227cSStefano Ceccherini {
460f466d35dSStephan Aßmus _SetTextData(fText, string, fLabel, false);
46152a38012Sejakowatz }
46252a38012Sejakowatz
4633583227cSStefano Ceccherini
4643583227cSStefano Ceccherini void
SetTrailingText(const char * string)4653583227cSStefano Ceccherini BStatusBar::SetTrailingText(const char* string)
4663583227cSStefano Ceccherini {
467f466d35dSStephan Aßmus _SetTextData(fTrailingText, string, fTrailingLabel, true);
46852a38012Sejakowatz }
4693583227cSStefano Ceccherini
4703583227cSStefano Ceccherini
4713583227cSStefano Ceccherini void
SetMaxValue(float max)4723583227cSStefano Ceccherini BStatusBar::SetMaxValue(float max)
47352a38012Sejakowatz {
474e51a01a5SRene Gollent // R5 and/or Zeta's SetMaxValue does not trigger an invalidate here.
475e51a01a5SRene Gollent // this is probably not ideal behavior, but it does break apps in some cases
476e51a01a5SRene Gollent // as observed with SpaceMonitor.
477e51a01a5SRene Gollent // TODO: revisit this when we break binary compatibility
47852a38012Sejakowatz fMax = max;
47952a38012Sejakowatz }
4803583227cSStefano Ceccherini
4813583227cSStefano Ceccherini
4823583227cSStefano Ceccherini void
Update(float delta,const char * text,const char * trailingText)4833583227cSStefano Ceccherini BStatusBar::Update(float delta, const char* text, const char* trailingText)
48452a38012Sejakowatz {
485ea1b25f5SStephan Aßmus // If any of these are NULL, the existing text remains (BeBook)
486ea1b25f5SStephan Aßmus if (text == NULL)
487ea1b25f5SStephan Aßmus text = fText.String();
488ea1b25f5SStephan Aßmus if (trailingText == NULL)
489ea1b25f5SStephan Aßmus trailingText = fTrailingText.String();
490075e65c7SAxel Dörfler BStatusBar::SetTo(fCurrent + delta, text, trailingText);
491075e65c7SAxel Dörfler }
49252a38012Sejakowatz
493f45d1cc7SMarc Flerackers
494075e65c7SAxel Dörfler void
Reset(const char * label,const char * trailingLabel)49589208c77SStephan Aßmus BStatusBar::Reset(const char *label, const char *trailingLabel)
49689208c77SStephan Aßmus {
49789208c77SStephan Aßmus // Reset replaces the label and trailing label with copies of the
49889208c77SStephan Aßmus // strings passed as arguments. If either argument is NULL, the
49989208c77SStephan Aßmus // label or trailing label will be deleted and erased.
50089208c77SStephan Aßmus fLabel = label ? label : "";
50189208c77SStephan Aßmus fTrailingLabel = trailingLabel ? trailingLabel : "";
50289208c77SStephan Aßmus
50389208c77SStephan Aßmus // Reset deletes and erases any text or trailing text
50489208c77SStephan Aßmus fText = "";
50589208c77SStephan Aßmus fTrailingText = "";
50689208c77SStephan Aßmus
50789208c77SStephan Aßmus fCurrent = 0;
50889208c77SStephan Aßmus fMax = 100;
50989208c77SStephan Aßmus
51089208c77SStephan Aßmus Invalidate();
51189208c77SStephan Aßmus }
51289208c77SStephan Aßmus
51389208c77SStephan Aßmus
51489208c77SStephan Aßmus void
SetTo(float value,const char * text,const char * trailingText)515075e65c7SAxel Dörfler BStatusBar::SetTo(float value, const char* text, const char* trailingText)
516075e65c7SAxel Dörfler {
517a788be67SStephan Aßmus SetText(text);
518a788be67SStephan Aßmus SetTrailingText(trailingText);
51952a38012Sejakowatz
520075e65c7SAxel Dörfler if (value > fMax)
521075e65c7SAxel Dörfler value = fMax;
522f466d35dSStephan Aßmus else if (value < 0)
523f466d35dSStephan Aßmus value = 0;
524075e65c7SAxel Dörfler if (value == fCurrent)
525075e65c7SAxel Dörfler return;
52652a38012Sejakowatz
527075e65c7SAxel Dörfler BRect barFrame = _BarFrame();
528075e65c7SAxel Dörfler float oldPosition = _BarPosition(barFrame);
529075e65c7SAxel Dörfler
530075e65c7SAxel Dörfler fCurrent = value;
531f466d35dSStephan Aßmus
532075e65c7SAxel Dörfler float newPosition = _BarPosition(barFrame);
533075e65c7SAxel Dörfler if (oldPosition == newPosition)
534075e65c7SAxel Dörfler return;
535075e65c7SAxel Dörfler
536f466d35dSStephan Aßmus // update only the part of the status bar with actual changes
537075e65c7SAxel Dörfler BRect update = barFrame;
538075e65c7SAxel Dörfler if (oldPosition < newPosition) {
539f466d35dSStephan Aßmus update.left = floorf(max_c(oldPosition - 1, update.left));
540f466d35dSStephan Aßmus update.right = ceilf(newPosition);
541075e65c7SAxel Dörfler } else {
542f466d35dSStephan Aßmus update.left = floorf(max_c(newPosition - 1, update.left));
543f466d35dSStephan Aßmus update.right = ceilf(oldPosition);
544075e65c7SAxel Dörfler }
545075e65c7SAxel Dörfler
5462f86ba45SStephan Aßmus // TODO: Ask the BControlLook in the first place about dirty rect.
5472f86ba45SStephan Aßmus update.InsetBy(-1, -1);
5482f86ba45SStephan Aßmus
549075e65c7SAxel Dörfler Invalidate(update);
55052a38012Sejakowatz }
5513583227cSStefano Ceccherini
5523583227cSStefano Ceccherini
5533583227cSStefano Ceccherini float
CurrentValue() const5543583227cSStefano Ceccherini BStatusBar::CurrentValue() const
55552a38012Sejakowatz {
55652a38012Sejakowatz return fCurrent;
55752a38012Sejakowatz }
5583583227cSStefano Ceccherini
5593583227cSStefano Ceccherini
5603583227cSStefano Ceccherini float
MaxValue() const5613583227cSStefano Ceccherini BStatusBar::MaxValue() const
56252a38012Sejakowatz {
56352a38012Sejakowatz return fMax;
56452a38012Sejakowatz }
5653583227cSStefano Ceccherini
5663583227cSStefano Ceccherini
5673583227cSStefano Ceccherini rgb_color
BarColor() const5683583227cSStefano Ceccherini BStatusBar::BarColor() const
56952a38012Sejakowatz {
57052a38012Sejakowatz return fBarColor;
57152a38012Sejakowatz }
5723583227cSStefano Ceccherini
5733583227cSStefano Ceccherini
5743583227cSStefano Ceccherini float
BarHeight() const5753583227cSStefano Ceccherini BStatusBar::BarHeight() const
57652a38012Sejakowatz {
577f466d35dSStephan Aßmus if (!fCustomBarHeight && fBarHeight == -1) {
578075e65c7SAxel Dörfler // the default bar height is as height as the label
579075e65c7SAxel Dörfler font_height fontHeight;
580075e65c7SAxel Dörfler GetFontHeight(&fontHeight);
581075e65c7SAxel Dörfler const_cast<BStatusBar *>(this)->fBarHeight = fontHeight.ascent
582f466d35dSStephan Aßmus + fontHeight.descent + 5;
58352a38012Sejakowatz }
58452a38012Sejakowatz
585f466d35dSStephan Aßmus return ceilf(fBarHeight);
58652a38012Sejakowatz }
5873583227cSStefano Ceccherini
5883583227cSStefano Ceccherini
5893583227cSStefano Ceccherini const char *
Text() const5903583227cSStefano Ceccherini BStatusBar::Text() const
59152a38012Sejakowatz {
592075e65c7SAxel Dörfler return fText.String();
59352a38012Sejakowatz }
5943583227cSStefano Ceccherini
5953583227cSStefano Ceccherini
5963583227cSStefano Ceccherini const char *
TrailingText() const5973583227cSStefano Ceccherini BStatusBar::TrailingText() const
59852a38012Sejakowatz {
599075e65c7SAxel Dörfler return fTrailingText.String();
60052a38012Sejakowatz }
6013583227cSStefano Ceccherini
6023583227cSStefano Ceccherini
6033583227cSStefano Ceccherini const char *
Label() const6043583227cSStefano Ceccherini BStatusBar::Label() const
60552a38012Sejakowatz {
606075e65c7SAxel Dörfler return fLabel.String();
60752a38012Sejakowatz }
6083583227cSStefano Ceccherini
6093583227cSStefano Ceccherini
6103583227cSStefano Ceccherini const char *
TrailingLabel() const6113583227cSStefano Ceccherini BStatusBar::TrailingLabel() const
61252a38012Sejakowatz {
613075e65c7SAxel Dörfler return fTrailingLabel.String();
61452a38012Sejakowatz }
6153583227cSStefano Ceccherini
6163583227cSStefano Ceccherini
61789208c77SStephan Aßmus // #pragma mark -
6183583227cSStefano Ceccherini
6193583227cSStefano Ceccherini
6203583227cSStefano Ceccherini BHandler *
ResolveSpecifier(BMessage * message,int32 index,BMessage * specifier,int32 what,const char * property)6213583227cSStefano Ceccherini BStatusBar::ResolveSpecifier(BMessage* message, int32 index,
622075e65c7SAxel Dörfler BMessage* specifier, int32 what, const char *property)
62352a38012Sejakowatz {
62452a38012Sejakowatz return BView::ResolveSpecifier(message, index, specifier, what, property);
62552a38012Sejakowatz }
6263583227cSStefano Ceccherini
6273583227cSStefano Ceccherini
6283583227cSStefano Ceccherini status_t
GetSupportedSuites(BMessage * data)6293583227cSStefano Ceccherini BStatusBar::GetSupportedSuites(BMessage* data)
63052a38012Sejakowatz {
63152a38012Sejakowatz return BView::GetSupportedSuites(data);
63252a38012Sejakowatz }
6333583227cSStefano Ceccherini
6343583227cSStefano Ceccherini
6353583227cSStefano Ceccherini status_t
Perform(perform_code code,void * _data)63639fbf550SOliver Tappe BStatusBar::Perform(perform_code code, void* _data)
63752a38012Sejakowatz {
63839fbf550SOliver Tappe switch (code) {
63939fbf550SOliver Tappe case PERFORM_CODE_MIN_SIZE:
64039fbf550SOliver Tappe ((perform_data_min_size*)_data)->return_value
64139fbf550SOliver Tappe = BStatusBar::MinSize();
64239fbf550SOliver Tappe return B_OK;
64339fbf550SOliver Tappe case PERFORM_CODE_MAX_SIZE:
64439fbf550SOliver Tappe ((perform_data_max_size*)_data)->return_value
64539fbf550SOliver Tappe = BStatusBar::MaxSize();
64639fbf550SOliver Tappe return B_OK;
64739fbf550SOliver Tappe case PERFORM_CODE_PREFERRED_SIZE:
64839fbf550SOliver Tappe ((perform_data_preferred_size*)_data)->return_value
64939fbf550SOliver Tappe = BStatusBar::PreferredSize();
65039fbf550SOliver Tappe return B_OK;
65139fbf550SOliver Tappe case PERFORM_CODE_LAYOUT_ALIGNMENT:
65239fbf550SOliver Tappe ((perform_data_layout_alignment*)_data)->return_value
65339fbf550SOliver Tappe = BStatusBar::LayoutAlignment();
65439fbf550SOliver Tappe return B_OK;
65539fbf550SOliver Tappe case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH:
65639fbf550SOliver Tappe ((perform_data_has_height_for_width*)_data)->return_value
65739fbf550SOliver Tappe = BStatusBar::HasHeightForWidth();
65839fbf550SOliver Tappe return B_OK;
65939fbf550SOliver Tappe case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH:
66039fbf550SOliver Tappe {
66139fbf550SOliver Tappe perform_data_get_height_for_width* data
66239fbf550SOliver Tappe = (perform_data_get_height_for_width*)_data;
66339fbf550SOliver Tappe BStatusBar::GetHeightForWidth(data->width, &data->min, &data->max,
66439fbf550SOliver Tappe &data->preferred);
66539fbf550SOliver Tappe return B_OK;
66639fbf550SOliver Tappe }
66739fbf550SOliver Tappe case PERFORM_CODE_SET_LAYOUT:
66839fbf550SOliver Tappe {
66939fbf550SOliver Tappe perform_data_set_layout* data = (perform_data_set_layout*)_data;
67039fbf550SOliver Tappe BStatusBar::SetLayout(data->layout);
67139fbf550SOliver Tappe return B_OK;
67239fbf550SOliver Tappe }
673eee4243dSAlex Wilson case PERFORM_CODE_LAYOUT_INVALIDATED:
67439fbf550SOliver Tappe {
675eee4243dSAlex Wilson perform_data_layout_invalidated* data
676eee4243dSAlex Wilson = (perform_data_layout_invalidated*)_data;
677eee4243dSAlex Wilson BStatusBar::LayoutInvalidated(data->descendants);
67839fbf550SOliver Tappe return B_OK;
67939fbf550SOliver Tappe }
68039fbf550SOliver Tappe case PERFORM_CODE_DO_LAYOUT:
68139fbf550SOliver Tappe {
68239fbf550SOliver Tappe BStatusBar::DoLayout();
68339fbf550SOliver Tappe return B_OK;
68439fbf550SOliver Tappe }
68539fbf550SOliver Tappe }
68639fbf550SOliver Tappe
68739fbf550SOliver Tappe return BView::Perform(code, _data);
68852a38012Sejakowatz }
6893583227cSStefano Ceccherini
6903583227cSStefano Ceccherini
69189208c77SStephan Aßmus // #pragma mark -
69289208c77SStephan Aßmus
69389208c77SStephan Aßmus
694b5a071bcSStephan Aßmus extern "C" void
_ReservedStatusBar1__10BStatusBar(BStatusBar * self,float value,const char * text,const char * trailingText)695075e65c7SAxel Dörfler _ReservedStatusBar1__10BStatusBar(BStatusBar* self, float value,
696075e65c7SAxel Dörfler const char* text, const char* trailingText)
697075e65c7SAxel Dörfler {
698075e65c7SAxel Dörfler self->BStatusBar::SetTo(value, text, trailingText);
699075e65c7SAxel Dörfler }
700075e65c7SAxel Dörfler
701075e65c7SAxel Dörfler
_ReservedStatusBar2()70252a38012Sejakowatz void BStatusBar::_ReservedStatusBar2() {}
_ReservedStatusBar3()70352a38012Sejakowatz void BStatusBar::_ReservedStatusBar3() {}
_ReservedStatusBar4()70452a38012Sejakowatz void BStatusBar::_ReservedStatusBar4() {}
70552a38012Sejakowatz
7063583227cSStefano Ceccherini
7073583227cSStefano Ceccherini BStatusBar &
operator =(const BStatusBar & other)708075e65c7SAxel Dörfler BStatusBar::operator=(const BStatusBar& other)
70952a38012Sejakowatz {
71052a38012Sejakowatz return *this;
71152a38012Sejakowatz }
71252a38012Sejakowatz
7133583227cSStefano Ceccherini
71489208c77SStephan Aßmus // #pragma mark -
71589208c77SStephan Aßmus
71689208c77SStephan Aßmus
71789208c77SStephan Aßmus void
_InitObject()71889208c77SStephan Aßmus BStatusBar::_InitObject()
71989208c77SStephan Aßmus {
72089208c77SStephan Aßmus fMax = 100.0;
72189208c77SStephan Aßmus fCurrent = 0.0;
72289208c77SStephan Aßmus
72389208c77SStephan Aßmus fBarHeight = -1.0;
72489208c77SStephan Aßmus fTextDivider = Bounds().Width();
72589208c77SStephan Aßmus
72689208c77SStephan Aßmus fCustomBarHeight = false;
7277a96554cSlooncraz fInternalFlags = 0;
72889208c77SStephan Aßmus
72989208c77SStephan Aßmus SetFlags(Flags() | B_FRAME_EVENTS);
73089208c77SStephan Aßmus }
73189208c77SStephan Aßmus
73289208c77SStephan Aßmus
7333583227cSStefano Ceccherini void
_SetTextData(BString & text,const char * source,const BString & combineWith,bool rightAligned)734f466d35dSStephan Aßmus BStatusBar::_SetTextData(BString& text, const char* source,
735f466d35dSStephan Aßmus const BString& combineWith, bool rightAligned)
7363583227cSStefano Ceccherini {
737a788be67SStephan Aßmus if (source == NULL)
738a788be67SStephan Aßmus source = "";
739a788be67SStephan Aßmus
740075e65c7SAxel Dörfler // If there were no changes, we don't have to do anything
741075e65c7SAxel Dörfler if (text == source)
742075e65c7SAxel Dörfler return;
743075e65c7SAxel Dörfler
7447ee23666SStephan Aßmus bool oldHasText = _HasText();
745075e65c7SAxel Dörfler text = source;
746f466d35dSStephan Aßmus
747f466d35dSStephan Aßmus BString newString;
748f466d35dSStephan Aßmus if (rightAligned)
749f466d35dSStephan Aßmus newString << text << combineWith;
750f466d35dSStephan Aßmus else
751f466d35dSStephan Aßmus newString << combineWith << text;
752f466d35dSStephan Aßmus
7537ee23666SStephan Aßmus if (oldHasText != _HasText())
7547ee23666SStephan Aßmus InvalidateLayout();
7557ee23666SStephan Aßmus
756075e65c7SAxel Dörfler font_height fontHeight;
757075e65c7SAxel Dörfler GetFontHeight(&fontHeight);
758075e65c7SAxel Dörfler
759f466d35dSStephan Aßmus // Invalidate(BRect(position, 0, position + invalidateWidth,
760f466d35dSStephan Aßmus // ceilf(fontHeight.ascent) + ceilf(fontHeight.descent)));
761f466d35dSStephan Aßmus // TODO: redrawing the entire area takes care of the edge case
762f466d35dSStephan Aßmus // where the left side string changes because of truncation and
763f466d35dSStephan Aßmus // part of it needs to be redrawn as well.
764f466d35dSStephan Aßmus Invalidate(BRect(0, 0, Bounds().right,
765f466d35dSStephan Aßmus ceilf(fontHeight.ascent) + ceilf(fontHeight.descent)));
7663583227cSStefano Ceccherini }
7673583227cSStefano Ceccherini
7683583227cSStefano Ceccherini
769075e65c7SAxel Dörfler /*!
770075e65c7SAxel Dörfler Returns the inner bar frame without the surrounding bevel.
771075e65c7SAxel Dörfler */
772075e65c7SAxel Dörfler BRect
_BarFrame(const font_height * fontHeight) const773075e65c7SAxel Dörfler BStatusBar::_BarFrame(const font_height* fontHeight) const
7743583227cSStefano Ceccherini {
775a487da80SStephan Aßmus float top = 2;
776a487da80SStephan Aßmus if (_HasText()) {
777075e65c7SAxel Dörfler if (fontHeight == NULL) {
778075e65c7SAxel Dörfler font_height height;
779075e65c7SAxel Dörfler GetFontHeight(&height);
780f466d35dSStephan Aßmus top = ceilf(height.ascent + height.descent) + 6;
781075e65c7SAxel Dörfler } else
782f466d35dSStephan Aßmus top = ceilf(fontHeight->ascent + fontHeight->descent) + 6;
783a487da80SStephan Aßmus }
7843583227cSStefano Ceccherini
785f466d35dSStephan Aßmus return BRect(2, top, Bounds().right - 2, top + BarHeight() - 4);
7863583227cSStefano Ceccherini }
7873583227cSStefano Ceccherini
7883583227cSStefano Ceccherini
789075e65c7SAxel Dörfler float
_BarPosition(const BRect & barFrame) const790075e65c7SAxel Dörfler BStatusBar::_BarPosition(const BRect& barFrame) const
7913583227cSStefano Ceccherini {
792f466d35dSStephan Aßmus if (fCurrent == 0)
793f466d35dSStephan Aßmus return barFrame.left - 1;
794075e65c7SAxel Dörfler
7952f86ba45SStephan Aßmus return roundf(barFrame.left - 1
7962f86ba45SStephan Aßmus + (fCurrent * (barFrame.Width() + 3) / fMax));
7973583227cSStefano Ceccherini }
7983583227cSStefano Ceccherini
799a487da80SStephan Aßmus
800a487da80SStephan Aßmus bool
_HasText() const801a487da80SStephan Aßmus BStatusBar::_HasText() const
802a487da80SStephan Aßmus {
8037ee23666SStephan Aßmus // Force BeOS behavior where the size of the BStatusBar always included
8047ee23666SStephan Aßmus // room for labels, even when there weren't any.
8057ee23666SStephan Aßmus if ((Flags() & B_SUPPORTS_LAYOUT) == 0)
8067ee23666SStephan Aßmus return true;
807a487da80SStephan Aßmus return fLabel.Length() > 0 || fTrailingLabel.Length() > 0
808a487da80SStephan Aßmus || fTrailingText.Length() > 0 || fText.Length() > 0;
809a487da80SStephan Aßmus }
810