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