xref: /haiku/src/kits/interface/TabView.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
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 	owner->StrokeLine(BPoint(frame.left + frame.Width() * 0.5f - width * 0.5f, frame.bottom),
211 		BPoint(frame.left + frame.Width() * 0.5f + width * 0.5f, frame.bottom));
212 }
213 
214 
215 void
216 BTab::DrawLabel(BView *owner, BRect frame)
217 {
218 	const char *label = Label();
219 	if (label == NULL)
220 		return;
221 
222 	owner->SetHighColor(0, 0, 0);
223 	owner->DrawString(label, BPoint(frame.left + frame.Width() * 0.5f -
224 		owner->StringWidth(label) * 0.5f, frame.bottom - 4.0f - 2.0f));
225 }
226 
227 
228 void
229 BTab::DrawTab(BView *owner, BRect frame, tab_position position, bool full)
230 {
231 	rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR);
232 	rgb_color lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT);
233 	rgb_color darken4 = tint_color(no_tint, B_DARKEN_4_TINT);
234 	rgb_color darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
235 
236 	owner->SetHighColor(darkenmax);
237 	owner->SetLowColor(no_tint);
238 	DrawLabel(owner, frame);
239 
240 	owner->BeginLineArray(12);
241 
242 	if (position != B_TAB_ANY) {
243 		owner->AddLine(BPoint(frame.left - 2.0f, frame.bottom),
244 			BPoint(frame.left - 1.0f, frame.bottom - 1.0f), lightenmax);
245 		owner->AddLine(BPoint(frame.left, frame.bottom - 2.0f),
246 			BPoint(frame.left, frame.bottom - 3.0f), lightenmax);
247 	}
248 
249 	owner->AddLine(BPoint(frame.left + 1.0f, frame.bottom - 4.0f),
250 		BPoint(frame.left + 1.0f, frame.top + 5.0f), lightenmax);
251 	owner->AddLine(BPoint(frame.left + 1.0f, frame.top + 4.0f),
252 		BPoint(frame.left + 2.0f, frame.top + 2.0f), lightenmax);
253 	owner->AddLine(BPoint(frame.left + 3.0f, frame.top + 1.0f),
254 		BPoint(frame.left + 4.0f, frame.top + 1.0f), lightenmax);
255 	owner->AddLine(BPoint(frame.left + 5.0f, frame.top),
256 		BPoint(frame.right - 5.0f, frame.top), lightenmax);
257 
258 	owner->AddLine(BPoint(frame.right - 4.0f, frame.top + 1.0f),
259 		BPoint(frame.right - 3.0f, frame.top + 1.0f), lightenmax);
260 
261 	owner->AddLine(BPoint(frame.right - 2.0f, frame.top + 2.0f),
262 		BPoint(frame.right - 2.0f, frame.top + 3.0f), darken4);
263 	owner->AddLine(BPoint(frame.right - 1.0f, frame.top + 4.0f),
264 		BPoint(frame.right - 1.0f, frame.bottom - 4.0f), darken4);
265 
266 	if (full) {
267 		owner->AddLine(BPoint(frame.right, frame.bottom - 3.0f),
268 			BPoint(frame.right, frame.bottom - 2.0f), darken4);
269 		owner->AddLine(BPoint(frame.right + 1.0f, frame.bottom - 1.0f),
270 			BPoint(frame.right + 2.0f, frame.bottom), darken4);
271 	}
272 
273 	owner->EndLineArray();
274 }
275 
276 
277 void BTab::_ReservedTab1() {}
278 void BTab::_ReservedTab2() {}
279 void BTab::_ReservedTab3() {}
280 void BTab::_ReservedTab4() {}
281 void BTab::_ReservedTab5() {}
282 void BTab::_ReservedTab6() {}
283 void BTab::_ReservedTab7() {}
284 void BTab::_ReservedTab8() {}
285 void BTab::_ReservedTab9() {}
286 void BTab::_ReservedTab10() {}
287 void BTab::_ReservedTab11() {}
288 void BTab::_ReservedTab12() {}
289 
290 BTab &BTab::operator=(const BTab &)
291 {
292 	// this is private and not functional, but exported
293 	return *this;
294 }
295 
296 
297 //	#pragma mark -
298 
299 
300 BTabView::BTabView(BRect frame, const char *name, button_width width,
301 	uint32 resizingMode, uint32 flags)
302 	: BView(frame, name, resizingMode, flags)
303 {
304 	_InitObject();
305 
306 	fTabWidthSetting = width;
307 }
308 
309 
310 BTabView::~BTabView()
311 {
312 	for (int32 i = 0; i < CountTabs(); i++) {
313 		delete TabAt(i);
314 	}
315 
316 	delete fTabList;
317 }
318 
319 
320 BTabView::BTabView(BMessage *archive)
321 	: BView(archive),
322 	fFocus(-1)
323 {
324 	fContainerView = NULL;
325 	fTabList = new BList;
326 
327 	int16 width;
328 
329 	if (archive->FindInt16("_but_width", &width) == B_OK)
330 		fTabWidthSetting = (button_width)width;
331 	else
332 		fTabWidthSetting = B_WIDTH_AS_USUAL;
333 
334 	if (archive->FindFloat("_high", &fTabHeight) != B_OK) {
335 		font_height fh;
336 		GetFontHeight(&fh);
337 		fTabHeight = fh.ascent + fh.descent + fh.leading + 8.0f;
338 	}
339 
340 	fFocus = -1;
341 
342 	if (archive->FindInt32("_sel", &fSelection) != B_OK)
343 		fSelection = 0;
344 
345 	if (fContainerView == NULL)
346 		fContainerView = ChildAt(0);
347 
348 	int32 i = 0;
349 	BMessage tabMsg;
350 
351 	while (archive->FindMessage("_l_items", i, &tabMsg) == B_OK) {
352 		BArchivable *archivedTab = instantiate_object(&tabMsg);
353 
354 		if (archivedTab) {
355 			BTab *tab = dynamic_cast<BTab *>(archivedTab);
356 
357 			BMessage viewMsg;
358 			if (archive->FindMessage("_view_list", i, &viewMsg) == B_OK) {
359 				BArchivable *archivedView = instantiate_object(&viewMsg);
360 				if (archivedView)
361 					AddTab(dynamic_cast<BView*>(archivedView), tab);
362 			}
363 		}
364 
365 		tabMsg.MakeEmpty();
366 		i++;
367 	}
368 }
369 
370 
371 BArchivable *
372 BTabView::Instantiate(BMessage *archive)
373 {
374 	if ( validate_instantiation(archive, "BTabView"))
375 		return new BTabView(archive);
376 
377 	return NULL;
378 }
379 
380 
381 status_t
382 BTabView::Archive(BMessage *archive, bool deep) const
383 {
384 	if (CountTabs() > 0)
385 		TabAt(Selection())->View()->RemoveSelf();
386 
387 	BView::Archive(archive, deep);
388 
389 	archive->AddInt16("_but_width", fTabWidthSetting);
390 	archive->AddFloat("_high", fTabHeight);
391 	archive->AddInt32("_sel", fSelection);
392 
393 	if (deep) {
394 		for (int32 i = 0; i < CountTabs(); i++) {
395 			BMessage tabArchive;
396 			BTab *tab = TabAt(i);
397 
398 			if (!tab)
399 				continue;
400 
401 			if (tab->Archive(&tabArchive, true) == B_OK)
402 				archive->AddMessage("_l_items", &tabArchive);
403 
404 			if (!tab->View())
405 				continue;
406 
407 			BMessage viewArchive;
408 
409 			if (tab->View()->Archive(&viewArchive, true) == B_OK)
410 				archive->AddMessage("_view_list", &viewArchive);
411 		}
412 	}
413 
414 	if (CountTabs() > 0) {
415 		if (TabAt(Selection())->View() && ContainerView())
416 			TabAt(Selection())->Select(ContainerView());
417 	}
418 
419 	return B_OK;
420 }
421 
422 
423 status_t
424 BTabView::Perform(perform_code d, void *arg)
425 {
426 	return BView::Perform(d, arg);
427 }
428 
429 
430 void
431 BTabView::WindowActivated(bool active)
432 {
433 	BView::WindowActivated(active);
434 
435 	DrawTabs();
436 }
437 
438 
439 void
440 BTabView::AttachedToWindow()
441 {
442 	BView::AttachedToWindow();
443 
444 	Select(fSelection);
445 }
446 
447 
448 void
449 BTabView::AllAttached()
450 {
451 	BView::AllAttached();
452 }
453 
454 
455 void
456 BTabView::AllDetached()
457 {
458 	BView::AllDetached();
459 }
460 
461 
462 void
463 BTabView::DetachedFromWindow()
464 {
465 	BView::DetachedFromWindow();
466 }
467 
468 
469 void
470 BTabView::MessageReceived(BMessage *message)
471 {
472 	BView::MessageReceived(message);
473 }
474 
475 
476 void
477 BTabView::FrameMoved(BPoint newLocation)
478 {
479 	BView::FrameMoved(newLocation);
480 }
481 
482 
483 void
484 BTabView::FrameResized(float width,float height)
485 {
486 	BView::FrameResized(width, height);
487 }
488 
489 
490 void
491 BTabView::KeyDown(const char *bytes, int32 numBytes)
492 {
493 	if (IsHidden())
494 		return;
495 
496 	switch (bytes[0]) {
497 		case B_DOWN_ARROW:
498 		case B_LEFT_ARROW:
499 			SetFocusTab((fFocus - 1) % CountTabs(), true);
500 			break;
501 
502 		case B_UP_ARROW:
503 		case B_RIGHT_ARROW:
504 			SetFocusTab((fFocus + 1) % CountTabs(), true);
505 			break;
506 
507 		case B_RETURN:
508 		case B_SPACE:
509 			Select(FocusTab());
510 			break;
511 
512 		default:
513 			BView::KeyDown(bytes, numBytes);
514 	}
515 }
516 
517 
518 void
519 BTabView::MouseDown(BPoint point)
520 {
521 	if (point.y > fTabHeight)
522 		return;
523 
524 	for (int32 i = 0; i < CountTabs(); i++) {
525 		if (TabFrame(i).Contains(point)
526 			&& i != Selection()) {
527 			Select(i);
528 			return;
529 		}
530 	}
531 
532 	BView::MouseDown(point);
533 }
534 
535 
536 void
537 BTabView::MouseUp(BPoint point)
538 {
539 	BView::MouseUp(point);
540 }
541 
542 
543 void
544 BTabView::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
545 {
546 	BView::MouseMoved(point, transit, message);
547 }
548 
549 
550 void
551 BTabView::Pulse()
552 {
553 	BView::Pulse();
554 }
555 
556 
557 void
558 BTabView::Select(int32 index)
559 {
560 	if (index < 0 || index >= CountTabs())
561 		index = Selection();
562 
563 	BTab *tab = TabAt(Selection());
564 	if (tab)
565 		tab->Deselect();
566 
567 	tab = TabAt(index);
568 	if (tab && ContainerView()) {
569 		tab->Select(ContainerView());
570 		fSelection = index;
571 	}
572 
573 	//Draw(Bounds());
574 	Invalidate();
575 }
576 
577 
578 int32
579 BTabView::Selection() const
580 {
581 	return fSelection;
582 }
583 
584 
585 void
586 BTabView::MakeFocus(bool focused)
587 {
588 	BView::MakeFocus(focused);
589 
590 	SetFocusTab(Selection(), focused);
591 }
592 
593 
594 void
595 BTabView::SetFocusTab(int32 tab, bool focused)
596 {
597 	if (tab >= CountTabs())
598 		return;
599 
600 	if (focused) {
601 		if (tab == fFocus)
602 			return;
603 
604 		if (fFocus != -1)
605 			TabAt (fFocus)->MakeFocus(false);
606 
607 		TabAt(tab)->MakeFocus(true);
608 		fFocus = tab;
609 	} else if (fFocus != -1) {
610 		TabAt (fFocus)->MakeFocus(false);
611 		fFocus = -1;
612 	}
613 
614 	Invalidate();
615 }
616 
617 
618 int32
619 BTabView::FocusTab() const
620 {
621 	return fFocus;
622 }
623 
624 
625 void
626 BTabView::Draw(BRect updateRect)
627 {
628 	DrawBox(DrawTabs());
629 
630 	if (IsFocus() && fFocus != -1)
631 		TabAt(fFocus)->DrawFocusMark(this, TabFrame(fFocus));
632 }
633 
634 
635 BRect
636 BTabView::DrawTabs()
637 {
638 	for (int32 i = 0; i < CountTabs(); i++)
639 		TabAt(i)->DrawTab(this, TabFrame(i),
640 			i == fSelection ? B_TAB_FRONT : (i == 0) ? B_TAB_FIRST : B_TAB_ANY,
641 			i + 1 != fSelection);
642 
643 	if (fSelection < CountTabs())
644 		return TabFrame(fSelection);
645 
646 	return BRect();
647 }
648 
649 
650 void
651 BTabView::DrawBox(BRect selTabRect)
652 {
653 	BRect rect = Bounds();
654 
655 	SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
656 		B_LIGHTEN_MAX_TINT));
657 
658 	StrokeLine(BPoint(0.0f, rect.bottom), BPoint(0.0f, selTabRect.bottom));
659 	StrokeLine(BPoint(selTabRect.left - 3.0f, selTabRect.bottom));
660 	StrokeLine(BPoint(selTabRect.right + 3.0f, selTabRect.bottom),
661 		BPoint(rect.right - 1.0f, selTabRect.bottom));
662 
663 	SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
664 		B_DARKEN_4_TINT));
665 
666 	StrokeLine(BPoint(rect.right, selTabRect.bottom + 1.0f),
667 		BPoint(rect.right, rect.bottom));
668 	StrokeLine(BPoint(rect.left + 1.0f, rect.bottom));
669 }
670 
671 
672 BRect
673 BTabView::TabFrame(int32 tab_index) const
674 {
675 	switch (fTabWidthSetting) {
676 		case B_WIDTH_FROM_LABEL:
677 		{
678 			float x = 6.0f;
679 			for (int32 i = 0; i < tab_index; i++)
680 				x += StringWidth(TabAt(i)->Label()) + 20.0f;
681 
682 			return BRect(x, 0.0f,
683 				x + StringWidth(TabAt(tab_index)->Label()) + 20.0f, fTabHeight);
684 		}
685 
686 		case B_WIDTH_FROM_WIDEST:
687 		{
688 			float width = 0.0f;
689 
690 			for (int32 i = 0; i < CountTabs(); i++) {
691 				float tabWidth = StringWidth(TabAt(i)->Label()) + 20.0f;
692 
693 				if (tabWidth > width)
694 					width = tabWidth;
695 			}
696 
697 			return BRect(6.0f + tab_index * width, 0.0f,
698 				6.0f + tab_index * width + width, fTabHeight);
699 		}
700 
701 		case B_WIDTH_AS_USUAL:
702 		default:
703 			return BRect(6.0f + tab_index * 100.0f, 0.0f,
704 				6.0f + tab_index * 100.0f + 100.0f, fTabHeight);
705 	}
706 }
707 
708 
709 void
710 BTabView::SetFlags(uint32 flags)
711 {
712 	BView::SetFlags(flags);
713 }
714 
715 
716 void
717 BTabView::SetResizingMode(uint32 mode)
718 {
719 	BView::SetResizingMode(mode);
720 }
721 
722 
723 void
724 BTabView::GetPreferredSize(float *width, float *height)
725 {
726 	BView::GetPreferredSize(width, height);
727 }
728 
729 
730 void
731 BTabView::ResizeToPreferred()
732 {
733 	BView::ResizeToPreferred();
734 }
735 
736 
737 BHandler *
738 BTabView::ResolveSpecifier(BMessage *message, int32 index,
739 	BMessage *specifier, int32 what, const char *property)
740 {
741 	return BView::ResolveSpecifier(message, index, specifier, what, property);
742 }
743 
744 
745 status_t
746 BTabView::GetSupportedSuites(BMessage *message)
747 {
748 	return BView::GetSupportedSuites(message);
749 }
750 
751 
752 void
753 BTabView::AddTab(BView *target, BTab *tab)
754 {
755 	if (tab == NULL)
756 		tab = new BTab(target);
757 	else
758 		tab->SetView(target);
759 
760 	fTabList->AddItem(tab);
761 }
762 
763 
764 BTab *
765 BTabView::RemoveTab(int32 index)
766 {
767 	if (index < 0 || index >= CountTabs())
768 		return NULL;
769 
770 	BTab *tab = (BTab *)fTabList->RemoveItem(index);
771 	if (tab == NULL)
772 		return NULL;
773 
774 	tab->Deselect();
775 
776 	if (index <= fSelection && fSelection != 0)
777 		fSelection--;
778 
779 	Select(fSelection);
780 
781 	if (fFocus == CountTabs() - 1)
782 		SetFocusTab(fFocus, false);
783 	else
784 		SetFocusTab(fFocus, true);
785 
786 	return tab;
787 }
788 
789 
790 BTab *
791 BTabView::TabAt(int32 index) const
792 {
793 	return (BTab *)fTabList->ItemAt(index);
794 }
795 
796 
797 void
798 BTabView::SetTabWidth(button_width width)
799 {
800 	fTabWidthSetting = width;
801 
802 	Invalidate();
803 }
804 
805 
806 button_width
807 BTabView::TabWidth() const
808 {
809 	return fTabWidthSetting;
810 }
811 
812 
813 void
814 BTabView::SetTabHeight(float height)
815 {
816 	if (fTabHeight == height)
817 		return;
818 
819 	fContainerView->MoveBy(0.0f, height - fTabHeight);
820 	fContainerView->ResizeBy(0.0f, height - fTabHeight);
821 
822 	fTabHeight = height;
823 
824 	Invalidate();
825 }
826 
827 
828 float
829 BTabView::TabHeight() const
830 {
831 	return fTabHeight;
832 }
833 
834 
835 BView *
836 BTabView::ContainerView() const
837 {
838 	return fContainerView;
839 }
840 
841 
842 int32
843 BTabView::CountTabs() const
844 {
845 	return fTabList->CountItems();
846 }
847 
848 
849 BView *
850 BTabView::ViewForTab(int32 tabIndex) const
851 {
852 	BTab *tab = TabAt(tabIndex);
853 	if (tab)
854 		return tab->View();
855 
856 	return NULL;
857 }
858 
859 
860 void
861 BTabView::_InitObject()
862 {
863 	fTabList = new BList;
864 
865 	fTabWidthSetting = B_WIDTH_AS_USUAL;
866 	fSelection = 0;
867 	fFocus = -1;
868 
869 	rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR);
870 
871 	SetViewColor(color);
872 	SetLowColor(color);
873 
874 	font_height fh;
875 	GetFontHeight(&fh);
876 	fTabHeight = fh.ascent + fh.descent + fh.leading + 8.0f;
877 
878 	BRect bounds = Bounds();
879 
880 	bounds.top += 1.0f + TabHeight();
881 	bounds.InsetBy(2.0f, 2.0f);
882 
883 	fContainerView = new BView(bounds, "view container", B_FOLLOW_ALL,
884 		B_WILL_DRAW);
885 
886 	fContainerView->SetViewColor(color);
887 	fContainerView->SetLowColor(color);
888 
889 	AddChild(fContainerView);
890 }
891 
892 
893 void BTabView::_ReservedTabView1() {}
894 void BTabView::_ReservedTabView2() {}
895 void BTabView::_ReservedTabView3() {}
896 void BTabView::_ReservedTabView4() {}
897 void BTabView::_ReservedTabView5() {}
898 void BTabView::_ReservedTabView6() {}
899 void BTabView::_ReservedTabView7() {}
900 void BTabView::_ReservedTabView8() {}
901 void BTabView::_ReservedTabView9() {}
902 void BTabView::_ReservedTabView10() {}
903 void BTabView::_ReservedTabView11() {}
904 void BTabView::_ReservedTabView12() {}
905 
906 
907 BTabView::BTabView(const BTabView &tabView)
908 	: BView(tabView)
909 {
910 	// this is private and not functional, but exported
911 }
912 
913 
914 BTabView &BTabView::operator=(const BTabView &)
915 {
916 	// this is private and not functional, but exported
917 	return *this;
918 }
919