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 <stdlib.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 // DW: I'm pretty sure we don't need to 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 { 205 SetViewColor(Parent()->ViewColor()); 206 SetLowColor(Parent()->ViewColor()); 207 } 208 } 209 //------------------------------------------------------------------------------ 210 void BStatusBar::MessageReceived(BMessage *message) 211 { 212 switch(message->what) 213 { 214 case B_UPDATE_STATUS_BAR: 215 { 216 float delta; 217 const char *text = NULL, *trailing_text = NULL; 218 219 message->FindFloat("delta", &delta); 220 message->FindString("text", &text); 221 message->FindString("trailing text", &trailing_text); 222 223 Update(delta, text, trailing_text); 224 225 break; 226 } 227 case B_RESET_STATUS_BAR: 228 { 229 const char *label = NULL, *trailing_label = NULL; 230 231 message->FindString("label", &label); 232 message->FindString("trailing label", &trailing_label); 233 234 Reset(label, trailing_label); 235 236 break; 237 } 238 default: 239 BView::MessageReceived ( message ); 240 } 241 } 242 //------------------------------------------------------------------------------ 243 void BStatusBar::Draw(BRect updateRect) 244 { 245 float width = Frame().Width(); 246 font_height fh; 247 GetFontHeight(&fh); 248 249 SetHighColor(0, 0, 0); 250 MovePenTo(2.0f, (float)ceil(fh.ascent) + 1.0f); 251 252 if (fLabel) 253 DrawString(fLabel); 254 if (fText) 255 DrawString(fText); 256 257 if (fTrailingText) 258 { 259 if (fTrailingLabel) 260 { 261 MovePenTo(width - StringWidth(fTrailingText) - 262 StringWidth(fTrailingLabel) - 2.0f, 263 (float)ceil(fh.ascent) + 1.0f); 264 DrawString(fTrailingText); 265 DrawString(fTrailingLabel); 266 } 267 else 268 { 269 MovePenTo(width - StringWidth(fTrailingText) - 2.0f, 270 (float)ceil(fh.ascent) + 1.0f); 271 DrawString(fTrailingText); 272 } 273 274 } 275 else if (fTrailingLabel) 276 { 277 MovePenTo(width - StringWidth(fTrailingLabel) - 2.0f, 278 (float)ceil(fh.ascent) + 1.0f); 279 DrawString(fTrailingLabel); 280 } 281 282 BRect rect(0.0f, (float)ceil(fh.ascent) + 4.0f, width, 283 (float)ceil(fh.ascent) + 4.0f + fBarHeight); 284 285 // First bevel 286 SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT)); 287 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top)); 288 StrokeLine(BPoint(rect.right, rect.top)); 289 290 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT)); 291 StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom)); 292 StrokeLine(BPoint(rect.right, rect.top + 1.0f)); 293 294 rect.InsetBy(1.0f, 1.0f); 295 296 // Second bevel 297 SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT)); 298 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top)); 299 StrokeLine(BPoint(rect.right, rect.top)); 300 301 SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 302 StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom)); 303 StrokeLine(BPoint(rect.right, rect.top + 1.0f)); 304 305 rect.InsetBy(1.0f, 1.0f); 306 307 // Filling 308 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT)); 309 FillRect(rect); 310 311 if (fCurrent != 0.0f) 312 { 313 rect.right = rect.left + (float)ceil(fCurrent * (width - 4) / fMax), 314 315 // Bevel 316 SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT)); 317 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top)); 318 StrokeLine(BPoint(rect.right, rect.top)); 319 320 SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT)); 321 StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.right, rect.bottom)); 322 StrokeLine(BPoint(rect.right, rect.top)); 323 324 rect.InsetBy(1.0f, 1.0f); 325 326 // Filling 327 SetHighColor(fBarColor); 328 FillRect(rect); 329 } 330 } 331 //------------------------------------------------------------------------------ 332 void BStatusBar::SetBarColor(rgb_color color) 333 { 334 memcpy(&fBarColor, &color, sizeof(rgb_color)); 335 336 Invalidate(); 337 } 338 //------------------------------------------------------------------------------ 339 void BStatusBar::SetBarHeight(float height) 340 { 341 BRect frame = Frame(); 342 343 fBarHeight = height; 344 fCustomBarHeight = true; 345 ResizeTo(frame.Width(), fBarHeight + 16); 346 } 347 //------------------------------------------------------------------------------ 348 void BStatusBar::SetText (const char *string) 349 { 350 // SetText frees the previous text and replaces it with a copy of the 351 // string that's passed. The string can be NULL. 352 if (fText) 353 free(fText); 354 355 fText = string ? strdup(string) : NULL; 356 357 Invalidate(); 358 } 359 //------------------------------------------------------------------------------ 360 void BStatusBar::SetTrailingText(const char *string) 361 { 362 // SetTrailingText frees the previous text and replaces it with a copy of the 363 // string that's passed. The string can be NULL. 364 if (fTrailingText) 365 free(fTrailingText); 366 367 fTrailingText = string ? strdup(string) : NULL; 368 369 Invalidate(); 370 } 371 //------------------------------------------------------------------------------ 372 void BStatusBar::SetMaxValue(float max) 373 { 374 fMax = max; 375 376 Invalidate(); 377 } 378 //------------------------------------------------------------------------------ 379 void BStatusBar::Update(float delta, const char *text, const char *trailingText) 380 { 381 fCurrent += delta; 382 383 if (fCurrent > fMax) 384 fCurrent = fMax; 385 386 // Passing NULL for the text or trailingText argument retains the previous 387 // text or trailing text string. 388 if (text) 389 { 390 if (fText) 391 free(fText); 392 393 fText = strdup(text); 394 } 395 396 if (trailingText) 397 { 398 if (fTrailingText) 399 free(fTrailingText); 400 401 fTrailingText = strdup(trailingText); 402 } 403 404 Invalidate(); 405 } 406 //------------------------------------------------------------------------------ 407 void BStatusBar::Reset(const char *label, const char *trailingLabel) 408 { 409 // Reset replaces the label and trailing label with copies of the 410 // strings passed as arguments. If either argument is NULL, the 411 // label or trailing label will be deleted and erased. 412 if (fLabel) 413 free(fLabel); 414 415 fLabel = label ? strdup(label) : NULL; 416 417 if (fTrailingLabel) 418 free(fTrailingLabel); 419 420 fTrailingLabel = trailingLabel ? strdup(trailingLabel) : NULL; 421 422 // Reset deletes and erases any text or trailing text 423 if (fText) 424 { 425 free(fText); 426 fText = NULL; 427 } 428 429 if (fTrailingText) 430 { 431 free(fTrailingText); 432 fTrailingText = NULL; 433 } 434 435 fCurrent = 0.0f; 436 fMax = 100.0f; 437 438 Invalidate(); 439 } 440 //------------------------------------------------------------------------------ 441 float BStatusBar::CurrentValue() const 442 { 443 return fCurrent; 444 } 445 //------------------------------------------------------------------------------ 446 float BStatusBar::MaxValue() const 447 { 448 return fMax; 449 } 450 //------------------------------------------------------------------------------ 451 rgb_color BStatusBar::BarColor() const 452 { 453 return fBarColor; 454 } 455 //------------------------------------------------------------------------------ 456 float BStatusBar::BarHeight() const 457 { 458 if (!fCustomBarHeight && fBarHeight == -1.0f) 459 { 460 font_height fh; 461 GetFontHeight(&fh); 462 ((BStatusBar*)this)->fBarHeight = fh.ascent + fh.descent + 6.0f; 463 } 464 465 return fBarHeight; 466 } 467 //------------------------------------------------------------------------------ 468 const char *BStatusBar::Text() const 469 { 470 return fText; 471 } 472 //------------------------------------------------------------------------------ 473 const char *BStatusBar::TrailingText() const 474 { 475 return fTrailingText; 476 } 477 //------------------------------------------------------------------------------ 478 const char *BStatusBar::Label() const 479 { 480 return fLabel; 481 } 482 //------------------------------------------------------------------------------ 483 const char *BStatusBar::TrailingLabel() const 484 { 485 return fTrailingLabel; 486 } 487 //------------------------------------------------------------------------------ 488 void BStatusBar::MouseDown(BPoint point) 489 { 490 BView::MouseDown(point); 491 } 492 //------------------------------------------------------------------------------ 493 void BStatusBar::MouseUp(BPoint point) 494 { 495 BView::MouseUp(point); 496 } 497 //------------------------------------------------------------------------------ 498 void BStatusBar::WindowActivated(bool state) 499 { 500 BView::WindowActivated(state); 501 } 502 //------------------------------------------------------------------------------ 503 void BStatusBar::MouseMoved(BPoint point, uint32 transit, 504 const BMessage *message) 505 { 506 BView::MouseMoved(point, transit, message); 507 } 508 //------------------------------------------------------------------------------ 509 void BStatusBar::DetachedFromWindow() 510 { 511 BView::DetachedFromWindow(); 512 } 513 //------------------------------------------------------------------------------ 514 void BStatusBar::FrameMoved(BPoint new_position) 515 { 516 BView::FrameMoved(new_position); 517 } 518 //------------------------------------------------------------------------------ 519 void BStatusBar::FrameResized(float new_width, float new_height) 520 { 521 BView::FrameResized(new_width, new_height); 522 } 523 //------------------------------------------------------------------------------ 524 BHandler *BStatusBar::ResolveSpecifier(BMessage *message, int32 index, 525 BMessage *specifier, 526 int32 what, const char *property) 527 { 528 return BView::ResolveSpecifier(message, index, specifier, what, property); 529 } 530 //------------------------------------------------------------------------------ 531 void BStatusBar::ResizeToPreferred() 532 { 533 BView::ResizeToPreferred(); 534 } 535 //------------------------------------------------------------------------------ 536 void BStatusBar::GetPreferredSize(float *width, float *height) 537 { 538 font_height fh; 539 GetFontHeight(&fh); 540 541 *width = (fLabel ? (float)ceil(StringWidth(fLabel)) : 0.0f) + 542 (fTrailingLabel ? (float)ceil(StringWidth(fTrailingLabel)) : 0.0f) + 543 7.0f; 544 *height = fh.ascent + fh.descent + 5.0f + BarHeight(); 545 } 546 //------------------------------------------------------------------------------ 547 void BStatusBar::MakeFocus(bool state) 548 { 549 BView::MakeFocus(state); 550 } 551 //------------------------------------------------------------------------------ 552 void BStatusBar::AllAttached() 553 { 554 BView::AllAttached(); 555 } 556 //------------------------------------------------------------------------------ 557 void BStatusBar::AllDetached() 558 { 559 BView::AllDetached(); 560 } 561 //------------------------------------------------------------------------------ 562 status_t BStatusBar::GetSupportedSuites(BMessage *data) 563 { 564 return BView::GetSupportedSuites(data); 565 } 566 //------------------------------------------------------------------------------ 567 status_t BStatusBar::Perform(perform_code d, void *arg) 568 { 569 return B_ERROR; 570 } 571 //------------------------------------------------------------------------------ 572 void BStatusBar::_ReservedStatusBar1() {} 573 void BStatusBar::_ReservedStatusBar2() {} 574 void BStatusBar::_ReservedStatusBar3() {} 575 void BStatusBar::_ReservedStatusBar4() {} 576 577 //------------------------------------------------------------------------------ 578 BStatusBar &BStatusBar::operator=(const BStatusBar &) 579 { 580 return *this; 581 } 582 //------------------------------------------------------------------------------ 583 void BStatusBar::InitObject(const char *l, const char *aux_l) 584 { 585 // TODO: 586 } 587 //------------------------------------------------------------------------------ 588 void BStatusBar::SetTextData(char **pp, const char *str) 589 { 590 // TODO: 591 } 592 //------------------------------------------------------------------------------ 593 void BStatusBar::FillBar(BRect r) 594 { 595 // TODO: 596 } 597 //------------------------------------------------------------------------------ 598 void BStatusBar::Resize() 599 { 600 // TODO: 601 } 602 //------------------------------------------------------------------------------ 603 void BStatusBar::_Draw(BRect updateRect, bool bar_only) 604 { 605 // TODO: 606 } 607 //------------------------------------------------------------------------------ 608 609 /* 610 * $Log $ 611 * 612 * $Id $ 613 * 614 */ 615