1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: StatusBar.cpp 23 // Author: Marc Flerackers (mflerackers@androme.be) 24 // Description: BStatusBar displays a "percentage-of-completion" gauge. 25 //------------------------------------------------------------------------------ 26 27 // Standard Includes ----------------------------------------------------------- 28 #include <string.h> 29 #include <malloc.h> 30 31 // System Includes ------------------------------------------------------------- 32 #include <StatusBar.h> 33 #include <Message.h> 34 #include <Errors.h> 35 36 // Project Includes ------------------------------------------------------------ 37 38 // Local Includes -------------------------------------------------------------- 39 40 // Local Defines --------------------------------------------------------------- 41 42 // Globals --------------------------------------------------------------------- 43 44 //------------------------------------------------------------------------------ 45 BStatusBar::BStatusBar(BRect frame, const char *name, const char *label, 46 const char *trailingLabel) 47 : BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW), 48 fText(NULL), 49 fTrailingText(NULL), 50 fMax(100.0f), 51 fCurrent(0.0f), 52 fBarHeight(-1.0f), 53 fTrailingWidth(-1.0f), 54 fEraseText(-1.0f), 55 fEraseTrailingText(-1.0f), 56 fCustomBarHeight(false) 57 58 { 59 fLabel = strdup(label); 60 fTrailingLabel = strdup(trailingLabel); 61 62 fBarColor.red = 50; 63 fBarColor.green = 150; 64 fBarColor.blue = 255; 65 fBarColor.alpha = 255; 66 } 67 //------------------------------------------------------------------------------ 68 BStatusBar::BStatusBar(BMessage *archive) 69 : BView(archive), 70 fTrailingWidth(-1.0f), 71 fEraseText(-1.0f), 72 fEraseTrailingText(-1.0f), 73 fCustomBarHeight(false) 74 { 75 if (archive->FindFloat("_high", &fBarHeight) != B_OK) 76 fBarHeight = -1.0f; 77 78 const void *ptr; 79 80 if (archive->FindData("_bcolor", B_INT32_TYPE, &ptr, NULL ) != B_OK) 81 { 82 fBarColor.red = 50; 83 fBarColor.green = 150; 84 fBarColor.blue = 255; 85 fBarColor.alpha = 255; 86 } 87 else 88 memcpy(&fBarColor, ptr, sizeof(rgb_color)); 89 90 if (archive->FindFloat("_val", &fCurrent) != B_OK) 91 fCurrent = 0.0f; 92 93 if (archive->FindFloat("_max", &fMax) != B_OK) 94 fMax = 100.0f; 95 96 const char *string; 97 98 if (archive->FindString("_text", &string) != B_OK) 99 fText = NULL; 100 else 101 fText = strdup(string); 102 103 if (archive->FindString("_ttext", &string) != B_OK) 104 fTrailingText = NULL; 105 else 106 fTrailingText = strdup(string); 107 108 if (archive->FindString("_label", &string) != B_OK) 109 fLabel = NULL; 110 else 111 fLabel = strdup(string); 112 113 if ( archive->FindString("_tlabel", &string) != B_OK) 114 fTrailingLabel = NULL; 115 else 116 fTrailingLabel = strdup(string); 117 } 118 //------------------------------------------------------------------------------ 119 BStatusBar::~BStatusBar() 120 { 121 if (fLabel) 122 free(fLabel); 123 124 if (fTrailingLabel) 125 free(fTrailingLabel); 126 127 if (fText) 128 free(fText); 129 130 if (fTrailingText) 131 free(fTrailingText); 132 } 133 //------------------------------------------------------------------------------ 134 BArchivable *BStatusBar::Instantiate(BMessage *archive) 135 { 136 if (validate_instantiation(archive, "BStatusBar")) 137 return new BStatusBar(archive); 138 139 return NULL; 140 } 141 //------------------------------------------------------------------------------ 142 status_t BStatusBar::Archive(BMessage *archive, bool deep) const 143 { 144 status_t err = BView::Archive(archive, deep); 145 146 if (err != B_OK) 147 return err; 148 149 if (fBarHeight != 16.0f) 150 err = archive->AddFloat("_high", fBarHeight); 151 152 if (err != B_OK) 153 return err; 154 155 // TODO: Should we compare the color with (50, 150, 255) ? 156 err = archive->AddData("_bcolor", B_INT32_TYPE, &fBarColor, sizeof( int32 )); 157 158 if (err != B_OK) 159 return err; 160 161 if (fCurrent != 0.0f) 162 err = archive->AddFloat("_val", fCurrent); 163 164 if (err != B_OK) 165 return err; 166 167 if (fMax != 100.0f ) 168 err = archive->AddFloat("_max", fMax); 169 170 if (err != B_OK) 171 return err; 172 173 if (fText ) 174 err = archive->AddString("_text", fText); 175 176 if (err != B_OK) 177 return err; 178 179 if (fTrailingText) 180 err = archive->AddString("_ttext", fTrailingText); 181 182 if (err != B_OK) 183 return err; 184 185 if (fLabel) 186 err = archive->AddString("_label", fLabel); 187 188 if (err != B_OK) 189 return err; 190 191 if (fTrailingLabel) 192 err = archive->AddString ("_tlabel", fTrailingLabel); 193 194 return err; 195 } 196 //------------------------------------------------------------------------------ 197 void BStatusBar::AttachedToWindow() 198 { 199 float width, height; 200 GetPreferredSize(&width, &height); 201 ResizeTo(Frame().Width(), height); 202 203 if (Parent()) 204 SetViewColor(Parent ()->ViewColor()); 205 } 206 //------------------------------------------------------------------------------ 207 void BStatusBar::MessageReceived(BMessage *message) 208 { 209 switch(message->what) 210 { 211 case B_UPDATE_STATUS_BAR: 212 { 213 float delta; 214 const char *text = NULL, *trailing_text = NULL; 215 216 message->FindFloat("delta", &delta); 217 message->FindString("text", &text); 218 message->FindString("trailing text", &trailing_text); 219 220 Update(delta, text, trailing_text); 221 222 break; 223 } 224 case B_RESET_STATUS_BAR: 225 { 226 const char *label = NULL, *trailing_label = NULL; 227 228 message->FindString("label", &label); 229 message->FindString("trailing label", &trailing_label); 230 231 Reset(label, trailing_label); 232 233 break; 234 } 235 default: 236 BView::MessageReceived ( message ); 237 } 238 } 239 //------------------------------------------------------------------------------ 240 void BStatusBar::Draw(BRect updateRect) 241 { 242 float width = Frame().Width(); 243 font_height fh; 244 GetFontHeight(&fh); 245 246 SetHighColor(0, 0, 0); 247 MovePenTo(2.0f, (float)ceil(fh.ascent) + 1.0f); 248 249 if (fLabel) 250 DrawString(fLabel); 251 if (fText) 252 DrawString(fText); 253 254 if (fTrailingText) 255 { 256 if (fTrailingLabel) 257 { 258 MovePenTo(width - StringWidth(fTrailingText) - 259 StringWidth(fTrailingLabel) - 2.0f, 260 (float)ceil(fh.ascent) + 1.0f); 261 DrawString(fTrailingText); 262 DrawString(fTrailingLabel); 263 } 264 else 265 { 266 MovePenTo(width - StringWidth(fTrailingText) - 2.0f, 267 (float)ceil(fh.ascent) + 1.0f); 268 DrawString(fTrailingText); 269 } 270 271 } 272 else if (fTrailingLabel) 273 { 274 MovePenTo(width - StringWidth(fTrailingLabel) - 2.0f, 275 (float)ceil(fh.ascent) + 1.0f); 276 DrawString(fTrailingLabel); 277 } 278 279 BRect rect(0.0f, (float)ceil(fh.ascent) + 4.0f, width, 280 (float)ceil(fh.ascent) + 4.0f + fBarHeight); 281 282 // First bevel 283 SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT)); 284 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top)); 285 StrokeLine(BPoint(rect.right, rect.top)); 286 287 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT)); 288 StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom)); 289 StrokeLine(BPoint(rect.right, rect.top + 1.0f)); 290 291 rect.InsetBy(1.0f, 1.0f); 292 293 // Second bevel 294 SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT)); 295 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top)); 296 StrokeLine(BPoint(rect.right, rect.top)); 297 298 SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 299 StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom)); 300 StrokeLine(BPoint(rect.right, rect.top + 1.0f)); 301 302 rect.InsetBy(1.0f, 1.0f); 303 304 // Filling 305 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT)); 306 FillRect(rect); 307 308 if (fCurrent != 0.0f) 309 { 310 rect.right = rect.left + (float)ceil(fCurrent * (width - 4) / fMax), 311 312 // Bevel 313 SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT)); 314 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top)); 315 StrokeLine(BPoint(rect.right, rect.top)); 316 317 SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT)); 318 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.right, rect.bottom)); 319 StrokeLine(BPoint(rect.right, rect.top)); 320 321 rect.InsetBy(1.0f, 1.0f); 322 323 // Filling 324 SetHighColor(fBarColor); 325 FillRect(rect); 326 } 327 } 328 //------------------------------------------------------------------------------ 329 void BStatusBar::SetBarColor(rgb_color color) 330 { 331 memcpy(&fBarColor, &color, sizeof(rgb_color)); 332 333 Invalidate(); 334 } 335 //------------------------------------------------------------------------------ 336 void BStatusBar::SetBarHeight(float height) 337 { 338 BRect frame = Frame(); 339 340 fBarHeight = height; 341 fCustomBarHeight = true; 342 ResizeTo(frame.Width(), fBarHeight + 16); 343 } 344 //------------------------------------------------------------------------------ 345 void BStatusBar::SetText ( const char *string ) 346 { 347 if (fText) 348 free(fText); 349 350 fText = strdup(string); 351 352 Invalidate(); 353 } 354 //------------------------------------------------------------------------------ 355 void BStatusBar::SetTrailingText(const char *string) 356 { 357 if (fTrailingText) 358 free(fTrailingText); 359 360 fTrailingText = strdup(string); 361 362 Invalidate(); 363 } 364 //------------------------------------------------------------------------------ 365 void BStatusBar::SetMaxValue(float max) 366 { 367 fMax = max; 368 369 Invalidate(); 370 } 371 //------------------------------------------------------------------------------ 372 void BStatusBar::Update(float delta, const char *text, const char *trailingText) 373 { 374 fCurrent += delta; 375 376 if (fCurrent > fMax) 377 fCurrent = fMax; 378 379 if (fText) 380 free(fText); 381 382 fText = strdup(text); 383 384 if (fTrailingText) 385 free(fTrailingText); 386 387 fTrailingText = strdup(trailingText); 388 389 Invalidate(); 390 } 391 //------------------------------------------------------------------------------ 392 void BStatusBar::Reset(const char *label, const char *trailingLabel) 393 { 394 if (fLabel) 395 free(fLabel); 396 397 fLabel = strdup(label); 398 399 if (fTrailingLabel) 400 free(fTrailingLabel); 401 402 fTrailingLabel = strdup(trailingLabel); 403 404 fCurrent = 0.0f; 405 406 Invalidate(); 407 } 408 float BStatusBar::CurrentValue() const 409 { 410 return fCurrent; 411 } 412 //------------------------------------------------------------------------------ 413 float BStatusBar::MaxValue() const 414 { 415 return fMax; 416 } 417 //------------------------------------------------------------------------------ 418 rgb_color BStatusBar::BarColor() const 419 { 420 return fBarColor; 421 } 422 //------------------------------------------------------------------------------ 423 float BStatusBar::BarHeight() const 424 { 425 if (!fCustomBarHeight && fBarHeight == -1.0f) 426 { 427 font_height fh; 428 GetFontHeight(&fh); 429 ((BStatusBar*)this)->fBarHeight = fh.ascent + fh.descent + 6.0f; 430 } 431 432 return fBarHeight; 433 } 434 //------------------------------------------------------------------------------ 435 const char *BStatusBar::Text() const 436 { 437 return fText; 438 } 439 //------------------------------------------------------------------------------ 440 const char *BStatusBar::TrailingText() const 441 { 442 return fTrailingText; 443 } 444 //------------------------------------------------------------------------------ 445 const char *BStatusBar::Label() const 446 { 447 return fLabel; 448 } 449 //------------------------------------------------------------------------------ 450 const char *BStatusBar::TrailingLabel() const 451 { 452 return fTrailingLabel; 453 } 454 //------------------------------------------------------------------------------ 455 void BStatusBar::MouseDown(BPoint point) 456 { 457 BView::MouseDown(point); 458 } 459 //------------------------------------------------------------------------------ 460 void BStatusBar::MouseUp(BPoint point) 461 { 462 BView::MouseUp(point); 463 } 464 //------------------------------------------------------------------------------ 465 void BStatusBar::WindowActivated(bool state) 466 { 467 BView::WindowActivated(state); 468 } 469 //------------------------------------------------------------------------------ 470 void BStatusBar::MouseMoved(BPoint point, uint32 transit, 471 const BMessage *message) 472 { 473 BView::MouseMoved(point, transit, message); 474 } 475 //------------------------------------------------------------------------------ 476 void BStatusBar::DetachedFromWindow() 477 { 478 BView::DetachedFromWindow(); 479 } 480 //------------------------------------------------------------------------------ 481 void BStatusBar::FrameMoved(BPoint new_position) 482 { 483 BView::FrameMoved(new_position); 484 } 485 //------------------------------------------------------------------------------ 486 void BStatusBar::FrameResized(float new_width, float new_height) 487 { 488 BView::FrameResized(new_width, new_height); 489 } 490 //------------------------------------------------------------------------------ 491 BHandler *BStatusBar::ResolveSpecifier(BMessage *message, int32 index, 492 BMessage *specifier, 493 int32 what, const char *property) 494 { 495 return BView::ResolveSpecifier(message, index, specifier, what, property); 496 } 497 //------------------------------------------------------------------------------ 498 void BStatusBar::ResizeToPreferred() 499 { 500 BView::ResizeToPreferred(); 501 } 502 //------------------------------------------------------------------------------ 503 void BStatusBar::GetPreferredSize(float *width, float *height) 504 { 505 font_height fh; 506 GetFontHeight(&fh); 507 508 *width = (fLabel ? (float)ceil(StringWidth(fLabel)) : 0.0f) + 509 (fTrailingLabel ? (float)ceil(StringWidth(fTrailingLabel)) : 0.0f) + 510 7.0f; 511 *height = fh.ascent + fh.descent + 5.0f + BarHeight(); 512 } 513 //------------------------------------------------------------------------------ 514 void BStatusBar::MakeFocus(bool state) 515 { 516 BView::MakeFocus(state); 517 } 518 //------------------------------------------------------------------------------ 519 void BStatusBar::AllAttached() 520 { 521 BView::AllAttached(); 522 } 523 //------------------------------------------------------------------------------ 524 void BStatusBar::AllDetached() 525 { 526 BView::AllDetached(); 527 } 528 //------------------------------------------------------------------------------ 529 status_t BStatusBar::GetSupportedSuites(BMessage *data) 530 { 531 return BView::GetSupportedSuites(data); 532 } 533 //------------------------------------------------------------------------------ 534 status_t BStatusBar::Perform(perform_code d, void *arg) 535 { 536 return B_ERROR; 537 } 538 //------------------------------------------------------------------------------ 539 void BStatusBar::_ReservedStatusBar1() {} 540 void BStatusBar::_ReservedStatusBar2() {} 541 void BStatusBar::_ReservedStatusBar3() {} 542 void BStatusBar::_ReservedStatusBar4() {} 543 544 //------------------------------------------------------------------------------ 545 BStatusBar &BStatusBar::operator=(const BStatusBar &) 546 { 547 return *this; 548 } 549 //------------------------------------------------------------------------------ 550 void BStatusBar::InitObject(const char *l, const char *aux_l) 551 { 552 // TODO: 553 } 554 //------------------------------------------------------------------------------ 555 void BStatusBar::SetTextData(char **pp, const char *str) 556 { 557 // TODO: 558 } 559 //------------------------------------------------------------------------------ 560 void BStatusBar::FillBar(BRect r) 561 { 562 // TODO: 563 } 564 //------------------------------------------------------------------------------ 565 void BStatusBar::Resize() 566 { 567 // TODO: 568 } 569 //------------------------------------------------------------------------------ 570 void BStatusBar::_Draw(BRect updateRect, bool bar_only) 571 { 572 // TODO: 573 } 574 //------------------------------------------------------------------------------ 575 576 /* 577 * $Log $ 578 * 579 * $Id $ 580 * 581 */ 582