1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2005, Haiku 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: TabView.cpp 23 // Author: Marc Flerackers (mflerackers@androme.be) 24 // Description: BTab creates individual "tabs" that can be assigned 25 // to specific views. 26 // BTabView provides the framework for containing and 27 // managing groups of BTab objects. 28 //------------------------------------------------------------------------------ 29 30 #include <TabView.h> 31 #include <Message.h> 32 #include <List.h> 33 #include <Rect.h> 34 //#include <Errors.h> 35 36 37 BTab::BTab(BView *tabView) 38 : 39 fEnabled(true), 40 fSelected(false), 41 fFocus(false), 42 fView(tabView) 43 { 44 } 45 46 47 BTab::BTab(BMessage *archive) 48 : 49 fSelected(false), 50 fFocus(false), 51 fView(NULL) 52 { 53 bool disable; 54 55 if (archive->FindBool("_disable", &disable) != B_OK) 56 SetEnabled(true); 57 else 58 SetEnabled(!disable); 59 } 60 61 62 BTab::~BTab() 63 { 64 if (!fView) 65 return; 66 67 if (fSelected) 68 fView->RemoveSelf(); 69 70 delete fView; 71 } 72 73 74 BArchivable * 75 BTab::Instantiate(BMessage *archive) 76 { 77 if (validate_instantiation(archive, "BTab")) 78 return new BTab(archive); 79 80 return NULL; 81 } 82 83 84 status_t 85 BTab::Archive(BMessage *archive, bool deep) const 86 { 87 status_t err = BArchivable::Archive(archive, deep); 88 if (err != B_OK) 89 return err; 90 91 if (!fEnabled) 92 err = archive->AddBool("_disable", false); 93 94 return err; 95 } 96 97 98 status_t 99 BTab::Perform(uint32 d, void *arg) 100 { 101 return BArchivable::Perform(d, arg); 102 } 103 104 105 const char * 106 BTab::Label() const 107 { 108 if (fView) 109 return fView->Name(); 110 else 111 return NULL; 112 } 113 114 115 void 116 BTab::SetLabel(const char *label) 117 { 118 if (!label || !fView) 119 return; 120 121 fView->SetName(label); 122 } 123 124 125 bool 126 BTab::IsSelected() const 127 { 128 return fSelected; 129 } 130 131 132 void 133 BTab::Select(BView *owner) 134 { 135 if (!owner || !View() || !owner->Window()) 136 return; 137 138 owner->AddChild(fView); 139 //fView->Show(); 140 141 fSelected = true; 142 } 143 144 145 void 146 BTab::Deselect() 147 { 148 if (View()) 149 View()->RemoveSelf(); 150 151 fSelected = false; 152 } 153 154 155 void 156 BTab::SetEnabled(bool enabled) 157 { 158 fEnabled = enabled; 159 } 160 161 162 bool 163 BTab::IsEnabled() const 164 { 165 return fEnabled; 166 } 167 168 169 void 170 BTab::MakeFocus(bool inFocus) 171 { 172 fFocus = inFocus; 173 } 174 175 176 bool 177 BTab::IsFocus() const 178 { 179 return fFocus; 180 } 181 182 183 void 184 BTab::SetView(BView *view) 185 { 186 if (!view || fView == view) 187 return; 188 189 if (fView != NULL) { 190 fView->RemoveSelf(); 191 delete fView; 192 } 193 fView = view; 194 } 195 196 197 BView * 198 BTab::View() const 199 { 200 return fView; 201 } 202 203 204 void 205 BTab::DrawFocusMark(BView *owner, BRect frame) 206 { 207 float width = owner->StringWidth(Label()); 208 209 owner->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 210 // TODO: remove offset 211 float offset = frame.Height() / 2.0; 212 owner->StrokeLine(BPoint((frame.left + frame.right - width + offset) / 2.0, frame.bottom - 3), 213 BPoint((frame.left + frame.right + width + offset) / 2.0, frame.bottom - 3)); 214 } 215 216 217 void 218 BTab::DrawLabel(BView *owner, BRect frame) 219 { 220 const char *label = Label(); 221 if (label == NULL) 222 return; 223 224 owner->SetHighColor(ui_color(B_CONTROL_TEXT_COLOR)); 225 float width = owner->StringWidth(label); 226 // TODO: remove offset 227 float offset = frame.Height() / 2.0; 228 owner->DrawString(label, BPoint((frame.left + frame.right - width + offset) / 2.0, 229 frame.bottom - 4.0f - 2.0f)); 230 } 231 232 233 void 234 BTab::DrawTab(BView *owner, BRect frame, tab_position position, bool full) 235 { 236 rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); 237 rgb_color lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT); 238 rgb_color darken2 = tint_color(no_tint, B_DARKEN_2_TINT); 239 rgb_color darken3 = tint_color(no_tint, B_DARKEN_3_TINT); 240 rgb_color darken4 = tint_color(no_tint, B_DARKEN_4_TINT); 241 rgb_color darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); 242 243 owner->SetHighColor(darkenmax); 244 owner->SetLowColor(no_tint); 245 DrawLabel(owner, frame); 246 247 owner->SetDrawingMode(B_OP_OVER); 248 249 owner->BeginLineArray(12); 250 251 int32 slopeWidth = (int32)ceilf(frame.Height() / 2.0); 252 253 if (position != B_TAB_ANY) { 254 // full height left side 255 owner->AddLine(BPoint(frame.left, frame.bottom), 256 BPoint(frame.left + slopeWidth, frame.top), darken3); 257 owner->AddLine(BPoint(frame.left, frame.bottom + 1), 258 BPoint(frame.left + slopeWidth, frame.top + 1), lightenmax); 259 } else { 260 // upper half of left side 261 owner->AddLine(BPoint(frame.left + slopeWidth / 2, frame.bottom - slopeWidth), 262 BPoint(frame.left + slopeWidth, frame.top), darken3); 263 owner->AddLine(BPoint(frame.left + slopeWidth / 2 + 2, frame.bottom - slopeWidth - 1), 264 BPoint(frame.left + slopeWidth, frame.top + 1), lightenmax); 265 } 266 267 // lines along the top 268 owner->AddLine(BPoint(frame.left + slopeWidth, frame.top), 269 BPoint(frame.right, frame.top), darken3); 270 owner->AddLine(BPoint(frame.left + slopeWidth, frame.top + 1), 271 BPoint(frame.right, frame.top + 1), lightenmax); 272 273 if (full) { 274 // full height right side 275 owner->AddLine(BPoint(frame.right, frame.top), 276 BPoint(frame.right + slopeWidth + 2, frame.bottom), darken2); 277 owner->AddLine(BPoint(frame.right, frame.top + 1), 278 BPoint(frame.right + slopeWidth + 1, frame.bottom), darken4); 279 } else { 280 // upper half of right side 281 owner->AddLine(BPoint(frame.right, frame.top), 282 BPoint(frame.right + slopeWidth / 2 + 1, 283 frame.bottom - slopeWidth), darken2); 284 owner->AddLine(BPoint(frame.right, frame.top + 1), 285 BPoint(frame.right + slopeWidth / 2, 286 frame.bottom - slopeWidth), darken4); 287 } 288 289 owner->EndLineArray(); 290 } 291 292 293 void BTab::_ReservedTab1() {} 294 void BTab::_ReservedTab2() {} 295 void BTab::_ReservedTab3() {} 296 void BTab::_ReservedTab4() {} 297 void BTab::_ReservedTab5() {} 298 void BTab::_ReservedTab6() {} 299 void BTab::_ReservedTab7() {} 300 void BTab::_ReservedTab8() {} 301 void BTab::_ReservedTab9() {} 302 void BTab::_ReservedTab10() {} 303 void BTab::_ReservedTab11() {} 304 void BTab::_ReservedTab12() {} 305 306 BTab &BTab::operator=(const BTab &) 307 { 308 // this is private and not functional, but exported 309 return *this; 310 } 311 312 313 // #pragma mark - 314 315 316 BTabView::BTabView(BRect frame, const char *name, button_width width, 317 uint32 resizingMode, uint32 flags) 318 : BView(frame, name, resizingMode, flags) 319 { 320 SetFont(be_bold_font); 321 322 _InitObject(); 323 324 fTabWidthSetting = width; 325 } 326 327 328 BTabView::~BTabView() 329 { 330 for (int32 i = 0; i < CountTabs(); i++) { 331 delete TabAt(i); 332 } 333 334 delete fTabList; 335 } 336 337 338 BTabView::BTabView(BMessage *archive) 339 : BView(archive), 340 fFocus(-1) 341 { 342 fContainerView = NULL; 343 fTabList = new BList; 344 345 int16 width; 346 347 if (archive->FindInt16("_but_width", &width) == B_OK) 348 fTabWidthSetting = (button_width)width; 349 else 350 fTabWidthSetting = B_WIDTH_AS_USUAL; 351 352 if (archive->FindFloat("_high", &fTabHeight) != B_OK) { 353 font_height fh; 354 GetFontHeight(&fh); 355 fTabHeight = fh.ascent + fh.descent + fh.leading + 8.0f; 356 } 357 358 fFocus = -1; 359 360 if (archive->FindInt32("_sel", &fSelection) != B_OK) 361 fSelection = 0; 362 363 if (fContainerView == NULL) 364 fContainerView = ChildAt(0); 365 366 int32 i = 0; 367 BMessage tabMsg; 368 369 while (archive->FindMessage("_l_items", i, &tabMsg) == B_OK) { 370 BArchivable *archivedTab = instantiate_object(&tabMsg); 371 372 if (archivedTab) { 373 BTab *tab = dynamic_cast<BTab *>(archivedTab); 374 375 BMessage viewMsg; 376 if (archive->FindMessage("_view_list", i, &viewMsg) == B_OK) { 377 BArchivable *archivedView = instantiate_object(&viewMsg); 378 if (archivedView) 379 AddTab(dynamic_cast<BView*>(archivedView), tab); 380 } 381 } 382 383 tabMsg.MakeEmpty(); 384 i++; 385 } 386 } 387 388 389 BArchivable * 390 BTabView::Instantiate(BMessage *archive) 391 { 392 if ( validate_instantiation(archive, "BTabView")) 393 return new BTabView(archive); 394 395 return NULL; 396 } 397 398 399 status_t 400 BTabView::Archive(BMessage *archive, bool deep) const 401 { 402 if (CountTabs() > 0) 403 TabAt(Selection())->View()->RemoveSelf(); 404 405 status_t ret = BView::Archive(archive, deep); 406 407 if (ret == B_OK) 408 ret = archive->AddInt16("_but_width", fTabWidthSetting); 409 if (ret == B_OK) 410 ret = archive->AddFloat("_high", fTabHeight); 411 if (ret == B_OK) 412 ret = archive->AddInt32("_sel", fSelection); 413 414 if (ret == B_OK && deep) { 415 for (int32 i = 0; i < CountTabs(); i++) { 416 BMessage tabArchive; 417 BTab *tab = TabAt(i); 418 419 if (!tab) 420 continue; 421 ret = tab->Archive(&tabArchive, true); 422 if (ret == B_OK) 423 ret = archive->AddMessage("_l_items", &tabArchive); 424 425 if (!tab->View()) 426 continue; 427 428 BMessage viewArchive; 429 ret = tab->View()->Archive(&viewArchive, true); 430 if (ret == B_OK) 431 ret = archive->AddMessage("_view_list", &viewArchive); 432 } 433 } 434 435 if (CountTabs() > 0) { 436 if (TabAt(Selection())->View() && ContainerView()) 437 TabAt(Selection())->Select(ContainerView()); 438 } 439 440 return ret; 441 } 442 443 444 status_t 445 BTabView::Perform(perform_code d, void *arg) 446 { 447 return BView::Perform(d, arg); 448 } 449 450 451 void 452 BTabView::WindowActivated(bool active) 453 { 454 BView::WindowActivated(active); 455 456 if (IsFocus()) 457 Invalidate(); 458 } 459 460 461 void 462 BTabView::AttachedToWindow() 463 { 464 BView::AttachedToWindow(); 465 466 Select(fSelection); 467 } 468 469 470 void 471 BTabView::AllAttached() 472 { 473 BView::AllAttached(); 474 } 475 476 477 void 478 BTabView::AllDetached() 479 { 480 BView::AllDetached(); 481 } 482 483 484 void 485 BTabView::DetachedFromWindow() 486 { 487 BView::DetachedFromWindow(); 488 } 489 490 491 void 492 BTabView::MessageReceived(BMessage *message) 493 { 494 BView::MessageReceived(message); 495 } 496 497 498 void 499 BTabView::FrameMoved(BPoint newLocation) 500 { 501 BView::FrameMoved(newLocation); 502 } 503 504 505 void 506 BTabView::FrameResized(float width,float height) 507 { 508 BView::FrameResized(width, height); 509 } 510 511 512 void 513 BTabView::KeyDown(const char *bytes, int32 numBytes) 514 { 515 if (IsHidden()) 516 return; 517 518 switch (bytes[0]) { 519 case B_DOWN_ARROW: 520 case B_LEFT_ARROW: { 521 int32 focus = fFocus - 1; 522 if (focus < 0) 523 focus = CountTabs() - 1; 524 SetFocusTab(focus, true); 525 break; 526 } 527 528 case B_UP_ARROW: 529 case B_RIGHT_ARROW: { 530 int32 focus = fFocus + 1; 531 if (focus >= CountTabs()) 532 focus = 0; 533 SetFocusTab(focus, true); 534 break; 535 } 536 537 case B_RETURN: 538 case B_SPACE: 539 Select(FocusTab()); 540 break; 541 542 default: 543 BView::KeyDown(bytes, numBytes); 544 } 545 } 546 547 548 void 549 BTabView::MouseDown(BPoint point) 550 { 551 if (point.y > fTabHeight) 552 return; 553 554 for (int32 i = 0; i < CountTabs(); i++) { 555 if (TabFrame(i).Contains(point) 556 && i != Selection()) { 557 Select(i); 558 return; 559 } 560 } 561 562 BView::MouseDown(point); 563 } 564 565 566 void 567 BTabView::MouseUp(BPoint point) 568 { 569 BView::MouseUp(point); 570 } 571 572 573 void 574 BTabView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) 575 { 576 BView::MouseMoved(point, transit, message); 577 } 578 579 580 void 581 BTabView::Pulse() 582 { 583 BView::Pulse(); 584 } 585 586 587 void 588 BTabView::Select(int32 index) 589 { 590 if (index < 0 || index >= CountTabs()) 591 index = Selection(); 592 593 BTab *tab = TabAt(Selection()); 594 if (tab) 595 tab->Deselect(); 596 597 tab = TabAt(index); 598 if (tab && ContainerView()) { 599 tab->Select(ContainerView()); 600 fSelection = index; 601 } 602 603 Invalidate(); 604 } 605 606 607 int32 608 BTabView::Selection() const 609 { 610 return fSelection; 611 } 612 613 614 void 615 BTabView::MakeFocus(bool focused) 616 { 617 BView::MakeFocus(focused); 618 619 SetFocusTab(Selection(), focused); 620 } 621 622 623 void 624 BTabView::SetFocusTab(int32 tab, bool focused) 625 { 626 if (tab >= CountTabs()) 627 return; 628 629 if (focused) { 630 if (tab == fFocus) 631 return; 632 633 if (fFocus != -1){ 634 TabAt(fFocus)->MakeFocus(false); 635 Invalidate(TabFrame(fFocus)); 636 } 637 if (tab != -1) { 638 TabAt(tab)->MakeFocus(true); 639 Invalidate(TabFrame(tab)); 640 } 641 642 fFocus = tab; 643 } else if (fFocus != -1) { 644 TabAt(fFocus)->MakeFocus(false); 645 Invalidate(TabFrame(fFocus)); 646 // fFocus = -1; 647 } 648 } 649 650 651 int32 652 BTabView::FocusTab() const 653 { 654 return fFocus; 655 } 656 657 658 void 659 BTabView::Draw(BRect updateRect) 660 { 661 DrawBox(DrawTabs()); 662 663 if (IsFocus() && fFocus != -1) 664 TabAt(fFocus)->DrawFocusMark(this, TabFrame(fFocus)); 665 } 666 667 668 BRect 669 BTabView::DrawTabs() 670 { 671 for (int32 i = 0; i < CountTabs(); i++) { 672 TabAt(i)->DrawTab(this, TabFrame(i), 673 i == fSelection ? B_TAB_FRONT : (i == 0) ? B_TAB_FIRST : B_TAB_ANY, 674 i + 1 != fSelection); 675 } 676 677 if (fSelection < CountTabs()) 678 return TabFrame(fSelection); 679 680 return BRect(); 681 } 682 683 684 void 685 BTabView::DrawBox(BRect selTabRect) 686 { 687 BRect rect = Bounds(); 688 BRect lastTabRect = TabFrame(CountTabs() - 1); 689 690 rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); 691 rgb_color lightenMax = tint_color(noTint, B_LIGHTEN_MAX_TINT); 692 rgb_color darken1 = tint_color(noTint, B_DARKEN_1_TINT); 693 rgb_color darken2 = tint_color(noTint, B_DARKEN_2_TINT); 694 rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT); 695 696 BeginLineArray(12); 697 698 int32 offset = (int32)ceilf(selTabRect.Height() / 2.0); 699 700 // outer lines 701 AddLine(BPoint(rect.left, rect.bottom - 1), 702 BPoint(rect.left, selTabRect.bottom), darken2); 703 if (selTabRect.left >= rect.left + 1) 704 AddLine(BPoint(rect.left + 1, selTabRect.bottom), 705 BPoint(selTabRect.left, selTabRect.bottom), darken2); 706 if (lastTabRect.right + offset + 1 <= rect.right - 1) 707 AddLine(BPoint(lastTabRect.right + offset + 1, selTabRect.bottom), 708 BPoint(rect.right - 1, selTabRect.bottom), darken2); 709 AddLine(BPoint(rect.right, selTabRect.bottom + 2), 710 BPoint(rect.right, rect.bottom), darken2); 711 AddLine(BPoint(rect.right - 1, rect.bottom), 712 BPoint(rect.left + 2, rect.bottom), darken2); 713 714 // inner lines 715 rect.InsetBy(1, 1); 716 selTabRect.bottom += 1; 717 718 AddLine(BPoint(rect.left, rect.bottom - 2), 719 BPoint(rect.left, selTabRect.bottom), lightenMax); 720 if (selTabRect.left >= rect.left + 1) 721 AddLine(BPoint(rect.left + 1, selTabRect.bottom), 722 BPoint(selTabRect.left, selTabRect.bottom), lightenMax); 723 if (selTabRect.right + offset + 1 <= rect.right - 2) 724 AddLine(BPoint(selTabRect.right + offset + 1, selTabRect.bottom), 725 BPoint(rect.right - 2, selTabRect.bottom), lightenMax); 726 AddLine(BPoint(rect.right, selTabRect.bottom), 727 BPoint(rect.right, rect.bottom), darken4); 728 AddLine(BPoint(rect.right - 1, rect.bottom), 729 BPoint(rect.left, rect.bottom), darken4); 730 731 // soft inner bevel at right/bottom 732 rect.right--; 733 rect.bottom--; 734 735 AddLine(BPoint(rect.right, selTabRect.bottom + 1), 736 BPoint(rect.right, rect.bottom), darken1); 737 AddLine(BPoint(rect.right - 1, rect.bottom), 738 BPoint(rect.left + 1, rect.bottom), darken1); 739 740 EndLineArray(); 741 } 742 743 #define X_OFFSET 0.0f 744 745 BRect 746 BTabView::TabFrame(int32 tab_index) const 747 { 748 // TODO: fix to remove "offset" in DrawTab and DrawLabel ... 749 switch (fTabWidthSetting) { 750 case B_WIDTH_FROM_LABEL: 751 { 752 float x = X_OFFSET; 753 for (int32 i = 0; i < tab_index; i++) 754 x += StringWidth(TabAt(i)->Label()) + 20.0f; 755 756 return BRect(x, 0.0f, 757 x + StringWidth(TabAt(tab_index)->Label()) + 20.0f, fTabHeight); 758 } 759 760 case B_WIDTH_FROM_WIDEST: 761 { 762 float width = 0.0f; 763 764 for (int32 i = 0; i < CountTabs(); i++) { 765 float tabWidth = StringWidth(TabAt(i)->Label()) + 20.0f; 766 767 if (tabWidth > width) 768 width = tabWidth; 769 } 770 771 return BRect(X_OFFSET + tab_index * width, 0.0f, 772 X_OFFSET + tab_index * width + width, fTabHeight); 773 } 774 775 case B_WIDTH_AS_USUAL: 776 default: 777 return BRect(X_OFFSET + tab_index * 100.0f, 0.0f, 778 X_OFFSET + tab_index * 100.0f + 100.0f, fTabHeight); 779 } 780 } 781 782 783 void 784 BTabView::SetFlags(uint32 flags) 785 { 786 BView::SetFlags(flags); 787 } 788 789 790 void 791 BTabView::SetResizingMode(uint32 mode) 792 { 793 BView::SetResizingMode(mode); 794 } 795 796 797 void 798 BTabView::GetPreferredSize(float *width, float *height) 799 { 800 BView::GetPreferredSize(width, height); 801 } 802 803 804 void 805 BTabView::ResizeToPreferred() 806 { 807 BView::ResizeToPreferred(); 808 } 809 810 811 BHandler * 812 BTabView::ResolveSpecifier(BMessage *message, int32 index, 813 BMessage *specifier, int32 what, const char *property) 814 { 815 return BView::ResolveSpecifier(message, index, specifier, what, property); 816 } 817 818 819 status_t 820 BTabView::GetSupportedSuites(BMessage *message) 821 { 822 return BView::GetSupportedSuites(message); 823 } 824 825 826 void 827 BTabView::AddTab(BView *target, BTab *tab) 828 { 829 if (tab == NULL) 830 tab = new BTab(target); 831 else 832 tab->SetView(target); 833 834 fTabList->AddItem(tab); 835 } 836 837 838 BTab * 839 BTabView::RemoveTab(int32 index) 840 { 841 if (index < 0 || index >= CountTabs()) 842 return NULL; 843 844 BTab *tab = (BTab *)fTabList->RemoveItem(index); 845 if (tab == NULL) 846 return NULL; 847 848 tab->Deselect(); 849 850 if (index <= fSelection && fSelection != 0) 851 fSelection--; 852 853 Select(fSelection); 854 855 if (fFocus == CountTabs() - 1) 856 SetFocusTab(fFocus, false); 857 else 858 SetFocusTab(fFocus, true); 859 860 return tab; 861 } 862 863 864 BTab * 865 BTabView::TabAt(int32 index) const 866 { 867 return (BTab *)fTabList->ItemAt(index); 868 } 869 870 871 void 872 BTabView::SetTabWidth(button_width width) 873 { 874 fTabWidthSetting = width; 875 876 Invalidate(); 877 } 878 879 880 button_width 881 BTabView::TabWidth() const 882 { 883 return fTabWidthSetting; 884 } 885 886 887 void 888 BTabView::SetTabHeight(float height) 889 { 890 if (fTabHeight == height) 891 return; 892 893 fContainerView->MoveBy(0.0f, height - fTabHeight); 894 fContainerView->ResizeBy(0.0f, height - fTabHeight); 895 896 fTabHeight = height; 897 898 Invalidate(); 899 } 900 901 902 float 903 BTabView::TabHeight() const 904 { 905 return fTabHeight; 906 } 907 908 909 BView * 910 BTabView::ContainerView() const 911 { 912 return fContainerView; 913 } 914 915 916 int32 917 BTabView::CountTabs() const 918 { 919 return fTabList->CountItems(); 920 } 921 922 923 BView * 924 BTabView::ViewForTab(int32 tabIndex) const 925 { 926 BTab *tab = TabAt(tabIndex); 927 if (tab) 928 return tab->View(); 929 930 return NULL; 931 } 932 933 934 void 935 BTabView::_InitObject() 936 { 937 fTabList = new BList; 938 939 fTabWidthSetting = B_WIDTH_AS_USUAL; 940 fSelection = 0; 941 fFocus = -1; 942 943 rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR); 944 945 SetViewColor(color); 946 SetLowColor(color); 947 948 font_height fh; 949 GetFontHeight(&fh); 950 fTabHeight = fh.ascent + fh.descent + fh.leading + 8.0f; 951 952 BRect bounds = Bounds(); 953 954 bounds.top += TabHeight(); 955 bounds.InsetBy(3.0f, 3.0f); 956 957 fContainerView = new BView(bounds, "view container", B_FOLLOW_ALL, 958 B_WILL_DRAW); 959 960 fContainerView->SetViewColor(color); 961 fContainerView->SetLowColor(color); 962 963 AddChild(fContainerView); 964 } 965 966 967 void BTabView::_ReservedTabView1() {} 968 void BTabView::_ReservedTabView2() {} 969 void BTabView::_ReservedTabView3() {} 970 void BTabView::_ReservedTabView4() {} 971 void BTabView::_ReservedTabView5() {} 972 void BTabView::_ReservedTabView6() {} 973 void BTabView::_ReservedTabView7() {} 974 void BTabView::_ReservedTabView8() {} 975 void BTabView::_ReservedTabView9() {} 976 void BTabView::_ReservedTabView10() {} 977 void BTabView::_ReservedTabView11() {} 978 void BTabView::_ReservedTabView12() {} 979 980 981 BTabView::BTabView(const BTabView &tabView) 982 : BView(tabView) 983 { 984 // this is private and not functional, but exported 985 } 986 987 988 BTabView &BTabView::operator=(const BTabView &) 989 { 990 // this is private and not functional, but exported 991 return *this; 992 } 993