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 228*8e80f8ccSczeidler return BLayoutUtils::ComposeSize(ExplicitMinSize(), 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 249*8e80f8ccSczeidler return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), 250*8e80f8ccSczeidler BSize(width, height)); 25189208c77SStephan Aßmus } 25289208c77SStephan Aßmus 25389208c77SStephan Aßmus 25489208c77SStephan Aßmus void 25589208c77SStephan Aßmus BStatusBar::ResizeToPreferred() 25689208c77SStephan Aßmus { 25789208c77SStephan Aßmus BView::ResizeToPreferred(); 25889208c77SStephan Aßmus } 25989208c77SStephan Aßmus 26089208c77SStephan Aßmus 26189208c77SStephan Aßmus void 26289208c77SStephan Aßmus BStatusBar::FrameMoved(BPoint newPosition) 26389208c77SStephan Aßmus { 26489208c77SStephan Aßmus BView::FrameMoved(newPosition); 26589208c77SStephan Aßmus } 26689208c77SStephan Aßmus 26789208c77SStephan Aßmus 26889208c77SStephan Aßmus void 26989208c77SStephan Aßmus BStatusBar::FrameResized(float newWidth, float newHeight) 27089208c77SStephan Aßmus { 27189208c77SStephan Aßmus BView::FrameResized(newWidth, newHeight); 27289208c77SStephan Aßmus Invalidate(); 27389208c77SStephan Aßmus } 27489208c77SStephan Aßmus 27589208c77SStephan Aßmus 27689208c77SStephan Aßmus // #pragma mark - 27789208c77SStephan Aßmus 27889208c77SStephan Aßmus 2793583227cSStefano Ceccherini void 2803583227cSStefano Ceccherini BStatusBar::Draw(BRect updateRect) 28152a38012Sejakowatz { 282861e4437SStephan Aßmus rgb_color backgroundColor = LowColor(); 28352a38012Sejakowatz 284075e65c7SAxel Dörfler font_height fontHeight; 285075e65c7SAxel Dörfler GetFontHeight(&fontHeight); 286075e65c7SAxel Dörfler BRect barFrame = _BarFrame(&fontHeight); 287f466d35dSStephan Aßmus BRect outerFrame = barFrame.InsetByCopy(-2, -2); 2880dc199a5SMarc Flerackers 289075e65c7SAxel Dörfler BRegion background(updateRect); 290075e65c7SAxel Dörfler background.Exclude(outerFrame); 291075e65c7SAxel Dörfler FillRegion(&background, B_SOLID_LOW); 2920dc199a5SMarc Flerackers 293075e65c7SAxel Dörfler // Draw labels/texts 294075e65c7SAxel Dörfler 295075e65c7SAxel Dörfler BRect rect = outerFrame; 296f466d35dSStephan Aßmus rect.top = 0; 297f466d35dSStephan Aßmus rect.bottom = outerFrame.top - 1; 298075e65c7SAxel Dörfler 299075e65c7SAxel Dörfler if (updateRect.Intersects(rect)) { 300075e65c7SAxel Dörfler // update labels 301f466d35dSStephan Aßmus BString leftText; 302f466d35dSStephan Aßmus leftText << fLabel << fText; 303075e65c7SAxel Dörfler 304f466d35dSStephan Aßmus BString rightText; 305f466d35dSStephan Aßmus rightText << fTrailingText << fTrailingLabel; 306075e65c7SAxel Dörfler 307f466d35dSStephan Aßmus float baseLine = ceilf(fontHeight.ascent) + 1; 308f466d35dSStephan Aßmus fTextDivider = rect.right; 309075e65c7SAxel Dörfler 310f466d35dSStephan Aßmus BFont font; 311f466d35dSStephan Aßmus GetFont(&font); 312075e65c7SAxel Dörfler 313f466d35dSStephan Aßmus if (rightText.Length()) { 314f466d35dSStephan Aßmus font.TruncateString(&rightText, B_TRUNCATE_BEGINNING, 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 323f466d35dSStephan Aßmus SetHighColor(ui_color(B_CONTROL_TEXT_COLOR)); 324f466d35dSStephan Aßmus 325f466d35dSStephan Aßmus if (leftText.Length()) 326f466d35dSStephan Aßmus DrawString(leftText.String(), BPoint(rect.left, baseLine)); 327f466d35dSStephan Aßmus 328f466d35dSStephan Aßmus if (rightText.Length()) 329f466d35dSStephan Aßmus DrawString(rightText.String(), BPoint(fTextDivider, baseLine)); 330f466d35dSStephan Aßmus 33152a38012Sejakowatz } 33252a38012Sejakowatz 333075e65c7SAxel Dörfler // Draw bar 3340dc199a5SMarc Flerackers 335075e65c7SAxel Dörfler if (!updateRect.Intersects(outerFrame)) 336075e65c7SAxel Dörfler return; 337075e65c7SAxel Dörfler 338075e65c7SAxel Dörfler rect = outerFrame; 33952a38012Sejakowatz 3402f86ba45SStephan Aßmus if (be_control_look != NULL) { 3412f86ba45SStephan Aßmus be_control_look->DrawStatusBar(this, rect, updateRect, 3422f86ba45SStephan Aßmus backgroundColor, fBarColor, _BarPosition(barFrame)); 3432f86ba45SStephan Aßmus return; 3442f86ba45SStephan Aßmus } 3452f86ba45SStephan Aßmus 34652a38012Sejakowatz // First bevel 34752a38012Sejakowatz SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT)); 348075e65c7SAxel Dörfler StrokeLine(rect.LeftBottom(), rect.LeftTop()); 349075e65c7SAxel Dörfler StrokeLine(rect.RightTop()); 35052a38012Sejakowatz 35152a38012Sejakowatz SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT)); 352f466d35dSStephan Aßmus StrokeLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom()); 353f466d35dSStephan Aßmus StrokeLine(BPoint(rect.right, rect.top + 1)); 35452a38012Sejakowatz 355f466d35dSStephan Aßmus rect.InsetBy(1, 1); 35652a38012Sejakowatz 35752a38012Sejakowatz // Second bevel 35852a38012Sejakowatz SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT)); 359075e65c7SAxel Dörfler StrokeLine(rect.LeftBottom(), rect.LeftTop()); 360075e65c7SAxel Dörfler StrokeLine(rect.RightTop()); 36152a38012Sejakowatz 36252a38012Sejakowatz SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 363f466d35dSStephan Aßmus StrokeLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom()); 364f466d35dSStephan Aßmus StrokeLine(BPoint(rect.right, rect.top + 1)); 36552a38012Sejakowatz 366075e65c7SAxel Dörfler rect = barFrame; 367075e65c7SAxel Dörfler rect.right = _BarPosition(barFrame); 36852a38012Sejakowatz 369075e65c7SAxel Dörfler // draw bar itself 37052a38012Sejakowatz 371075e65c7SAxel Dörfler if (rect.right >= rect.left) { 37252a38012Sejakowatz // Bevel 37352a38012Sejakowatz SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT)); 374075e65c7SAxel Dörfler StrokeLine(rect.LeftBottom(), rect.LeftTop()); 375075e65c7SAxel Dörfler StrokeLine(rect.RightTop()); 37652a38012Sejakowatz 37752a38012Sejakowatz SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT)); 378f466d35dSStephan Aßmus StrokeLine(BPoint(rect.left + 1, rect.bottom), rect.RightBottom()); 379f466d35dSStephan Aßmus StrokeLine(BPoint(rect.right, rect.top + 1)); 38052a38012Sejakowatz 381075e65c7SAxel Dörfler // filling 38252a38012Sejakowatz SetHighColor(fBarColor); 383f466d35dSStephan Aßmus FillRect(rect.InsetByCopy(1, 1)); 384075e65c7SAxel Dörfler } 385075e65c7SAxel Dörfler 386075e65c7SAxel Dörfler if (rect.right < barFrame.right) { 387075e65c7SAxel Dörfler // empty space 388f466d35dSStephan Aßmus rect.left = rect.right + 1; 389075e65c7SAxel Dörfler rect.right = barFrame.right; 390075e65c7SAxel Dörfler SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT)); 39152a38012Sejakowatz FillRect(rect); 39252a38012Sejakowatz } 39352a38012Sejakowatz } 3943583227cSStefano Ceccherini 3953583227cSStefano Ceccherini 3963583227cSStefano Ceccherini void 39789208c77SStephan Aßmus BStatusBar::MessageReceived(BMessage *message) 39889208c77SStephan Aßmus { 39989208c77SStephan Aßmus switch(message->what) { 40089208c77SStephan Aßmus case B_UPDATE_STATUS_BAR: 40189208c77SStephan Aßmus { 40289208c77SStephan Aßmus float delta; 40389208c77SStephan Aßmus const char *text = NULL, *trailing_text = NULL; 40489208c77SStephan Aßmus 40589208c77SStephan Aßmus message->FindFloat("delta", &delta); 40689208c77SStephan Aßmus message->FindString("text", &text); 40789208c77SStephan Aßmus message->FindString("trailing_text", &trailing_text); 40889208c77SStephan Aßmus 40989208c77SStephan Aßmus Update(delta, text, trailing_text); 41089208c77SStephan Aßmus 41189208c77SStephan Aßmus break; 41289208c77SStephan Aßmus } 41389208c77SStephan Aßmus 41489208c77SStephan Aßmus case B_RESET_STATUS_BAR: 41589208c77SStephan Aßmus { 41689208c77SStephan Aßmus const char *label = NULL, *trailing_label = NULL; 41789208c77SStephan Aßmus 41889208c77SStephan Aßmus message->FindString("label", &label); 41989208c77SStephan Aßmus message->FindString("trailing_label", &trailing_label); 42089208c77SStephan Aßmus 42189208c77SStephan Aßmus Reset(label, trailing_label); 42289208c77SStephan Aßmus 42389208c77SStephan Aßmus break; 42489208c77SStephan Aßmus } 42589208c77SStephan Aßmus 42689208c77SStephan Aßmus default: 42789208c77SStephan Aßmus BView::MessageReceived(message); 42889208c77SStephan Aßmus break; 42989208c77SStephan Aßmus } 43089208c77SStephan Aßmus } 43189208c77SStephan Aßmus 43289208c77SStephan Aßmus 43389208c77SStephan Aßmus void 43489208c77SStephan Aßmus BStatusBar::MouseDown(BPoint point) 43589208c77SStephan Aßmus { 43689208c77SStephan Aßmus BView::MouseDown(point); 43789208c77SStephan Aßmus } 43889208c77SStephan Aßmus 43989208c77SStephan Aßmus 44089208c77SStephan Aßmus void 44189208c77SStephan Aßmus BStatusBar::MouseUp(BPoint point) 44289208c77SStephan Aßmus { 44389208c77SStephan Aßmus BView::MouseUp(point); 44489208c77SStephan Aßmus } 44589208c77SStephan Aßmus 44689208c77SStephan Aßmus 44789208c77SStephan Aßmus void 44889208c77SStephan Aßmus BStatusBar::MouseMoved(BPoint point, uint32 transit, const BMessage *message) 44989208c77SStephan Aßmus { 45089208c77SStephan Aßmus BView::MouseMoved(point, transit, message); 45189208c77SStephan Aßmus } 45289208c77SStephan Aßmus 45389208c77SStephan Aßmus 45489208c77SStephan Aßmus // #pragma mark - 45589208c77SStephan Aßmus 45689208c77SStephan Aßmus 45789208c77SStephan Aßmus void 4583583227cSStefano Ceccherini BStatusBar::SetBarColor(rgb_color color) 45952a38012Sejakowatz { 46030d24296SMarcus Overhagen fBarColor = color; 46152a38012Sejakowatz 46252a38012Sejakowatz Invalidate(); 46352a38012Sejakowatz } 4643583227cSStefano Ceccherini 4653583227cSStefano Ceccherini 4663583227cSStefano Ceccherini void 467075e65c7SAxel Dörfler BStatusBar::SetBarHeight(float barHeight) 46852a38012Sejakowatz { 469075e65c7SAxel Dörfler float oldHeight = BarHeight(); 47052a38012Sejakowatz 47152a38012Sejakowatz fCustomBarHeight = true; 472075e65c7SAxel Dörfler fBarHeight = barHeight; 473075e65c7SAxel Dörfler 474075e65c7SAxel Dörfler if (barHeight == oldHeight) 475075e65c7SAxel Dörfler return; 476075e65c7SAxel Dörfler 477075e65c7SAxel Dörfler // resize so that the height fits 47826fe4141SStephan Aßmus if ((Flags() & B_SUPPORTS_LAYOUT) != 0) 479a487da80SStephan Aßmus InvalidateLayout(); 48026fe4141SStephan Aßmus else { 481075e65c7SAxel Dörfler float width, height; 482075e65c7SAxel Dörfler GetPreferredSize(&width, &height); 483075e65c7SAxel Dörfler ResizeTo(Bounds().Width(), height); 48452a38012Sejakowatz } 485a487da80SStephan Aßmus } 48652a38012Sejakowatz 4873583227cSStefano Ceccherini 4883583227cSStefano Ceccherini void 4893583227cSStefano Ceccherini BStatusBar::SetText(const char* string) 4903583227cSStefano Ceccherini { 491f466d35dSStephan Aßmus _SetTextData(fText, string, fLabel, false); 49252a38012Sejakowatz } 49352a38012Sejakowatz 4943583227cSStefano Ceccherini 4953583227cSStefano Ceccherini void 4963583227cSStefano Ceccherini BStatusBar::SetTrailingText(const char* string) 4973583227cSStefano Ceccherini { 498f466d35dSStephan Aßmus _SetTextData(fTrailingText, string, fTrailingLabel, true); 49952a38012Sejakowatz } 5003583227cSStefano Ceccherini 5013583227cSStefano Ceccherini 5023583227cSStefano Ceccherini void 5033583227cSStefano Ceccherini BStatusBar::SetMaxValue(float max) 50452a38012Sejakowatz { 505e51a01a5SRene Gollent // R5 and/or Zeta's SetMaxValue does not trigger an invalidate here. 506e51a01a5SRene Gollent // this is probably not ideal behavior, but it does break apps in some cases 507e51a01a5SRene Gollent // as observed with SpaceMonitor. 508e51a01a5SRene Gollent // TODO: revisit this when we break binary compatibility 50952a38012Sejakowatz fMax = max; 51052a38012Sejakowatz } 5113583227cSStefano Ceccherini 5123583227cSStefano Ceccherini 5133583227cSStefano Ceccherini void 5143583227cSStefano Ceccherini BStatusBar::Update(float delta, const char* text, const char* trailingText) 51552a38012Sejakowatz { 516ea1b25f5SStephan Aßmus // If any of these are NULL, the existing text remains (BeBook) 517ea1b25f5SStephan Aßmus if (text == NULL) 518ea1b25f5SStephan Aßmus text = fText.String(); 519ea1b25f5SStephan Aßmus if (trailingText == NULL) 520ea1b25f5SStephan Aßmus trailingText = fTrailingText.String(); 521075e65c7SAxel Dörfler BStatusBar::SetTo(fCurrent + delta, text, trailingText); 522075e65c7SAxel Dörfler } 52352a38012Sejakowatz 524f45d1cc7SMarc Flerackers 525075e65c7SAxel Dörfler void 52689208c77SStephan Aßmus BStatusBar::Reset(const char *label, const char *trailingLabel) 52789208c77SStephan Aßmus { 52889208c77SStephan Aßmus // Reset replaces the label and trailing label with copies of the 52989208c77SStephan Aßmus // strings passed as arguments. If either argument is NULL, the 53089208c77SStephan Aßmus // label or trailing label will be deleted and erased. 53189208c77SStephan Aßmus fLabel = label ? label : ""; 53289208c77SStephan Aßmus fTrailingLabel = trailingLabel ? trailingLabel : ""; 53389208c77SStephan Aßmus 53489208c77SStephan Aßmus // Reset deletes and erases any text or trailing text 53589208c77SStephan Aßmus fText = ""; 53689208c77SStephan Aßmus fTrailingText = ""; 53789208c77SStephan Aßmus 53889208c77SStephan Aßmus fCurrent = 0; 53989208c77SStephan Aßmus fMax = 100; 54089208c77SStephan Aßmus 54189208c77SStephan Aßmus Invalidate(); 54289208c77SStephan Aßmus } 54389208c77SStephan Aßmus 54489208c77SStephan Aßmus 54589208c77SStephan Aßmus void 546075e65c7SAxel Dörfler BStatusBar::SetTo(float value, const char* text, const char* trailingText) 547075e65c7SAxel Dörfler { 548a788be67SStephan Aßmus SetText(text); 549a788be67SStephan Aßmus SetTrailingText(trailingText); 55052a38012Sejakowatz 551075e65c7SAxel Dörfler if (value > fMax) 552075e65c7SAxel Dörfler value = fMax; 553f466d35dSStephan Aßmus else if (value < 0) 554f466d35dSStephan Aßmus value = 0; 555075e65c7SAxel Dörfler if (value == fCurrent) 556075e65c7SAxel Dörfler return; 55752a38012Sejakowatz 558075e65c7SAxel Dörfler BRect barFrame = _BarFrame(); 559075e65c7SAxel Dörfler float oldPosition = _BarPosition(barFrame); 560075e65c7SAxel Dörfler 561075e65c7SAxel Dörfler fCurrent = value; 562f466d35dSStephan Aßmus 563075e65c7SAxel Dörfler float newPosition = _BarPosition(barFrame); 564075e65c7SAxel Dörfler if (oldPosition == newPosition) 565075e65c7SAxel Dörfler return; 566075e65c7SAxel Dörfler 567f466d35dSStephan Aßmus // update only the part of the status bar with actual changes 568075e65c7SAxel Dörfler BRect update = barFrame; 569075e65c7SAxel Dörfler if (oldPosition < newPosition) { 570f466d35dSStephan Aßmus update.left = floorf(max_c(oldPosition - 1, update.left)); 571f466d35dSStephan Aßmus update.right = ceilf(newPosition); 572075e65c7SAxel Dörfler } else { 573f466d35dSStephan Aßmus update.left = floorf(max_c(newPosition - 1, update.left)); 574f466d35dSStephan Aßmus update.right = ceilf(oldPosition); 575075e65c7SAxel Dörfler } 576075e65c7SAxel Dörfler 5772f86ba45SStephan Aßmus // TODO: Ask the BControlLook in the first place about dirty rect. 57857c5b09eSRyan Leavengood if (be_control_look != NULL) 5792f86ba45SStephan Aßmus update.InsetBy(-1, -1); 5802f86ba45SStephan Aßmus 581075e65c7SAxel Dörfler Invalidate(update); 58252a38012Sejakowatz } 5833583227cSStefano Ceccherini 5843583227cSStefano Ceccherini 5853583227cSStefano Ceccherini float 5863583227cSStefano Ceccherini BStatusBar::CurrentValue() const 58752a38012Sejakowatz { 58852a38012Sejakowatz return fCurrent; 58952a38012Sejakowatz } 5903583227cSStefano Ceccherini 5913583227cSStefano Ceccherini 5923583227cSStefano Ceccherini float 5933583227cSStefano Ceccherini BStatusBar::MaxValue() const 59452a38012Sejakowatz { 59552a38012Sejakowatz return fMax; 59652a38012Sejakowatz } 5973583227cSStefano Ceccherini 5983583227cSStefano Ceccherini 5993583227cSStefano Ceccherini rgb_color 6003583227cSStefano Ceccherini BStatusBar::BarColor() const 60152a38012Sejakowatz { 60252a38012Sejakowatz return fBarColor; 60352a38012Sejakowatz } 6043583227cSStefano Ceccherini 6053583227cSStefano Ceccherini 6063583227cSStefano Ceccherini float 6073583227cSStefano Ceccherini BStatusBar::BarHeight() const 60852a38012Sejakowatz { 609f466d35dSStephan Aßmus if (!fCustomBarHeight && fBarHeight == -1) { 610075e65c7SAxel Dörfler // the default bar height is as height as the label 611075e65c7SAxel Dörfler font_height fontHeight; 612075e65c7SAxel Dörfler GetFontHeight(&fontHeight); 613075e65c7SAxel Dörfler const_cast<BStatusBar *>(this)->fBarHeight = fontHeight.ascent 614f466d35dSStephan Aßmus + fontHeight.descent + 5; 61552a38012Sejakowatz } 61652a38012Sejakowatz 617f466d35dSStephan Aßmus return ceilf(fBarHeight); 61852a38012Sejakowatz } 6193583227cSStefano Ceccherini 6203583227cSStefano Ceccherini 6213583227cSStefano Ceccherini const char * 6223583227cSStefano Ceccherini BStatusBar::Text() const 62352a38012Sejakowatz { 624075e65c7SAxel Dörfler return fText.String(); 62552a38012Sejakowatz } 6263583227cSStefano Ceccherini 6273583227cSStefano Ceccherini 6283583227cSStefano Ceccherini const char * 6293583227cSStefano Ceccherini BStatusBar::TrailingText() const 63052a38012Sejakowatz { 631075e65c7SAxel Dörfler return fTrailingText.String(); 63252a38012Sejakowatz } 6333583227cSStefano Ceccherini 6343583227cSStefano Ceccherini 6353583227cSStefano Ceccherini const char * 6363583227cSStefano Ceccherini BStatusBar::Label() const 63752a38012Sejakowatz { 638075e65c7SAxel Dörfler return fLabel.String(); 63952a38012Sejakowatz } 6403583227cSStefano Ceccherini 6413583227cSStefano Ceccherini 6423583227cSStefano Ceccherini const char * 6433583227cSStefano Ceccherini BStatusBar::TrailingLabel() const 64452a38012Sejakowatz { 645075e65c7SAxel Dörfler return fTrailingLabel.String(); 64652a38012Sejakowatz } 6473583227cSStefano Ceccherini 6483583227cSStefano Ceccherini 64989208c77SStephan Aßmus // #pragma mark - 6503583227cSStefano Ceccherini 6513583227cSStefano Ceccherini 6523583227cSStefano Ceccherini BHandler * 6533583227cSStefano Ceccherini BStatusBar::ResolveSpecifier(BMessage* message, int32 index, 654075e65c7SAxel Dörfler BMessage* specifier, int32 what, const char *property) 65552a38012Sejakowatz { 65652a38012Sejakowatz return BView::ResolveSpecifier(message, index, specifier, what, property); 65752a38012Sejakowatz } 6583583227cSStefano Ceccherini 6593583227cSStefano Ceccherini 6603583227cSStefano Ceccherini status_t 6613583227cSStefano Ceccherini BStatusBar::GetSupportedSuites(BMessage* data) 66252a38012Sejakowatz { 66352a38012Sejakowatz return BView::GetSupportedSuites(data); 66452a38012Sejakowatz } 6653583227cSStefano Ceccherini 6663583227cSStefano Ceccherini 6673583227cSStefano Ceccherini status_t 66839fbf550SOliver Tappe BStatusBar::Perform(perform_code code, void* _data) 66952a38012Sejakowatz { 67039fbf550SOliver Tappe switch (code) { 67139fbf550SOliver Tappe case PERFORM_CODE_MIN_SIZE: 67239fbf550SOliver Tappe ((perform_data_min_size*)_data)->return_value 67339fbf550SOliver Tappe = BStatusBar::MinSize(); 67439fbf550SOliver Tappe return B_OK; 67539fbf550SOliver Tappe case PERFORM_CODE_MAX_SIZE: 67639fbf550SOliver Tappe ((perform_data_max_size*)_data)->return_value 67739fbf550SOliver Tappe = BStatusBar::MaxSize(); 67839fbf550SOliver Tappe return B_OK; 67939fbf550SOliver Tappe case PERFORM_CODE_PREFERRED_SIZE: 68039fbf550SOliver Tappe ((perform_data_preferred_size*)_data)->return_value 68139fbf550SOliver Tappe = BStatusBar::PreferredSize(); 68239fbf550SOliver Tappe return B_OK; 68339fbf550SOliver Tappe case PERFORM_CODE_LAYOUT_ALIGNMENT: 68439fbf550SOliver Tappe ((perform_data_layout_alignment*)_data)->return_value 68539fbf550SOliver Tappe = BStatusBar::LayoutAlignment(); 68639fbf550SOliver Tappe return B_OK; 68739fbf550SOliver Tappe case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH: 68839fbf550SOliver Tappe ((perform_data_has_height_for_width*)_data)->return_value 68939fbf550SOliver Tappe = BStatusBar::HasHeightForWidth(); 69039fbf550SOliver Tappe return B_OK; 69139fbf550SOliver Tappe case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH: 69239fbf550SOliver Tappe { 69339fbf550SOliver Tappe perform_data_get_height_for_width* data 69439fbf550SOliver Tappe = (perform_data_get_height_for_width*)_data; 69539fbf550SOliver Tappe BStatusBar::GetHeightForWidth(data->width, &data->min, &data->max, 69639fbf550SOliver Tappe &data->preferred); 69739fbf550SOliver Tappe return B_OK; 69839fbf550SOliver Tappe } 69939fbf550SOliver Tappe case PERFORM_CODE_SET_LAYOUT: 70039fbf550SOliver Tappe { 70139fbf550SOliver Tappe perform_data_set_layout* data = (perform_data_set_layout*)_data; 70239fbf550SOliver Tappe BStatusBar::SetLayout(data->layout); 70339fbf550SOliver Tappe return B_OK; 70439fbf550SOliver Tappe } 705eee4243dSAlex Wilson case PERFORM_CODE_LAYOUT_INVALIDATED: 70639fbf550SOliver Tappe { 707eee4243dSAlex Wilson perform_data_layout_invalidated* data 708eee4243dSAlex Wilson = (perform_data_layout_invalidated*)_data; 709eee4243dSAlex Wilson BStatusBar::LayoutInvalidated(data->descendants); 71039fbf550SOliver Tappe return B_OK; 71139fbf550SOliver Tappe } 71239fbf550SOliver Tappe case PERFORM_CODE_DO_LAYOUT: 71339fbf550SOliver Tappe { 71439fbf550SOliver Tappe BStatusBar::DoLayout(); 71539fbf550SOliver Tappe return B_OK; 71639fbf550SOliver Tappe } 71739fbf550SOliver Tappe } 71839fbf550SOliver Tappe 71939fbf550SOliver Tappe return BView::Perform(code, _data); 72052a38012Sejakowatz } 7213583227cSStefano Ceccherini 7223583227cSStefano Ceccherini 72389208c77SStephan Aßmus // #pragma mark - 72489208c77SStephan Aßmus 72589208c77SStephan Aßmus 726b5a071bcSStephan Aßmus extern "C" void 727075e65c7SAxel Dörfler _ReservedStatusBar1__10BStatusBar(BStatusBar* self, float value, 728075e65c7SAxel Dörfler const char* text, const char* trailingText) 729075e65c7SAxel Dörfler { 730075e65c7SAxel Dörfler self->BStatusBar::SetTo(value, text, trailingText); 731075e65c7SAxel Dörfler } 732075e65c7SAxel Dörfler 733075e65c7SAxel Dörfler 73452a38012Sejakowatz void BStatusBar::_ReservedStatusBar2() {} 73552a38012Sejakowatz void BStatusBar::_ReservedStatusBar3() {} 73652a38012Sejakowatz void BStatusBar::_ReservedStatusBar4() {} 73752a38012Sejakowatz 7383583227cSStefano Ceccherini 7393583227cSStefano Ceccherini BStatusBar & 740075e65c7SAxel Dörfler BStatusBar::operator=(const BStatusBar& other) 74152a38012Sejakowatz { 74252a38012Sejakowatz return *this; 74352a38012Sejakowatz } 74452a38012Sejakowatz 7453583227cSStefano Ceccherini 74689208c77SStephan Aßmus // #pragma mark - 74789208c77SStephan Aßmus 74889208c77SStephan Aßmus 74989208c77SStephan Aßmus void 75089208c77SStephan Aßmus BStatusBar::_InitObject() 75189208c77SStephan Aßmus { 75289208c77SStephan Aßmus fMax = 100.0; 75389208c77SStephan Aßmus fCurrent = 0.0; 75489208c77SStephan Aßmus 75589208c77SStephan Aßmus fBarHeight = -1.0; 75689208c77SStephan Aßmus fTextDivider = Bounds().Width(); 75789208c77SStephan Aßmus 75889208c77SStephan Aßmus fBarColor = kDefaultBarColor; 75989208c77SStephan Aßmus fCustomBarHeight = false; 76089208c77SStephan Aßmus 76189208c77SStephan Aßmus SetFlags(Flags() | B_FRAME_EVENTS); 76289208c77SStephan Aßmus } 76389208c77SStephan Aßmus 76489208c77SStephan Aßmus 7653583227cSStefano Ceccherini void 766f466d35dSStephan Aßmus BStatusBar::_SetTextData(BString& text, const char* source, 767f466d35dSStephan Aßmus const BString& combineWith, bool rightAligned) 7683583227cSStefano Ceccherini { 769a788be67SStephan Aßmus if (source == NULL) 770a788be67SStephan Aßmus source = ""; 771a788be67SStephan Aßmus 772075e65c7SAxel Dörfler // If there were no changes, we don't have to do anything 773075e65c7SAxel Dörfler if (text == source) 774075e65c7SAxel Dörfler return; 775075e65c7SAxel Dörfler 7767ee23666SStephan Aßmus bool oldHasText = _HasText(); 777075e65c7SAxel Dörfler text = source; 778f466d35dSStephan Aßmus 779f466d35dSStephan Aßmus BString newString; 780f466d35dSStephan Aßmus if (rightAligned) 781f466d35dSStephan Aßmus newString << text << combineWith; 782f466d35dSStephan Aßmus else 783f466d35dSStephan Aßmus newString << combineWith << text; 784f466d35dSStephan Aßmus 7857ee23666SStephan Aßmus if (oldHasText != _HasText()) 7867ee23666SStephan Aßmus InvalidateLayout(); 7877ee23666SStephan Aßmus 788075e65c7SAxel Dörfler font_height fontHeight; 789075e65c7SAxel Dörfler GetFontHeight(&fontHeight); 790075e65c7SAxel Dörfler 791f466d35dSStephan Aßmus // Invalidate(BRect(position, 0, position + invalidateWidth, 792f466d35dSStephan Aßmus // ceilf(fontHeight.ascent) + ceilf(fontHeight.descent))); 793f466d35dSStephan Aßmus // TODO: redrawing the entire area takes care of the edge case 794f466d35dSStephan Aßmus // where the left side string changes because of truncation and 795f466d35dSStephan Aßmus // part of it needs to be redrawn as well. 796f466d35dSStephan Aßmus Invalidate(BRect(0, 0, Bounds().right, 797f466d35dSStephan Aßmus ceilf(fontHeight.ascent) + ceilf(fontHeight.descent))); 7983583227cSStefano Ceccherini } 7993583227cSStefano Ceccherini 8003583227cSStefano Ceccherini 801075e65c7SAxel Dörfler /*! 802075e65c7SAxel Dörfler Returns the inner bar frame without the surrounding bevel. 803075e65c7SAxel Dörfler */ 804075e65c7SAxel Dörfler BRect 805075e65c7SAxel Dörfler BStatusBar::_BarFrame(const font_height* fontHeight) const 8063583227cSStefano Ceccherini { 807a487da80SStephan Aßmus float top = 2; 808a487da80SStephan Aßmus if (_HasText()) { 809075e65c7SAxel Dörfler if (fontHeight == NULL) { 810075e65c7SAxel Dörfler font_height height; 811075e65c7SAxel Dörfler GetFontHeight(&height); 812f466d35dSStephan Aßmus top = ceilf(height.ascent + height.descent) + 6; 813075e65c7SAxel Dörfler } else 814f466d35dSStephan Aßmus top = ceilf(fontHeight->ascent + fontHeight->descent) + 6; 815a487da80SStephan Aßmus } 8163583227cSStefano Ceccherini 817f466d35dSStephan Aßmus return BRect(2, top, Bounds().right - 2, top + BarHeight() - 4); 8183583227cSStefano Ceccherini } 8193583227cSStefano Ceccherini 8203583227cSStefano Ceccherini 821075e65c7SAxel Dörfler float 822075e65c7SAxel Dörfler BStatusBar::_BarPosition(const BRect& barFrame) const 8233583227cSStefano Ceccherini { 824f466d35dSStephan Aßmus if (fCurrent == 0) 825f466d35dSStephan Aßmus return barFrame.left - 1; 826075e65c7SAxel Dörfler 8272f86ba45SStephan Aßmus return roundf(barFrame.left - 1 8282f86ba45SStephan Aßmus + (fCurrent * (barFrame.Width() + 3) / fMax)); 8293583227cSStefano Ceccherini } 8303583227cSStefano Ceccherini 831a487da80SStephan Aßmus 832a487da80SStephan Aßmus bool 833a487da80SStephan Aßmus BStatusBar::_HasText() const 834a487da80SStephan Aßmus { 8357ee23666SStephan Aßmus // Force BeOS behavior where the size of the BStatusBar always included 8367ee23666SStephan Aßmus // room for labels, even when there weren't any. 8377ee23666SStephan Aßmus if ((Flags() & B_SUPPORTS_LAYOUT) == 0) 8387ee23666SStephan Aßmus return true; 839a487da80SStephan Aßmus return fLabel.Length() > 0 || fTrailingLabel.Length() > 0 840a487da80SStephan Aßmus || fTrailingText.Length() > 0 || fText.Length() > 0; 841a487da80SStephan Aßmus } 842