xref: /haiku/headers/os/interface/LayoutBuilder.h (revision 7749d0bb0c358a3279b1b9cc76d8376e900130a5)
1 /*
2  * Copyright 2009-2010, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef	_LAYOUT_BUILDER_H
6 #define	_LAYOUT_BUILDER_H
7 
8 
9 #include <new>
10 
11 #include <GridLayout.h>
12 #include <GridView.h>
13 #include <GroupLayout.h>
14 #include <GroupView.h>
15 #include <Menu.h>
16 #include <MenuField.h>
17 #include <MenuItem.h>
18 #include <SpaceLayoutItem.h>
19 #include <SplitView.h>
20 #include <TextControl.h>
21 #include <Window.h>
22 
23 
24 namespace BLayoutBuilder {
25 
26 template<typename ParentBuilder> class Base;
27 template<typename ParentBuilder = void*> class Group;
28 template<typename ParentBuilder = void*> class Grid;
29 template<typename ParentBuilder = void*> class Split;
30 template<typename ParentBuilder = void*> class Menu;
31 template<typename ParentBuilder = void*> class MenuItem;
32 
33 
34 template<typename ParentBuilder>
35 class Base {
36 protected:
37 	inline						Base();
38 
39 public:
40 	inline	void				SetParent(ParentBuilder* parent);
41 		// conceptually private
42 	inline	ParentBuilder&		End();
43 
44 protected:
45 			ParentBuilder*		fParent;
46 };
47 
48 
49 template<typename ParentBuilder>
50 class Group : public Base<ParentBuilder> {
51 public:
52 	typedef Group<ParentBuilder>	ThisBuilder;
53 	typedef Group<ThisBuilder>		GroupBuilder;
54 	typedef Grid<ThisBuilder>		GridBuilder;
55 	typedef Split<ThisBuilder>		SplitBuilder;
56 
57 public:
58 	inline						Group(enum orientation orientation
59 										= B_HORIZONTAL,
60 									float spacing = B_USE_DEFAULT_SPACING);
61 	inline						Group(BWindow* window,
62 									enum orientation orientation = B_HORIZONTAL,
63 									float spacing = B_USE_DEFAULT_SPACING);
64 	inline						Group(BView* view,
65 									enum orientation orientation = B_HORIZONTAL,
66 									float spacing = B_USE_DEFAULT_SPACING);
67 	inline						Group(BGroupLayout* layout);
68 	inline						Group(BGroupView* view);
69 
70 	inline	BGroupLayout*		Layout() const;
71 	inline	BView*				View() const;
72 	inline	ThisBuilder&		GetLayout(BGroupLayout** _layout);
73 	inline	ThisBuilder&		GetView(BView** _view);
74 
75 	inline	ThisBuilder&		Add(BView* view);
76 	inline	ThisBuilder&		Add(BView* view, float weight);
77 	inline	ThisBuilder&		Add(BLayoutItem* item);
78 	inline	ThisBuilder&		Add(BLayoutItem* item, float weight);
79 
80 	inline	GroupBuilder		AddGroup(enum orientation orientation,
81 									float spacing = B_USE_DEFAULT_SPACING,
82 									float weight = 1.0f);
83 	inline	GroupBuilder		AddGroup(BGroupView* groupView,
84 									float weight = 1.0f);
85 	inline	GroupBuilder		AddGroup(BGroupLayout* groupLayout,
86 									float weight = 1.0f);
87 
88 	inline	GridBuilder			AddGrid(float horizontal
89 										= B_USE_DEFAULT_SPACING,
90 									float vertical = B_USE_DEFAULT_SPACING,
91 									float weight = 1.0f);
92 	inline	GridBuilder			AddGrid(BGridLayout* gridLayout,
93 									float weight = 1.0f);
94 	inline	GridBuilder			AddGrid(BGridView* gridView,
95 									float weight = 1.0f);
96 
97 	inline	SplitBuilder		AddSplit(enum orientation orientation,
98 									float spacing = B_USE_DEFAULT_SPACING,
99 									float weight = 1.0f);
100 	inline	SplitBuilder		AddSplit(BSplitView* splitView,
101 									float weight = 1.0f);
102 
103 	inline	ThisBuilder&		AddGlue(float weight = 1.0f);
104 	inline	ThisBuilder&		AddStrut(float size);
105 
106 	inline	ThisBuilder&		SetInsets(float left, float top, float right,
107 									float bottom);
108 	inline	ThisBuilder&		SetInsets(float horizontal, float vertical);
109 	inline	ThisBuilder&		SetInsets(float insets);
110 
111 	inline						operator BGroupLayout*();
112 
113 private:
114 			BGroupLayout*		fLayout;
115 };
116 
117 
118 template<typename ParentBuilder>
119 class Grid : public Base<ParentBuilder> {
120 public:
121 	typedef Grid<ParentBuilder>		ThisBuilder;
122 	typedef Group<ThisBuilder>		GroupBuilder;
123 	typedef Grid<ThisBuilder>		GridBuilder;
124 	typedef Split<ThisBuilder>		SplitBuilder;
125 
126 public:
127 	inline						Grid(float horizontal
128 										= B_USE_DEFAULT_SPACING,
129 									float vertical = B_USE_DEFAULT_SPACING);
130 	inline						Grid(BWindow* window,
131 									float horizontal = B_USE_DEFAULT_SPACING,
132 									float vertical = B_USE_DEFAULT_SPACING);
133 	inline						Grid(BView* view,
134 									float horizontal = B_USE_DEFAULT_SPACING,
135 									float vertical = B_USE_DEFAULT_SPACING);
136 	inline						Grid(BGridLayout* layout);
137 	inline						Grid(BGridView* view);
138 
139 	inline	BGridLayout*		Layout() const;
140 	inline	BView*				View() const;
141 	inline	ThisBuilder&		GetLayout(BGridLayout** _layout);
142 	inline	ThisBuilder&		GetView(BView** _view);
143 
144 	inline	ThisBuilder&		Add(BView* view, int32 column, int32 row,
145 									int32 columnCount = 1, int32 rowCount = 1);
146 	inline	ThisBuilder&		Add(BLayoutItem* item, int32 column, int32 row,
147 									int32 columnCount = 1, int32 rowCount = 1);
148 	inline	ThisBuilder&		AddMenuField(BMenuField* menuField,
149 									int32 column, int32 row,
150 									alignment labelAlignment
151 										= B_ALIGN_HORIZONTAL_UNSET,
152 									int32 labelColumnCount = 1,
153 									int32 fieldColumnCount = 1,
154 									int32 rowCount = 1);
155 	inline	ThisBuilder&		AddTextControl(BTextControl* textControl,
156 									int32 column, int32 row,
157 									alignment labelAlignment
158 										= B_ALIGN_HORIZONTAL_UNSET,
159 									int32 labelColumnCount = 1,
160 									int32 textColumnCount = 1,
161 									int32 rowCount = 1);
162 
163 	inline	GroupBuilder		AddGroup(enum orientation orientation,
164 									float spacing, int32 column, int32 row,
165 									int32 columnCount = 1, int32 rowCount = 1);
166 	inline	GroupBuilder		AddGroup(BGroupView* groupView,	int32 column,
167 									int32 row, int32 columnCount = 1,
168 									int32 rowCount = 1);
169 	inline	GroupBuilder		AddGroup(BGroupLayout* groupLayout,
170 									int32 column, int32 row,
171 									int32 columnCount = 1, int32 rowCount = 1);
172 
173 	inline	GridBuilder			AddGrid(float horizontalSpacing,
174 									float verticalSpacing, int32 column,
175 									int32 row, int32 columnCount = 1,
176 									int32 rowCount = 1);
177 	inline	GridBuilder			AddGrid(BGridLayout* gridLayout,
178 									int32 column, int32 row,
179 									int32 columnCount = 1, int32 rowCount = 1);
180 	inline	GridBuilder			AddGrid(BGridView* gridView,
181 									int32 column, int32 row,
182 									int32 columnCount = 1, int32 rowCount = 1);
183 
184 	inline	SplitBuilder		AddSplit(enum orientation orientation,
185 									float spacing, int32 column, int32 row,
186 									int32 columnCount = 1, int32 rowCount = 1);
187 	inline	SplitBuilder		AddSplit(BSplitView* splitView, int32 column,
188 									int32 row, int32 columnCount = 1,
189 									int32 rowCount = 1);
190 
191 	inline	ThisBuilder&		SetColumnWeight(int32 column, float weight);
192 	inline	ThisBuilder&		SetRowWeight(int32 row, float weight);
193 
194 	inline	ThisBuilder&		SetInsets(float left, float top, float right,
195 									float bottom);
196 	inline	ThisBuilder&		SetInsets(float horizontal, float vertical);
197 	inline	ThisBuilder&		SetInsets(float insets);
198 
199 	inline						operator BGridLayout*();
200 
201 private:
202 			BGridLayout*		fLayout;
203 };
204 
205 
206 template<typename ParentBuilder>
207 class Split : public Base<ParentBuilder> {
208 public:
209 	typedef Split<ParentBuilder>	ThisBuilder;
210 	typedef Group<ThisBuilder>		GroupBuilder;
211 	typedef Grid<ThisBuilder>		GridBuilder;
212 	typedef Split<ThisBuilder>		SplitBuilder;
213 
214 public:
215 	inline						Split(enum orientation orientation
216 										= B_HORIZONTAL,
217 									float spacing = B_USE_DEFAULT_SPACING);
218 	inline						Split(BSplitView* view);
219 
220 	inline	BSplitView*			View() const;
221 	inline	ThisBuilder&		GetView(BView** _view);
222 	inline	ThisBuilder&		GetSplitView(BSplitView** _view);
223 
224 	inline	ThisBuilder&		Add(BView* view);
225 	inline	ThisBuilder&		Add(BView* view, float weight);
226 	inline	ThisBuilder&		Add(BLayoutItem* item);
227 	inline	ThisBuilder&		Add(BLayoutItem* item, float weight);
228 
229 	inline	GroupBuilder		AddGroup(enum orientation orientation,
230 									float spacing = B_USE_DEFAULT_SPACING,
231 									float weight = 1.0f);
232 	inline	GroupBuilder		AddGroup(BGroupView* groupView,
233 									float weight = 1.0f);
234 	inline	GroupBuilder		AddGroup(BGroupLayout* groupLayout,
235 									float weight = 1.0f);
236 
237 	inline	GridBuilder			AddGrid(float horizontal
238 											= B_USE_DEFAULT_SPACING,
239 									float vertical = B_USE_DEFAULT_SPACING,
240 									float weight = 1.0f);
241 	inline	GridBuilder			AddGrid(BGridView* gridView,
242 									float weight = 1.0f);
243 	inline	GridBuilder			AddGrid(BGridLayout* gridLayout,
244 									float weight = 1.0f);
245 
246 	inline	SplitBuilder		AddSplit(enum orientation orientation,
247 									float spacing = B_USE_DEFAULT_SPACING,
248 									float weight = 1.0f);
249 	inline	SplitBuilder		AddSplit(BSplitView* splitView,
250 									float weight = 1.0f);
251 
252 	inline	ThisBuilder&		SetCollapsible(bool collapsible);
253 	inline	ThisBuilder&		SetCollapsible(int32 index, bool collapsible);
254 	inline	ThisBuilder&		SetCollapsible(int32 first, int32 last,
255 									bool collapsible);
256 
257 	inline	ThisBuilder&		SetInsets(float left, float top, float right,
258 									float bottom);
259 	inline	ThisBuilder&		SetInsets(float horizontal, float vertical);
260 	inline	ThisBuilder&		SetInsets(float insets);
261 
262 	inline						operator BSplitView*();
263 
264 private:
265 			BSplitView*			fView;
266 };
267 
268 
269 template<typename ParentBuilder>
270 class Menu : public Base<ParentBuilder> {
271 public:
272 	typedef Menu<ParentBuilder>		ThisBuilder;
273 	typedef MenuItem<ParentBuilder>	ItemBuilder;
274 	typedef Menu<ThisBuilder>		MenuBuilder;
275 
276 public:
277 	inline						Menu(BMenu* menu);
278 
279 	inline	ThisBuilder&		GetMenu(BMenu*& _menu);
280 
281 	inline	ItemBuilder			AddItem(BMenuItem* item);
282 	inline	ItemBuilder			AddItem(BMenu* menu);
283 	inline	ItemBuilder			AddItem(const char* label, BMessage* message,
284 									char shortcut = 0, uint32 modifiers = 0);
285 	inline	ItemBuilder			AddItem(const char* label, uint32 messageWhat,
286 									char shortcut = 0, uint32 modifiers = 0);
287 
288 	inline	MenuBuilder			AddMenu(BMenu* menu);
289 	inline	MenuBuilder			AddMenu(const char* title,
290 									menu_layout layout = B_ITEMS_IN_COLUMN);
291 
292 	inline	ThisBuilder&		AddSeparator();
293 
294 private:
295 			BMenu*				fMenu;
296 };
297 
298 
299 template<typename ParentBuilder>
300 class MenuItem : public Menu<ParentBuilder> {
301 public:
302 	typedef MenuItem<ParentBuilder>	ThisBuilder;
303 
304 public:
305 	inline						MenuItem(ParentBuilder* parentBuilder,
306 									BMenu* menu, BMenuItem* item);
307 
308 	inline	ThisBuilder&		GetItem(BMenuItem*& _item);
309 
310 	inline	ThisBuilder&		SetEnabled(bool enabled);
311 
312 private:
313 			BMenuItem*			fMenuItem;
314 };
315 
316 
317 // #pragma mark - Base
318 
319 
320 template<typename ParentBuilder>
321 Base<ParentBuilder>::Base()
322 	:
323 	fParent(NULL)
324 {
325 }
326 
327 
328 template<typename ParentBuilder>
329 void
330 Base<ParentBuilder>::SetParent(ParentBuilder* parent)
331 {
332 	fParent = parent;
333 }
334 
335 
336 template<typename ParentBuilder>
337 ParentBuilder&
338 Base<ParentBuilder>::End()
339 {
340 	return *fParent;
341 }
342 
343 
344 // #pragma mark - Group
345 
346 
347 template<typename ParentBuilder>
348 Group<ParentBuilder>::Group(enum orientation orientation, float spacing)
349 	:
350 	fLayout((new BGroupView(orientation, spacing))->GroupLayout())
351 {
352 }
353 
354 
355 template<typename ParentBuilder>
356 Group<ParentBuilder>::Group(BWindow* window, enum orientation orientation,
357 	float spacing)
358 	:
359 	fLayout(new BGroupLayout(orientation, spacing))
360 {
361 	window->SetLayout(fLayout);
362 
363 	fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
364 		// TODO: we get a white background if we don't do this
365 }
366 
367 
368 template<typename ParentBuilder>
369 Group<ParentBuilder>::Group(BView* view, enum orientation orientation,
370 	float spacing)
371 	:
372 	fLayout(new BGroupLayout(orientation, spacing))
373 {
374 	view->SetLayout(fLayout);
375 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
376 		// TODO: we get a white background if we don't do this
377 }
378 
379 
380 template<typename ParentBuilder>
381 Group<ParentBuilder>::Group(BGroupLayout* layout)
382 	:
383 	fLayout(layout)
384 {
385 }
386 
387 
388 template<typename ParentBuilder>
389 Group<ParentBuilder>::Group(BGroupView* view)
390 	:
391 	fLayout(view->GroupLayout())
392 {
393 }
394 
395 
396 template<typename ParentBuilder>
397 BGroupLayout*
398 Group<ParentBuilder>::Layout() const
399 {
400 	return fLayout;
401 }
402 
403 
404 template<typename ParentBuilder>
405 BView*
406 Group<ParentBuilder>::View() const
407 {
408 	return fLayout->Owner();
409 }
410 
411 
412 template<typename ParentBuilder>
413 typename Group<ParentBuilder>::ThisBuilder&
414 Group<ParentBuilder>::GetLayout(BGroupLayout** _layout)
415 {
416 	*_layout = fLayout;
417 	return *this;
418 }
419 
420 
421 template<typename ParentBuilder>
422 typename Group<ParentBuilder>::ThisBuilder&
423 Group<ParentBuilder>::GetView(BView** _view)
424 {
425 	*_view = fLayout->Owner();
426 	return *this;
427 }
428 
429 
430 template<typename ParentBuilder>
431 typename Group<ParentBuilder>::ThisBuilder&
432 Group<ParentBuilder>::Add(BView* view)
433 {
434 	fLayout->AddView(view);
435 	return *this;
436 }
437 
438 
439 template<typename ParentBuilder>
440 typename Group<ParentBuilder>::ThisBuilder&
441 Group<ParentBuilder>::Add(BView* view, float weight)
442 {
443 	fLayout->AddView(view, weight);
444 	return *this;
445 }
446 
447 
448 template<typename ParentBuilder>
449 typename Group<ParentBuilder>::ThisBuilder&
450 Group<ParentBuilder>::Add(BLayoutItem* item)
451 {
452 	fLayout->AddItem(item);
453 	return *this;
454 }
455 
456 
457 template<typename ParentBuilder>
458 typename Group<ParentBuilder>::ThisBuilder&
459 Group<ParentBuilder>::Add(BLayoutItem* item, float weight)
460 {
461 	fLayout->AddItem(item, weight);
462 	return *this;
463 }
464 
465 
466 template<typename ParentBuilder>
467 typename Group<ParentBuilder>::GroupBuilder
468 Group<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
469 	float weight)
470 {
471 	GroupBuilder builder(new BGroupLayout(orientation, spacing));
472 	builder.SetParent(this);
473 	fLayout->AddItem(builder.Layout(), weight);
474 	return builder;
475 }
476 
477 
478 template<typename ParentBuilder>
479 typename Group<ParentBuilder>::GroupBuilder
480 Group<ParentBuilder>::AddGroup(BGroupView* groupView, float weight)
481 {
482 	GroupBuilder builder(groupView);
483 	builder.SetParent(this);
484 	fLayout->AddItem(builder.Layout(), weight);
485 	return builder;
486 }
487 
488 
489 template<typename ParentBuilder>
490 typename Group<ParentBuilder>::GroupBuilder
491 Group<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight)
492 {
493 	GroupBuilder builder(groupLayout);
494 	builder.SetParent(this);
495 	fLayout->AddItem(builder.Layout(), weight);
496 	return builder;
497 }
498 
499 
500 template<typename ParentBuilder>
501 typename Group<ParentBuilder>::GridBuilder
502 Group<ParentBuilder>::AddGrid(float horizontalSpacing,
503 	float verticalSpacing, float weight)
504 {
505 	GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
506 	builder.SetParent(this);
507 	fLayout->AddItem(builder.Layout(), weight);
508 	return builder;
509 }
510 
511 
512 template<typename ParentBuilder>
513 typename Group<ParentBuilder>::GridBuilder
514 Group<ParentBuilder>::AddGrid(BGridLayout* gridLayout, float weight)
515 {
516 	GridBuilder builder(gridLayout);
517 	builder.SetParent(this);
518 	fLayout->AddItem(builder.Layout(), weight);
519 	return builder;
520 }
521 
522 
523 template<typename ParentBuilder>
524 typename Group<ParentBuilder>::GridBuilder
525 Group<ParentBuilder>::AddGrid(BGridView* gridView, float weight)
526 {
527 	GridBuilder builder(gridView);
528 	builder.SetParent(this);
529 	fLayout->AddItem(builder.Layout(), weight);
530 	return builder;
531 }
532 
533 
534 template<typename ParentBuilder>
535 typename Group<ParentBuilder>::SplitBuilder
536 Group<ParentBuilder>::AddSplit(enum orientation orientation, float spacing,
537 	float weight)
538 {
539 	SplitBuilder builder(orientation, spacing);
540 	builder.SetParent(this);
541 	fLayout->AddView(builder.View(), weight);
542 	return builder;
543 }
544 
545 
546 template<typename ParentBuilder>
547 typename Group<ParentBuilder>::SplitBuilder
548 Group<ParentBuilder>::AddSplit(BSplitView* splitView, float weight)
549 {
550 	SplitBuilder builder(splitView);
551 	builder.SetParent(this);
552 	fLayout->AddView(builder.View(), weight);
553 	return builder;
554 }
555 
556 
557 template<typename ParentBuilder>
558 typename Group<ParentBuilder>::ThisBuilder&
559 Group<ParentBuilder>::AddGlue(float weight)
560 {
561 	fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), weight);
562 	return *this;
563 }
564 
565 
566 template<typename ParentBuilder>
567 typename Group<ParentBuilder>::ThisBuilder&
568 Group<ParentBuilder>::AddStrut(float size)
569 {
570 	if (fLayout->Orientation() == B_HORIZONTAL)
571 		fLayout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(size));
572 	else
573 		fLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(size));
574 
575 	return *this;
576 }
577 
578 
579 template<typename ParentBuilder>
580 typename Group<ParentBuilder>::ThisBuilder&
581 Group<ParentBuilder>::SetInsets(float left, float top, float right,
582 	float bottom)
583 {
584 	fLayout->SetInsets(left, top, right, bottom);
585 	return *this;
586 }
587 
588 
589 template<typename ParentBuilder>
590 typename Group<ParentBuilder>::ThisBuilder&
591 Group<ParentBuilder>::SetInsets(float horizontal, float vertical)
592 {
593 	fLayout->SetInsets(horizontal, vertical);
594 	return *this;
595 }
596 
597 
598 template<typename ParentBuilder>
599 typename Group<ParentBuilder>::ThisBuilder&
600 Group<ParentBuilder>::SetInsets(float insets)
601 {
602 	fLayout->SetInsets(insets);
603 	return *this;
604 }
605 
606 
607 template<typename ParentBuilder>
608 Group<ParentBuilder>::operator BGroupLayout*()
609 {
610 	return fLayout;
611 }
612 
613 
614 // #pragma mark - Grid
615 
616 
617 template<typename ParentBuilder>
618 Grid<ParentBuilder>::Grid(float horizontalSpacing, float verticalSpacing)
619 	:
620 	fLayout((new BGridView(horizontalSpacing, verticalSpacing))->GridLayout())
621 {
622 }
623 
624 
625 template<typename ParentBuilder>
626 Grid<ParentBuilder>::Grid(BWindow* window, float horizontalSpacing,
627 	float verticalSpacing)
628 	:
629 	fLayout(new BGridLayout(horizontalSpacing, verticalSpacing))
630 {
631 	window->SetLayout(fLayout);
632 
633 	fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
634 		// TODO: we get a white background if we don't do this
635 }
636 
637 
638 template<typename ParentBuilder>
639 Grid<ParentBuilder>::Grid(BView* view, float horizontalSpacing,
640 	float verticalSpacing)
641 	:
642 	fLayout(new BGridLayout(horizontalSpacing, verticalSpacing))
643 {
644 	view->SetLayout(fLayout);
645 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
646 		// TODO: we get a white background if we don't do this
647 }
648 
649 
650 template<typename ParentBuilder>
651 Grid<ParentBuilder>::Grid(BGridLayout* layout)
652 	:
653 	fLayout(layout)
654 {
655 }
656 
657 
658 template<typename ParentBuilder>
659 Grid<ParentBuilder>::Grid(BGridView* view)
660 	:
661 	fLayout(view->GridLayout())
662 {
663 }
664 
665 
666 template<typename ParentBuilder>
667 BGridLayout*
668 Grid<ParentBuilder>::Layout() const
669 {
670 	return fLayout;
671 }
672 
673 
674 template<typename ParentBuilder>
675 BView*
676 Grid<ParentBuilder>::View() const
677 {
678 	return fLayout->Owner();
679 }
680 
681 
682 template<typename ParentBuilder>
683 typename Grid<ParentBuilder>::ThisBuilder&
684 Grid<ParentBuilder>::GetLayout(BGridLayout** _layout)
685 {
686 	*_layout = fLayout;
687 	return *this;
688 }
689 
690 
691 template<typename ParentBuilder>
692 typename Grid<ParentBuilder>::ThisBuilder&
693 Grid<ParentBuilder>::GetView(BView** _view)
694 {
695 	*_view = fLayout->Owner();
696 	return *this;
697 }
698 
699 
700 template<typename ParentBuilder>
701 typename Grid<ParentBuilder>::ThisBuilder&
702 Grid<ParentBuilder>::Add(BView* view, int32 column, int32 row,
703 	int32 columnCount, int32 rowCount)
704 {
705 	fLayout->AddView(view, column, row, columnCount, rowCount);
706 	return *this;
707 }
708 
709 
710 template<typename ParentBuilder>
711 typename Grid<ParentBuilder>::ThisBuilder&
712 Grid<ParentBuilder>::Add(BLayoutItem* item, int32 column, int32 row,
713 	int32 columnCount, int32 rowCount)
714 {
715 	fLayout->AddItem(item, column, row, columnCount, rowCount);
716 	return *this;
717 }
718 
719 
720 template<typename ParentBuilder>
721 typename Grid<ParentBuilder>::ThisBuilder&
722 Grid<ParentBuilder>::AddMenuField(BMenuField* menuField, int32 column,
723 	int32 row, alignment labelAlignment, int32 labelColumnCount,
724 	int32 fieldColumnCount, int32 rowCount)
725 {
726 	BLayoutItem* item = menuField->CreateLabelLayoutItem();
727 	item->SetExplicitAlignment(
728 		BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET));
729 	fLayout->AddItem(item, column, row, labelColumnCount, rowCount);
730 	fLayout->AddItem(menuField->CreateMenuBarLayoutItem(),
731 		column + labelColumnCount, row, fieldColumnCount, rowCount);
732 	return *this;
733 }
734 
735 
736 template<typename ParentBuilder>
737 typename Grid<ParentBuilder>::ThisBuilder&
738 Grid<ParentBuilder>::AddTextControl(BTextControl* textControl, int32 column,
739 	int32 row, alignment labelAlignment, int32 labelColumnCount,
740 	int32 textColumnCount, int32 rowCount)
741 {
742 	BLayoutItem* item = textControl->CreateLabelLayoutItem();
743 	item->SetExplicitAlignment(
744 		BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET));
745 	fLayout->AddItem(item, column, row, labelColumnCount, rowCount);
746 	fLayout->AddItem(textControl->CreateTextViewLayoutItem(),
747 		column + labelColumnCount, row, textColumnCount, rowCount);
748 	return *this;
749 }
750 
751 
752 template<typename ParentBuilder>
753 typename Grid<ParentBuilder>::GroupBuilder
754 Grid<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
755 	int32 column, int32 row, int32 columnCount, int32 rowCount)
756 {
757 	GroupBuilder builder(new BGroupLayout(orientation, spacing));
758 	builder.SetParent(this);
759 	fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
760 	return builder;
761 }
762 
763 
764 template<typename ParentBuilder>
765 typename Grid<ParentBuilder>::GroupBuilder
766 Grid<ParentBuilder>::AddGroup(BGroupView* groupView, int32 column, int32 row,
767 	int32 columnCount, int32 rowCount)
768 {
769 	GroupBuilder builder(groupView);
770 	builder.SetParent(this);
771 	fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
772 	return builder;
773 }
774 
775 
776 template<typename ParentBuilder>
777 typename Grid<ParentBuilder>::GroupBuilder
778 Grid<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, int32 column,
779 	int32 row, int32 columnCount, int32 rowCount)
780 {
781 	GroupBuilder builder(groupLayout);
782 	builder.SetParent(this);
783 	fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
784 	return builder;
785 }
786 
787 
788 template<typename ParentBuilder>
789 typename Grid<ParentBuilder>::GridBuilder
790 Grid<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
791 	int32 column, int32 row, int32 columnCount, int32 rowCount)
792 {
793 	GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
794 	builder.SetParent(this);
795 	fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount);
796 	return builder;
797 }
798 
799 
800 template<typename ParentBuilder>
801 typename Grid<ParentBuilder>::GridBuilder
802 Grid<ParentBuilder>::AddGrid(BGridView* gridView, int32 column, int32 row,
803 	int32 columnCount, int32 rowCount)
804 {
805 	GridBuilder builder(gridView);
806 	builder.SetParent(this);
807 	fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
808 	return builder;
809 }
810 
811 
812 template<typename ParentBuilder>
813 typename Grid<ParentBuilder>::SplitBuilder
814 Grid<ParentBuilder>::AddSplit(enum orientation orientation, float spacing,
815 	int32 column, int32 row, int32 columnCount, int32 rowCount)
816 {
817 	SplitBuilder builder(orientation, spacing);
818 	builder.SetParent(this);
819 	fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
820 	return builder;
821 }
822 
823 
824 template<typename ParentBuilder>
825 typename Grid<ParentBuilder>::SplitBuilder
826 Grid<ParentBuilder>::AddSplit(BSplitView* splitView, int32 column, int32 row,
827 	int32 columnCount, int32 rowCount)
828 {
829 	SplitBuilder builder(splitView);
830 	builder.SetParent(this);
831 	fLayout->AddView(builder.View(), column, row, columnCount, rowCount);
832 	return builder;
833 }
834 
835 
836 template<typename ParentBuilder>
837 typename Grid<ParentBuilder>::ThisBuilder&
838 Grid<ParentBuilder>::SetColumnWeight(int32 column, float weight)
839 {
840 	fLayout->SetColumnWeight(column, weight);
841 	return *this;
842 }
843 
844 
845 template<typename ParentBuilder>
846 typename Grid<ParentBuilder>::ThisBuilder&
847 Grid<ParentBuilder>::SetRowWeight(int32 row, float weight)
848 {
849 	fLayout->SetRowWeight(row, weight);
850 	return *this;
851 }
852 
853 
854 template<typename ParentBuilder>
855 typename Grid<ParentBuilder>::ThisBuilder&
856 Grid<ParentBuilder>::SetInsets(float left, float top, float right,
857 	float bottom)
858 {
859 	fLayout->SetInsets(left, top, right, bottom);
860 	return *this;
861 }
862 
863 
864 template<typename ParentBuilder>
865 typename Grid<ParentBuilder>::ThisBuilder&
866 Grid<ParentBuilder>::SetInsets(float horizontal, float vertical)
867 {
868 	fLayout->SetInsets(horizontal, vertical);
869 	return *this;
870 }
871 
872 
873 template<typename ParentBuilder>
874 typename Grid<ParentBuilder>::ThisBuilder&
875 Grid<ParentBuilder>::SetInsets(float insets)
876 {
877 	fLayout->SetInsets(insets);
878 	return *this;
879 }
880 
881 
882 template<typename ParentBuilder>
883 Grid<ParentBuilder>::operator BGridLayout*()
884 {
885 	return fLayout;
886 }
887 
888 
889 // #pragma mark - Split
890 
891 
892 template<typename ParentBuilder>
893 Split<ParentBuilder>::Split(enum orientation orientation, float spacing)
894 	:
895 	fView(new BSplitView(orientation, spacing))
896 {
897 }
898 
899 
900 template<typename ParentBuilder>
901 Split<ParentBuilder>::Split(BSplitView* view)
902 	:
903 	fView(view)
904 {
905 }
906 
907 
908 template<typename ParentBuilder>
909 BSplitView*
910 Split<ParentBuilder>::View() const
911 {
912 	return fView;
913 }
914 
915 
916 template<typename ParentBuilder>
917 typename Split<ParentBuilder>::ThisBuilder&
918 Split<ParentBuilder>::GetView(BView** _view)
919 {
920 	*_view = fView;
921 	return *this;
922 }
923 
924 
925 template<typename ParentBuilder>
926 typename Split<ParentBuilder>::ThisBuilder&
927 Split<ParentBuilder>::GetSplitView(BSplitView** _view)
928 {
929 	*_view = fView;
930 	return *this;
931 }
932 
933 
934 template<typename ParentBuilder>
935 typename Split<ParentBuilder>::ThisBuilder&
936 Split<ParentBuilder>::Add(BView* view)
937 {
938 	fView->AddChild(view);
939 	return *this;
940 }
941 
942 
943 template<typename ParentBuilder>
944 typename Split<ParentBuilder>::ThisBuilder&
945 Split<ParentBuilder>::Add(BView* view, float weight)
946 {
947 	fView->AddChild(view, weight);
948 	return *this;
949 }
950 
951 
952 template<typename ParentBuilder>
953 typename Split<ParentBuilder>::ThisBuilder&
954 Split<ParentBuilder>::Add(BLayoutItem* item)
955 {
956 	fView->AddChild(item);
957 	return *this;
958 }
959 
960 
961 template<typename ParentBuilder>
962 typename Split<ParentBuilder>::ThisBuilder&
963 Split<ParentBuilder>::Add(BLayoutItem* item, float weight)
964 {
965 	fView->AddChild(item, weight);
966 	return *this;
967 }
968 
969 
970 template<typename ParentBuilder>
971 typename Split<ParentBuilder>::GroupBuilder
972 Split<ParentBuilder>::AddGroup(enum orientation orientation, float spacing,
973 	float weight)
974 {
975 	GroupBuilder builder(new BGroupLayout(orientation, spacing));
976 	builder.SetParent(this);
977 	fView->AddChild(builder.Layout(), weight);
978 	return builder;
979 }
980 
981 
982 template<typename ParentBuilder>
983 typename Split<ParentBuilder>::GroupBuilder
984 Split<ParentBuilder>::AddGroup(BGroupView* groupView, float weight)
985 {
986 	GroupBuilder builder(groupView);
987 	builder.SetParent(this);
988 	fView->AddChild(builder.Layout(), weight);
989 	return builder;
990 }
991 
992 
993 template<typename ParentBuilder>
994 typename Split<ParentBuilder>::GroupBuilder
995 Split<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight)
996 {
997 	GroupBuilder builder(groupLayout);
998 	builder.SetParent(this);
999 	fView->AddChild(builder.Layout(), weight);
1000 	return builder;
1001 }
1002 
1003 
1004 template<typename ParentBuilder>
1005 typename Split<ParentBuilder>::GridBuilder
1006 Split<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing,
1007 	float weight)
1008 {
1009 	GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing));
1010 	builder.SetParent(this);
1011 	fView->AddChild(builder.Layout(), weight);
1012 	return builder;
1013 }
1014 
1015 
1016 template<typename ParentBuilder>
1017 typename Split<ParentBuilder>::GridBuilder
1018 Split<ParentBuilder>::AddGrid(BGridView* gridView, float weight)
1019 {
1020 	GridBuilder builder(gridView);
1021 	builder.SetParent(this);
1022 	fView->AddChild(builder.Layout(), weight);
1023 	return builder;
1024 }
1025 
1026 
1027 template<typename ParentBuilder>
1028 typename Split<ParentBuilder>::GridBuilder
1029 Split<ParentBuilder>::AddGrid(BGridLayout* layout, float weight)
1030 {
1031 	GridBuilder builder(layout);
1032 	builder.SetParent(this);
1033 	fView->AddChild(builder.Layout(), weight);
1034 	return builder;
1035 }
1036 
1037 
1038 template<typename ParentBuilder>
1039 typename Split<ParentBuilder>::SplitBuilder
1040 Split<ParentBuilder>::AddSplit(enum orientation orientation, float spacing,
1041 	float weight)
1042 {
1043 	SplitBuilder builder(orientation, spacing);
1044 	builder.SetParent(this);
1045 	fView->AddChild(builder.View(), weight);
1046 	return builder;
1047 }
1048 
1049 
1050 template<typename ParentBuilder>
1051 typename Split<ParentBuilder>::ThisBuilder&
1052 Split<ParentBuilder>::SetCollapsible(bool collapsible)
1053 {
1054 	fView->SetCollapsible(collapsible);
1055 	return *this;
1056 }
1057 
1058 
1059 template<typename ParentBuilder>
1060 typename Split<ParentBuilder>::ThisBuilder&
1061 Split<ParentBuilder>::SetCollapsible(int32 index, bool collapsible)
1062 {
1063 	fView->SetCollapsible(index, collapsible);
1064 	return *this;
1065 }
1066 
1067 
1068 template<typename ParentBuilder>
1069 typename Split<ParentBuilder>::ThisBuilder&
1070 Split<ParentBuilder>::SetCollapsible(int32 first, int32 last, bool collapsible)
1071 {
1072 	fView->SetCollapsible(first, last, collapsible);
1073 	return *this;
1074 }
1075 
1076 
1077 template<typename ParentBuilder>
1078 typename Split<ParentBuilder>::ThisBuilder&
1079 Split<ParentBuilder>::SetInsets(float left, float top, float right,
1080 	float bottom)
1081 {
1082 	fView->SetInsets(left, top, right, bottom);
1083 	return *this;
1084 }
1085 
1086 
1087 template<typename ParentBuilder>
1088 typename Split<ParentBuilder>::ThisBuilder&
1089 Split<ParentBuilder>::SetInsets(float horizontal, float vertical)
1090 {
1091 	fView->SetInsets(horizontal, vertical);
1092 	return *this;
1093 }
1094 
1095 
1096 template<typename ParentBuilder>
1097 typename Split<ParentBuilder>::ThisBuilder&
1098 Split<ParentBuilder>::SetInsets(float insets)
1099 {
1100 	fView->SetInsets(insets);
1101 	return *this;
1102 }
1103 
1104 
1105 template<typename ParentBuilder>
1106 Split<ParentBuilder>::operator BSplitView*()
1107 {
1108 	return fView;
1109 }
1110 
1111 
1112 // #pragma mark - Menu
1113 
1114 
1115 template<typename ParentBuilder>
1116 Menu<ParentBuilder>::Menu(BMenu* menu)
1117 	:
1118 	fMenu(menu)
1119 {
1120 }
1121 
1122 
1123 template<typename ParentBuilder>
1124 typename Menu<ParentBuilder>::ThisBuilder&
1125 Menu<ParentBuilder>::GetMenu(BMenu*& _menu)
1126 {
1127 	_menu = fMenu;
1128 	return *this;
1129 }
1130 
1131 
1132 template<typename ParentBuilder>
1133 typename Menu<ParentBuilder>::ItemBuilder
1134 Menu<ParentBuilder>::AddItem(BMenuItem* item)
1135 {
1136 	fMenu->AddItem(item);
1137 	return MenuItem<ParentBuilder>(this->fParent, fMenu, item);
1138 }
1139 
1140 
1141 template<typename ParentBuilder>
1142 typename Menu<ParentBuilder>::ItemBuilder
1143 Menu<ParentBuilder>::AddItem(BMenu* menu)
1144 {
1145 	if (!fMenu->AddItem(menu))
1146 		throw std::bad_alloc();
1147 
1148 	return MenuItem<ParentBuilder>(this->fParent, fMenu,
1149 		fMenu->ItemAt(fMenu->CountItems() - 1));
1150 }
1151 
1152 
1153 template<typename ParentBuilder>
1154 typename Menu<ParentBuilder>::ItemBuilder
1155 Menu<ParentBuilder>::AddItem(const char* label, BMessage* message,
1156 	char shortcut, uint32 modifiers)
1157 {
1158 	BMenuItem* item = new BMenuItem(label, message, shortcut, modifiers);
1159 	if (!fMenu->AddItem(item))
1160 		delete item;
1161 
1162 	return MenuItem<ParentBuilder>(this->fParent, fMenu, item);
1163 }
1164 
1165 
1166 template<typename ParentBuilder>
1167 typename Menu<ParentBuilder>::ItemBuilder
1168 Menu<ParentBuilder>::AddItem(const char* label, uint32 messageWhat,
1169 	char shortcut, uint32 modifiers)
1170 {
1171 	BMessage* message = new BMessage(messageWhat);
1172 	BMenuItem* item;
1173 	try {
1174 		item = new BMenuItem(label, message, shortcut, modifiers);
1175 	} catch (...) {
1176 		delete message;
1177 		throw;
1178 	}
1179 
1180 	if (!fMenu->AddItem(item))
1181 		delete item;
1182 
1183 	return MenuItem<ParentBuilder>(this->fParent, fMenu, item);
1184 }
1185 
1186 
1187 template<typename ParentBuilder>
1188 typename Menu<ParentBuilder>::ThisBuilder&
1189 Menu<ParentBuilder>::AddSeparator()
1190 {
1191 	fMenu->AddSeparatorItem();
1192 	return *this;
1193 }
1194 
1195 
1196 template<typename ParentBuilder>
1197 typename Menu<ParentBuilder>::MenuBuilder
1198 Menu<ParentBuilder>::AddMenu(BMenu* menu)
1199 {
1200 	if (!fMenu->AddItem(menu))
1201 		throw std::bad_alloc();
1202 
1203 	MenuBuilder builder(menu);
1204 	builder.SetParent(this);
1205 	return builder;
1206 }
1207 
1208 
1209 template<typename ParentBuilder>
1210 typename Menu<ParentBuilder>::MenuBuilder
1211 Menu<ParentBuilder>::AddMenu(const char* title, menu_layout layout)
1212 {
1213 	BMenu* menu = new BMenu(title, layout);
1214 	if (!fMenu->AddItem(menu)) {
1215 		delete menu;
1216 		throw std::bad_alloc();
1217 	}
1218 
1219 	MenuBuilder builder(menu);
1220 	builder.SetParent(this);
1221 	return builder;
1222 }
1223 
1224 
1225 // #pragma mark - MenuItem
1226 
1227 
1228 template<typename ParentBuilder>
1229 MenuItem<ParentBuilder>::MenuItem(ParentBuilder* parentBuilder, BMenu* menu,
1230 	BMenuItem* item)
1231 	:
1232 	Menu<ParentBuilder>(menu),
1233 	fMenuItem(item)
1234 {
1235 	SetParent(parentBuilder);
1236 }
1237 
1238 
1239 template<typename ParentBuilder>
1240 typename MenuItem<ParentBuilder>::ThisBuilder&
1241 MenuItem<ParentBuilder>::GetItem(BMenuItem*& _item)
1242 {
1243 	_item = fMenuItem;
1244 	return *this;
1245 }
1246 
1247 
1248 template<typename ParentBuilder>
1249 typename MenuItem<ParentBuilder>::ThisBuilder&
1250 MenuItem<ParentBuilder>::SetEnabled(bool enabled)
1251 {
1252 	fMenuItem->SetEnabled(enabled);
1253 	return *this;
1254 }
1255 
1256 
1257 }	// namespace BLayoutBuilder
1258 
1259 
1260 #endif	// _LAYOUT_BUILDER_H
1261