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