xref: /haiku/src/apps/icon-o-matic/generic/gui/Group.cpp (revision bab64f65bb775dc23060e276f1f1c4498ab7af6c)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "Group.h"
10 
11 #include <stdio.h>
12 
13 // constructor
Group(BRect frame,const char * name,orientation direction)14 Group::Group(BRect frame, const char* name, orientation direction)
15 	: BView(frame, name, B_FOLLOW_ALL, B_FRAME_EVENTS),
16 	  fOrientation(direction),
17 	  fInset(4.0),
18 	  fSpacing(0.0)
19 {
20 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
21 }
22 
23 // destructor
~Group()24 Group::~Group()
25 {
26 }
27 
28 // AttachedToWindow
29 void
AttachedToWindow()30 Group::AttachedToWindow()
31 {
32 	// trigger a layout
33 	FrameResized(Bounds().Width(), Bounds().Height());
34 }
35 
36 // FrameResized
37 void
FrameResized(float width,float height)38 Group::FrameResized(float width, float height)
39 {
40 	// layout controls
41 	BRect r(Bounds());
42 	r.InsetBy(fInset, fInset);
43 	_LayoutControls(r);
44 }
45 
46 // GetPreferredSize
47 void
GetPreferredSize(float * width,float * height)48 Group::GetPreferredSize(float* width, float* height)
49 {
50 	BRect r(_MinFrame());
51 
52 	if (width)
53 		*width = r.Width();
54 	if (height)
55 		*height = r.Height();
56 }
57 
58 // #pragma mark -
59 
60 void
SetSpacing(float insetFromBorder,float childSpacing)61 Group::SetSpacing(float insetFromBorder, float childSpacing)
62 {
63 	if (fSpacing == childSpacing && fInset == insetFromBorder)
64 		return;
65 
66 	fInset = insetFromBorder;
67 	fSpacing = childSpacing;
68 	// trigger a layout
69 	FrameResized(Bounds().Width(), Bounds().Height());
70 }
71 
72 // #pragma mark -
73 
74 // _LayoutControls
75 void
_LayoutControls(BRect r) const76 Group::_LayoutControls(BRect r) const
77 {
78 	if (fOrientation == B_HORIZONTAL) {
79 		r.left -= fSpacing;
80 		for (int32 i = 0; BView* child = ChildAt(i); i++) {
81 			r.right = r.left + child->Bounds().Width() + 2 * fSpacing;
82 			_LayoutControl(child, r);
83 			r.left = r.right + 1.0 - fSpacing;
84 		}
85 	} else {
86 		r.top -= fSpacing;
87 		for (int32 i = 0; BView* child = ChildAt(i); i++) {
88 			r.bottom = r.top + child->Bounds().Height() + 2 * fSpacing;
89 			_LayoutControl(child, r);
90 			r.top = r.bottom + 1.0 - fSpacing;
91 		}
92 	}
93 }
94 
95 // _MinFrame
96 BRect
_MinFrame() const97 Group::_MinFrame() const
98 {
99 	float minWidth = fInset * 2.0;
100 	float minHeight = fInset * 2.0;
101 
102 	if (fOrientation == B_HORIZONTAL) {
103 		minWidth += fSpacing;
104 		for (int32 i = 0; BView* child = ChildAt(i); i++) {
105 			minWidth += child->Bounds().Width() + 1 + fSpacing;
106 			minHeight = max_c(minHeight,
107 							  child->Bounds().Height() + 1 + fInset * 2.0);
108 		}
109 	} else {
110 		minHeight += fSpacing;
111 		for (int32 i = 0; BView* child = ChildAt(i); i++) {
112 			minHeight += child->Bounds().Height() + 1 + fSpacing;
113 			minWidth = max_c(minWidth,
114 							 child->Bounds().Width() + 1 + fInset * 2.0);
115 		}
116 	}
117 
118 	return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0);
119 }
120 
121 // _LayoutControl
122 void
_LayoutControl(BView * view,BRect frame,bool resizeWidth,bool resizeHeight) const123 Group::_LayoutControl(BView* view, BRect frame,
124 					  bool resizeWidth, bool resizeHeight) const
125 {
126 	if (!resizeHeight)
127 		// center vertically
128 		frame.top = (frame.top + frame.bottom) / 2.0 - view->Bounds().Height() / 2.0;
129 	if (!resizeWidth)
130 		// center horizontally
131 		frame.left = (frame.left + frame.right) / 2.0 - view->Bounds().Width() / 2.0;
132 	view->MoveTo(frame.LeftTop());
133 	float width = resizeWidth ? frame.Width() : view->Bounds().Width();
134 	float height = resizeHeight ? frame.Height() : view->Bounds().Height();
135 	if (resizeWidth || resizeHeight)
136 		view->ResizeTo(width, height);
137 }
138 
139