xref: /haiku/src/kits/interface/LayoutItem.cpp (revision 204dee708a999d5a71d0cb9497650ee7cef85d0a)
1 /*
2  * Copyright 2010-2012, Haiku, Inc.
3  * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
4  * All rights reserved. Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include <LayoutItem.h>
9 
10 #include <Layout.h>
11 #include <LayoutUtils.h>
12 #include <View.h>
13 #include <ViewPrivate.h>
14 
15 #include <algorithm>
16 
17 
18 BLayoutItem::BLayoutItem()
19 	:
20 	fLayout(NULL),
21 	fLayoutData(NULL)
22 {
23 }
24 
25 
26 BLayoutItem::BLayoutItem(BMessage* from)
27 	:
28 	BArchivable(BUnarchiver::PrepareArchive(from)),
29 	fLayout(NULL),
30 	fLayoutData(NULL)
31 {
32 	BUnarchiver(from).Finish();
33 }
34 
35 
36 BLayoutItem::~BLayoutItem()
37 {
38 	if (fLayout)
39 		fLayout->RemoveItem(this);
40 }
41 
42 
43 BLayout*
44 BLayoutItem::Layout() const
45 {
46 	return fLayout;
47 }
48 
49 
50 void
51 BLayoutItem::SetExplicitSize(BSize size)
52 {
53 	SetExplicitMinSize(size);
54 	SetExplicitMaxSize(size);
55 	SetExplicitPreferredSize(size);
56 }
57 
58 
59 bool
60 BLayoutItem::HasHeightForWidth()
61 {
62 	// no "height for width" by default
63 	return false;
64 }
65 
66 
67 void
68 BLayoutItem::GetHeightForWidth(float width, float* min, float* max,
69 	float* preferred)
70 {
71 	// no "height for width" by default
72 }
73 
74 
75 BView*
76 BLayoutItem::View()
77 {
78 	return NULL;
79 }
80 
81 
82 void
83 BLayoutItem::InvalidateLayout(bool children)
84 {
85 	LayoutInvalidated(children);
86 	if (fLayout)
87 		fLayout->InvalidateLayout(children);
88 }
89 
90 
91 void
92 BLayoutItem::Relayout(bool immediate)
93 {
94 	BView* view = View();
95 	if (view && !immediate)
96 		view->Relayout();
97 	else if (view && immediate)
98 		view->Layout(false);
99 }
100 
101 
102 void*
103 BLayoutItem::LayoutData() const
104 {
105 	return fLayoutData;
106 }
107 
108 
109 void
110 BLayoutItem::SetLayoutData(void* data)
111 {
112 	fLayoutData = data;
113 }
114 
115 
116 void
117 BLayoutItem::AlignInFrame(BRect frame)
118 {
119 	BSize maxSize = MaxSize();
120 	BAlignment alignment = Alignment();
121 
122 	if (HasHeightForWidth()) {
123 		// The item has height for width, so we do the horizontal alignment
124 		// ourselves and restrict the height max constraint respectively.
125 		if (maxSize.width < frame.Width()
126 			&& alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) {
127 			frame.left += (int)((frame.Width() - maxSize.width)
128 				* alignment.horizontal);
129 			frame.right = frame.left + maxSize.width;
130 		}
131 		alignment.horizontal = B_ALIGN_USE_FULL_WIDTH;
132 
133 		float minHeight;
134 		GetHeightForWidth(frame.Width(), &minHeight, NULL, NULL);
135 
136 		frame.bottom = frame.top + max_c(frame.Height(), minHeight);
137 		maxSize.height = minHeight;
138 	}
139 
140 	SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment));
141 }
142 
143 
144 status_t
145 BLayoutItem::Archive(BMessage* into, bool deep) const
146 {
147 	BArchiver archiver(into);
148 	status_t err = BArchivable::Archive(into, deep);
149 
150 	if (err == B_OK)
151 		err = archiver.Finish();
152 
153 	return err;
154 }
155 
156 
157 status_t
158 BLayoutItem::AllArchived(BMessage* into) const
159 {
160 	BArchiver archiver(into);
161 	return BArchivable::AllArchived(into);
162 }
163 
164 
165 status_t
166 BLayoutItem::AllUnarchived(const BMessage* from)
167 {
168 	return BArchivable::AllUnarchived(from);
169 }
170 
171 
172 void
173 BLayoutItem::SetLayout(BLayout* layout)
174 {
175 	if (layout == fLayout)
176 		return;
177 
178 	BLayout* oldLayout = fLayout;
179 	fLayout = layout;
180 
181 	if (oldLayout)
182 		DetachedFromLayout(oldLayout);
183 
184 	if (BView* view = View()) {
185 		if (oldLayout && !fLayout) {
186 			BView::Private(view).DeregisterLayoutItem(this);
187 		} else if (fLayout && !oldLayout) {
188 			BView::Private(view).RegisterLayoutItem(this);
189 		}
190 	}
191 
192 	if (fLayout)
193 		AttachedToLayout();
194 }
195 
196 
197 status_t
198 BLayoutItem::Perform(perform_code code, void* _data)
199 {
200 	return BArchivable::Perform(code, _data);
201 }
202 
203 
204 void
205 BLayoutItem::LayoutInvalidated(bool children)
206 {
207 	// hook method
208 }
209 
210 
211 void
212 BLayoutItem::AttachedToLayout()
213 {
214 	// hook method
215 }
216 
217 
218 void
219 BLayoutItem::DetachedFromLayout(BLayout* oldLayout)
220 {
221 	// hook method
222 }
223 
224 
225 void
226 BLayoutItem::AncestorVisibilityChanged(bool shown)
227 {
228 	// hook method
229 }
230 
231 
232 // Binary compatibility stuff
233 
234 
235 void BLayoutItem::_ReservedLayoutItem1() {}
236 void BLayoutItem::_ReservedLayoutItem2() {}
237 void BLayoutItem::_ReservedLayoutItem3() {}
238 void BLayoutItem::_ReservedLayoutItem4() {}
239 void BLayoutItem::_ReservedLayoutItem5() {}
240 void BLayoutItem::_ReservedLayoutItem6() {}
241 void BLayoutItem::_ReservedLayoutItem7() {}
242 void BLayoutItem::_ReservedLayoutItem8() {}
243 void BLayoutItem::_ReservedLayoutItem9() {}
244 void BLayoutItem::_ReservedLayoutItem10() {}
245 
246