2 * Copyright 2001-2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Marc Flerackers (mflerackers@androme.be)
7 * Jérôme Duval (korli@users.berlios.de)
8 * Stephan Aßmus <superstippi@gmx.de>
10 * Rene Gollent (rene@gollent.com)
15 #include <TabViewPrivate.h>
20 #include <CardLayout.h>
21 #include <ControlLook.h>
22 #include <GroupLayout.h>
23 #include <LayoutUtils.h>
26 #include <PropertyInfo.h>
31 #include <binary_compatibility/Support.h>
37 static property_info sPropertyList
[] = {
40 { B_GET_PROPERTY
, B_SET_PROPERTY
},
41 { B_DIRECT_SPECIFIER
},
51 BTab::BTab(BView
* contentsView
)
62 BTab::BTab(BMessage
* archive
)
72 if (archive
->FindBool("_disable", &disable
) != B_OK
)
92 BTab::Instantiate(BMessage
* archive
)
94 if (validate_instantiation(archive
, "BTab"))
95 return new BTab(archive
);
102 BTab::Archive(BMessage
* data
, bool deep
) const
104 status_t result
= BArchivable::Archive(data
, deep
);
109 result
= data
->AddBool("_disable", false);
116 BTab::Perform(uint32 d
, void* arg
)
118 return BArchivable::Perform(d
, arg
);
126 return fView
->Name();
133 BTab::SetLabel(const char* label
)
135 if (label
== NULL
|| fView
== NULL
)
138 fView
->SetName(label
);
140 if (fTabView
!= NULL
)
141 fTabView
->Invalidate();
146 BTab::IsSelected() const
153 BTab::Select(BView
* owner
)
157 if (owner
== NULL
|| fView
== NULL
)
160 // NOTE: Views are not added/removed, if there is layout,
161 // they are made visible/invisible in that case.
162 if (owner
->GetLayout() == NULL
&& fView
->Parent() == NULL
)
163 owner
->AddChild(fView
);
171 // NOTE: Views are not added/removed, if there is layout,
172 // they are made visible/invisible in that case.
173 bool removeView
= false;
174 BView
* container
= fView
->Parent();
175 if (container
!= NULL
)
177 dynamic_cast<BCardLayout
*>(container
->GetLayout()) == NULL
;
187 BTab::SetEnabled(bool enable
)
194 BTab::IsEnabled() const
201 BTab::MakeFocus(bool focus
)
208 BTab::IsFocus() const
215 BTab::SetView(BView
* view
)
217 if (view
== NULL
|| fView
== view
)
226 if (fTabView
!= NULL
&& fSelected
) {
227 Select(fTabView
->ContainerView());
228 fTabView
->Invalidate();
241 BTab::DrawFocusMark(BView
* owner
, BRect frame
)
243 float width
= owner
->StringWidth(Label());
245 owner
->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR
));
247 float offset
= IsSelected() ? 3 : 2;
248 owner
->StrokeLine(BPoint((frame
.left
+ frame
.right
- width
) / 2.0,
249 frame
.bottom
- offset
),
250 BPoint((frame
.left
+ frame
.right
+ width
) / 2.0,
251 frame
.bottom
- offset
));
256 BTab::DrawLabel(BView
* owner
, BRect frame
)
258 be_control_look
->DrawLabel(owner
, Label(), frame
, frame
,
259 ui_color(B_PANEL_BACKGROUND_COLOR
),
260 IsEnabled() ? 0 : BPrivate::BControlLook::B_DISABLED
,
261 BAlignment(B_ALIGN_HORIZONTAL_CENTER
, B_ALIGN_VERTICAL_CENTER
));
266 BTab::DrawTab(BView
* owner
, BRect frame
, tab_position position
, bool full
)
268 rgb_color no_tint
= ui_color(B_PANEL_BACKGROUND_COLOR
);
269 uint32 borders
= BControlLook::B_TOP_BORDER
270 | BControlLook::B_BOTTOM_BORDER
;
272 if (frame
.left
== owner
->Bounds().left
)
273 borders
|= BControlLook::B_LEFT_BORDER
;
275 if (frame
.right
== owner
->Bounds().right
)
276 borders
|= BControlLook::B_RIGHT_BORDER
;
278 if (position
== B_TAB_FRONT
) {
280 be_control_look
->DrawActiveTab(owner
, frame
, frame
, no_tint
, 0,
283 be_control_look
->DrawInactiveTab(owner
, frame
, frame
, no_tint
, 0,
287 DrawLabel(owner
, frame
);
291 // #pragma mark - FBC padding and private methods
294 void BTab::_ReservedTab1() {}
295 void BTab::_ReservedTab2() {}
296 void BTab::_ReservedTab3() {}
297 void BTab::_ReservedTab4() {}
298 void BTab::_ReservedTab5() {}
299 void BTab::_ReservedTab6() {}
300 void BTab::_ReservedTab7() {}
301 void BTab::_ReservedTab8() {}
302 void BTab::_ReservedTab9() {}
303 void BTab::_ReservedTab10() {}
304 void BTab::_ReservedTab11() {}
305 void BTab::_ReservedTab12() {}
307 BTab
&BTab::operator=(const BTab
&)
309 // this is private and not functional, but exported
314 // #pragma mark - BTabView
317 BTabView::BTabView(const char* name
, button_width width
, uint32 flags
)
321 _InitObject(true, width
);
325 BTabView::BTabView(BRect frame
, const char* name
, button_width width
,
326 uint32 resizeMask
, uint32 flags
)
328 BView(frame
, name
, resizeMask
, flags
)
330 _InitObject(false, width
);
334 BTabView::~BTabView()
336 for (int32 i
= 0; i
< CountTabs(); i
++)
343 BTabView::BTabView(BMessage
* archive
)
345 BView(BUnarchiver::PrepareArchive(archive
)),
347 fContainerView(NULL
),
350 BUnarchiver
unarchiver(archive
);
353 if (archive
->FindInt16("_but_width", &width
) == B_OK
)
354 fTabWidthSetting
= (button_width
)width
;
356 fTabWidthSetting
= B_WIDTH_AS_USUAL
;
358 if (archive
->FindFloat("_high", &fTabHeight
) != B_OK
) {
361 fTabHeight
= fh
.ascent
+ fh
.descent
+ fh
.leading
+ 8.0f
;
364 if (archive
->FindInt32("_sel", &fSelection
) != B_OK
)
367 if (archive
->FindInt32("_border_style", (int32
*)&fBorderStyle
) != B_OK
)
368 fBorderStyle
= B_FANCY_BORDER
;
373 if (BUnarchiver::IsArchiveManaged(archive
)) {
375 archive
->GetInfo("_l_items", NULL
, &tabCount
);
376 for (int32 i
= 0; i
< tabCount
; i
++) {
377 unarchiver
.EnsureUnarchived("_l_items", i
);
378 unarchiver
.EnsureUnarchived("_view_list", i
);
383 fContainerView
= ChildAt(0);
384 _InitContainerView(Flags() & B_SUPPORTS_LAYOUT
);
386 while (archive
->FindMessage("_l_items", i
, &tabMsg
) == B_OK
) {
387 BArchivable
* archivedTab
= instantiate_object(&tabMsg
);
390 BTab
* tab
= dynamic_cast<BTab
*>(archivedTab
);
393 if (archive
->FindMessage("_view_list", i
, &viewMsg
) == B_OK
) {
394 BArchivable
* archivedView
= instantiate_object(&viewMsg
);
396 AddTab(dynamic_cast<BView
*>(archivedView
), tab
);
407 BTabView::Instantiate(BMessage
* archive
)
409 if ( validate_instantiation(archive
, "BTabView"))
410 return new BTabView(archive
);
417 BTabView::Archive(BMessage
* archive
, bool deep
) const
419 BArchiver
archiver(archive
);
421 status_t result
= BView::Archive(archive
, deep
);
424 result
= archive
->AddInt16("_but_width", fTabWidthSetting
);
426 result
= archive
->AddFloat("_high", fTabHeight
);
428 result
= archive
->AddInt32("_sel", fSelection
);
429 if (result
== B_OK
&& fBorderStyle
!= B_FANCY_BORDER
)
430 result
= archive
->AddInt32("_border_style", fBorderStyle
);
432 if (result
== B_OK
&& deep
) {
433 for (int32 i
= 0; i
< CountTabs(); i
++) {
434 BTab
* tab
= TabAt(i
);
436 if ((result
= archiver
.AddArchivable("_l_items", tab
, deep
)) != B_OK
)
438 result
= archiver
.AddArchivable("_view_list", tab
->View(), deep
);
442 return archiver
.Finish(result
);
447 BTabView::AllUnarchived(const BMessage
* archive
)
449 status_t err
= BView::AllUnarchived(archive
);
453 fContainerView
= ChildAt(0);
454 _InitContainerView(Flags() & B_SUPPORTS_LAYOUT
);
456 BUnarchiver
unarchiver(archive
);
459 archive
->GetInfo("_l_items", NULL
, &tabCount
);
460 for (int32 i
= 0; i
< tabCount
&& err
== B_OK
; i
++) {
462 err
= unarchiver
.FindObject("_l_items", i
, tab
);
463 if (err
== B_OK
&& tab
) {
465 if ((err
= unarchiver
.FindObject("_view_list", i
,
466 BUnarchiver::B_DONT_ASSUME_OWNERSHIP
, view
)) != B_OK
)
470 fTabList
->AddItem(tab
);
482 BTabView::Perform(perform_code code
, void* _data
)
485 case PERFORM_CODE_ALL_UNARCHIVED
:
487 perform_data_all_unarchived
* data
488 = (perform_data_all_unarchived
*)_data
;
490 data
->return_value
= BTabView::AllUnarchived(data
->archive
);
495 return BView::Perform(code
, _data
);
500 BTabView::AttachedToWindow()
502 BView::AttachedToWindow();
504 if (fSelection
< 0 && CountTabs() > 0)
510 BTabView::DetachedFromWindow()
512 BView::DetachedFromWindow();
517 BTabView::AllAttached()
519 BView::AllAttached();
524 BTabView::AllDetached()
526 BView::AllDetached();
534 BTabView::MessageReceived(BMessage
* message
)
536 switch (message
->what
) {
540 BMessage
reply(B_REPLY
);
541 bool handled
= false;
546 const char* property
;
547 if (message
->GetCurrentSpecifier(&index
, &specifier
, &form
, &property
) == B_OK
) {
548 if (strcmp(property
, "Selection") == 0) {
549 if (message
->what
== B_GET_PROPERTY
) {
550 reply
.AddInt32("result", fSelection
);
555 if (message
->FindInt32("data", &selection
) == B_OK
) {
557 reply
.AddInt32("error", B_OK
);
565 message
->SendReply(&reply
);
567 BView::MessageReceived(message
);
572 case B_MOUSE_WHEEL_CHANGED
:
576 message
->FindFloat("be:wheel_delta_x", &deltaX
);
577 message
->FindFloat("be:wheel_delta_y", &deltaY
);
579 if (deltaX
== 0.0f
&& deltaY
== 0.0f
)
585 int32 selection
= Selection();
586 int32 numTabs
= CountTabs();
587 if (deltaY
> 0 && selection
< numTabs
- 1) {
588 // move to the right tab.
589 Select(Selection() + 1);
590 } else if (deltaY
< 0 && selection
> 0 && numTabs
> 1) {
591 // move to the left tab.
592 Select(selection
- 1);
599 BView::MessageReceived(message
);
606 BTabView::KeyDown(const char* bytes
, int32 numBytes
)
614 int32 focus
= fFocus
- 1;
616 focus
= CountTabs() - 1;
617 SetFocusTab(focus
, true);
622 case B_RIGHT_ARROW
: {
623 int32 focus
= fFocus
+ 1;
624 if (focus
>= CountTabs())
626 SetFocusTab(focus
, true);
636 BView::KeyDown(bytes
, numBytes
);
642 BTabView::MouseDown(BPoint where
)
644 if (where
.y
> fTabHeight
)
647 for (int32 i
= 0; i
< CountTabs(); i
++) {
648 if (TabFrame(i
).Contains(where
)
649 && i
!= Selection()) {
655 BView::MouseDown(where
);
660 BTabView::MouseUp(BPoint where
)
662 BView::MouseUp(where
);
667 BTabView::MouseMoved(BPoint where
, uint32 transit
, const BMessage
* dragMessage
)
669 BView::MouseMoved(where
, transit
, dragMessage
);
681 BTabView::Select(int32 index
)
683 if (index
== Selection())
686 if (index
< 0 || index
>= CountTabs())
689 BTab
* tab
= TabAt(Selection());
695 if (tab
!= NULL
&& fContainerView
!= NULL
) {
698 tab
->Select(fContainerView
);
701 // make the view visible through the layout if there is one
703 = dynamic_cast<BCardLayout
*>(fContainerView
->GetLayout());
705 layout
->SetVisibleItem(index
);
710 if (index
!= 0 && !Bounds().Contains(TabFrame(index
))){
711 if (!Bounds().Contains(TabFrame(index
).LeftTop()))
712 fTabOffset
+= TabFrame(index
).left
- Bounds().left
- 20.0f
;
714 fTabOffset
+= TabFrame(index
).right
- Bounds().right
+ 20.0f
;
719 SetFocusTab(index
, true);
724 BTabView::Selection() const
731 BTabView::WindowActivated(bool active
)
733 BView::WindowActivated(active
);
741 BTabView::MakeFocus(bool focus
)
743 BView::MakeFocus(focus
);
745 SetFocusTab(Selection(), focus
);
750 BTabView::SetFocusTab(int32 tab
, bool focus
)
752 if (tab
>= CountTabs())
756 tab
= CountTabs() - 1;
763 if (TabAt (fFocus
) != NULL
)
764 TabAt(fFocus
)->MakeFocus(false);
765 Invalidate(TabFrame(fFocus
));
767 if (TabAt(tab
) != NULL
){
768 TabAt(tab
)->MakeFocus(true);
769 Invalidate(TabFrame(tab
));
772 } else if (fFocus
!= -1) {
773 TabAt(fFocus
)->MakeFocus(false);
774 Invalidate(TabFrame(fFocus
));
781 BTabView::FocusTab() const
788 BTabView::Draw(BRect updateRect
)
790 DrawBox(TabFrame(fSelection
));
793 if (IsFocus() && fFocus
!= -1)
794 TabAt(fFocus
)->DrawFocusMark(this, TabFrame(fFocus
));
803 for (int32 i
= 0; i
< CountTabs(); i
++) {
804 BRect tabFrame
= TabFrame(i
);
805 TabAt(i
)->DrawTab(this, tabFrame
,
806 i
== fSelection
? B_TAB_FRONT
: (i
== 0) ? B_TAB_FIRST
: B_TAB_ANY
,
807 i
+ 1 != fSelection
);
808 left
= tabFrame
.right
;
811 BRect
frame(Bounds());
812 if (fBorderStyle
== B_PLAIN_BORDER
)
814 else if (fBorderStyle
== B_NO_BORDER
)
816 if (left
< frame
.right
) {
818 frame
.bottom
= fTabHeight
;
819 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
820 uint32 borders
= BControlLook::B_TOP_BORDER
821 | BControlLook::B_BOTTOM_BORDER
| BControlLook::B_RIGHT_BORDER
;
823 borders
|= BControlLook::B_LEFT_BORDER
;
824 be_control_look
->DrawInactiveTab(this, frame
, frame
, base
, 0,
827 if (fBorderStyle
== B_NO_BORDER
) {
828 // Draw a small inactive area before first tab.
832 frame
.bottom
= fTabHeight
;
833 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
834 uint32 borders
= BControlLook::B_TOP_BORDER
835 | BControlLook::B_BOTTOM_BORDER
;
836 be_control_look
->DrawInactiveTab(this, frame
, frame
, base
, 0,
840 if (fSelection
< CountTabs())
841 return TabFrame(fSelection
);
848 BTabView::DrawBox(BRect selTabRect
)
850 BRect
rect(Bounds());
851 rect
.top
= selTabRect
.bottom
;
852 if (fBorderStyle
!= B_FANCY_BORDER
)
854 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
856 if (fBorderStyle
== B_FANCY_BORDER
)
857 be_control_look
->DrawGroupFrame(this, rect
, rect
, base
);
859 uint32 borders
= BControlLook::B_TOP_BORDER
;
860 if (fBorderStyle
== B_PLAIN_BORDER
)
861 borders
= BControlLook::B_ALL_BORDERS
;
862 be_control_look
->DrawBorder(this, rect
, rect
, base
, B_PLAIN_BORDER
,
869 BTabView::TabFrame(int32 index
) const
871 if (index
>= CountTabs() || index
< 0)
874 float width
= 100.0f
;
875 float height
= fTabHeight
;
876 float borderOffset
= 0.0f
;
877 // Do not use 2.0f for B_NO_BORDER, that will look yet different
878 // again (handled in DrawTabs()).
879 if (fBorderStyle
== B_PLAIN_BORDER
)
881 switch (fTabWidthSetting
) {
882 case B_WIDTH_FROM_LABEL
:
885 for (int32 i
= 0; i
< index
; i
++){
886 x
+= StringWidth(TabAt(i
)->Label()) + 20.0f
;
889 return BRect(x
- borderOffset
, 0.0f
,
890 x
+ StringWidth(TabAt(index
)->Label()) + 20.0f
895 case B_WIDTH_FROM_WIDEST
:
897 for (int32 i
= 0; i
< CountTabs(); i
++) {
898 float tabWidth
= StringWidth(TabAt(i
)->Label()) + 20.0f
;
899 if (tabWidth
> width
)
904 case B_WIDTH_AS_USUAL
:
906 return BRect(index
* width
- borderOffset
, 0.0f
,
907 index
* width
+ width
- borderOffset
, height
);
910 // TODO: fix to remove "offset" in DrawTab and DrawLabel ...
911 switch (fTabWidthSetting
) {
912 case B_WIDTH_FROM_LABEL
:
915 for (int32 i
= 0; i
< index
; i
++){
916 x
+= StringWidth(TabAt(i
)->Label()) + 20.0f
;
919 return BRect(x
- fTabOffset
, 0.0f
,
920 x
- fTabOffset
+ StringWidth(TabAt(index
)->Label()) + 20.0f
,
924 case B_WIDTH_FROM_WIDEST
:
928 for (int32 i
= 0; i
< CountTabs(); i
++) {
929 float tabWidth
= StringWidth(TabAt(i
)->Label()) + 20.0f
;
930 if (tabWidth
> width
)
933 return BRect((6.0f
+ index
* width
) - fTabOffset
, 0.0f
,
934 (6.0f
+ index
* width
+ width
) - fTabOffset
, fTabHeight
);
937 case B_WIDTH_AS_USUAL
:
939 return BRect((6.0f
+ index
* 100.0f
) - fTabOffset
, 0.0f
,
940 (6.0f
+ index
* 100.0f
+ 100.0f
) - fTabOffset
, fTabHeight
);
946 BTabView::SetFlags(uint32 flags
)
948 BView::SetFlags(flags
);
953 BTabView::SetResizingMode(uint32 mode
)
955 BView::SetResizingMode(mode
);
963 BTabView::ResizeToPreferred()
965 BView::ResizeToPreferred();
970 BTabView::GetPreferredSize(float* _width
, float* _height
)
972 BView::GetPreferredSize(_width
, _height
);
981 size
= GetLayout()->MinSize();
983 size
= _TabsMinSize();
984 BSize containerSize
= fContainerView
->MinSize();
985 containerSize
.width
+= 2 * _BorderWidth();
986 containerSize
.height
+= 2 * _BorderWidth();
987 if (containerSize
.width
> size
.width
)
988 size
.width
= containerSize
.width
;
989 size
.height
+= containerSize
.height
;
991 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size
);
1000 size
= GetLayout()->MaxSize();
1002 size
= _TabsMinSize();
1003 BSize containerSize
= fContainerView
->MaxSize();
1004 containerSize
.width
+= 2 * _BorderWidth();
1005 containerSize
.height
+= 2 * _BorderWidth();
1006 if (containerSize
.width
> size
.width
)
1007 size
.width
= containerSize
.width
;
1008 size
.height
+= containerSize
.height
;
1010 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size
);
1015 BTabView::PreferredSize()
1018 if (GetLayout() != NULL
)
1019 size
= GetLayout()->PreferredSize();
1021 size
= _TabsMinSize();
1022 BSize containerSize
= fContainerView
->PreferredSize();
1023 containerSize
.width
+= 2 * _BorderWidth();
1024 containerSize
.height
+= 2 * _BorderWidth();
1025 if (containerSize
.width
> size
.width
)
1026 size
.width
= containerSize
.width
;
1027 size
.height
+= containerSize
.height
;
1029 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size
);
1034 BTabView::FrameMoved(BPoint newPosition
)
1036 BView::FrameMoved(newPosition
);
1041 BTabView::FrameResized(float newWidth
, float newHeight
)
1043 BView::FrameResized(newWidth
, newHeight
);
1051 BTabView::ResolveSpecifier(BMessage
* message
, int32 index
,
1052 BMessage
* specifier
, int32 what
, const char* property
)
1054 BPropertyInfo
propInfo(sPropertyList
);
1056 if (propInfo
.FindMatch(message
, 0, specifier
, what
, property
) >= B_OK
)
1059 return BView::ResolveSpecifier(message
, index
, specifier
, what
, property
);
1064 BTabView::GetSupportedSuites(BMessage
* message
)
1066 message
->AddString("suites", "suite/vnd.Be-tab-view");
1068 BPropertyInfo
propInfo(sPropertyList
);
1069 message
->AddFlat("messages", &propInfo
);
1071 return BView::GetSupportedSuites(message
);
1079 BTabView::AddTab(BView
* target
, BTab
* tab
)
1082 tab
= new BTab(target
);
1084 tab
->SetView(target
);
1086 if (fContainerView
->GetLayout())
1087 fContainerView
->GetLayout()->AddView(CountTabs(), target
);
1089 fTabList
->AddItem(tab
);
1090 BTab::Private(tab
).SetTabView(this);
1092 // When we haven't had a any tabs before, but are already attached to the
1093 // window, select this one.
1094 if (CountTabs() == 1 && Window() != NULL
)
1100 BTabView::RemoveTab(int32 index
)
1102 if (index
< 0 || index
>= CountTabs())
1105 BTab
* tab
= (BTab
*)fTabList
->RemoveItem(index
);
1110 BTab::Private(tab
).SetTabView(NULL
);
1112 if (fContainerView
->GetLayout())
1113 fContainerView
->GetLayout()->RemoveItem(index
);
1115 if (CountTabs() == 0)
1117 else if (index
<= fSelection
)
1118 Select(fSelection
- 1);
1120 if (fFocus
== CountTabs() - 1 || CountTabs() == 0)
1121 SetFocusTab(fFocus
, false);
1123 SetFocusTab(fFocus
, true);
1130 BTabView::TabAt(int32 index
) const
1132 return (BTab
*)fTabList
->ItemAt(index
);
1137 BTabView::SetTabWidth(button_width width
)
1139 fTabWidthSetting
= width
;
1146 BTabView::TabWidth() const
1148 return fTabWidthSetting
;
1153 BTabView::SetTabHeight(float height
)
1155 if (fTabHeight
== height
)
1158 fTabHeight
= height
;
1159 _LayoutContainerView(GetLayout() != NULL
);
1166 BTabView::TabHeight() const
1173 BTabView::SetBorder(border_style border
)
1175 if (fBorderStyle
== border
)
1178 fBorderStyle
= border
;
1180 _LayoutContainerView((Flags() & B_SUPPORTS_LAYOUT
) != 0);
1185 BTabView::Border() const
1187 return fBorderStyle
;
1192 BTabView::ContainerView() const
1194 return fContainerView
;
1199 BTabView::CountTabs() const
1201 return fTabList
->CountItems();
1206 BTabView::ViewForTab(int32 tabIndex
) const
1208 BTab
* tab
= TabAt(tabIndex
);
1217 BTabView::_InitObject(bool layouted
, button_width width
)
1219 fTabList
= new BList
;
1221 fTabWidthSetting
= width
;
1225 fBorderStyle
= B_FANCY_BORDER
;
1227 rgb_color color
= ui_color(B_PANEL_BACKGROUND_COLOR
);
1229 SetViewColor(color
);
1234 fTabHeight
= fh
.ascent
+ fh
.descent
+ fh
.leading
+ 8.0f
;
1236 fContainerView
= NULL
;
1237 _InitContainerView(layouted
);
1242 BTabView::_InitContainerView(bool layouted
)
1244 bool needsLayout
= false;
1245 bool createdContainer
= false;
1247 if (GetLayout() == NULL
) {
1248 SetLayout(new(nothrow
) BGroupLayout(B_HORIZONTAL
));
1252 if (fContainerView
== NULL
) {
1253 fContainerView
= new BView("view container", B_WILL_DRAW
);
1254 fContainerView
->SetLayout(new(std::nothrow
) BCardLayout());
1255 createdContainer
= true;
1257 } else if (fContainerView
== NULL
) {
1258 fContainerView
= new BView(Bounds(), "view container", B_FOLLOW_ALL
,
1260 createdContainer
= true;
1263 if (needsLayout
|| createdContainer
)
1264 _LayoutContainerView(layouted
);
1266 if (createdContainer
) {
1267 fContainerView
->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
1268 fContainerView
->SetLowColor(fContainerView
->ViewColor());
1269 AddChild(fContainerView
);
1275 BTabView::_TabsMinSize() const
1277 BSize
size(0.0f
, TabHeight());
1278 int32 count
= min_c(2, CountTabs());
1279 for (int32 i
= 0; i
< count
; i
++) {
1280 BRect frame
= TabFrame(i
);
1281 size
.width
+= frame
.Width();
1284 if (count
< CountTabs()) {
1285 // TODO: Add size for yet to be implemented buttons that allow
1286 // "scrolling" the displayed tabs left/right.
1294 BTabView::_BorderWidth() const
1296 switch (fBorderStyle
) {
1298 case B_FANCY_BORDER
:
1300 case B_PLAIN_BORDER
:
1309 BTabView::_LayoutContainerView(bool layouted
)
1311 float borderWidth
= _BorderWidth();
1313 float topBorderOffset
;
1314 switch (fBorderStyle
) {
1316 case B_FANCY_BORDER
:
1317 topBorderOffset
= 1.0f
;
1319 case B_PLAIN_BORDER
:
1320 topBorderOffset
= 0.0f
;
1323 topBorderOffset
= -1.0f
;
1326 BGroupLayout
* layout
= dynamic_cast<BGroupLayout
*>(GetLayout());
1327 if (layout
!= NULL
) {
1328 layout
->SetInsets(borderWidth
, borderWidth
+ TabHeight()
1329 - topBorderOffset
, borderWidth
, borderWidth
);
1332 BRect bounds
= Bounds();
1334 bounds
.top
+= TabHeight();
1335 bounds
.InsetBy(borderWidth
, borderWidth
);
1337 fContainerView
->MoveTo(bounds
.left
, bounds
.top
);
1338 fContainerView
->ResizeTo(bounds
.Width(), bounds
.Height());
1343 // #pragma mark - FBC and forbidden
1346 void BTabView::_ReservedTabView2() {}
1347 void BTabView::_ReservedTabView3() {}
1348 void BTabView::_ReservedTabView4() {}
1349 void BTabView::_ReservedTabView5() {}
1350 void BTabView::_ReservedTabView6() {}
1351 void BTabView::_ReservedTabView7() {}
1352 void BTabView::_ReservedTabView8() {}
1353 void BTabView::_ReservedTabView9() {}
1354 void BTabView::_ReservedTabView10() {}
1355 void BTabView::_ReservedTabView11() {}
1356 void BTabView::_ReservedTabView12() {}
1359 BTabView::BTabView(const BTabView
& tabView
)
1362 // this is private and not functional, but exported
1367 BTabView::operator=(const BTabView
&)
1369 // this is private and not functional, but exported
1373 // #pragma mark - binary compatibility
1377 B_IF_GCC_2(_ReservedTabView1__8BTabView
, _ZN8BTabView17_ReservedTabView1Ev
)(
1378 BTabView
* tabView
, border_style border
)
1380 tabView
->BTabView::SetBorder(border
);