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
18BLayoutItem::BLayoutItem()
19	:
20	fLayout(NULL),
21	fLayoutData(NULL)
22{
23}
24
25
26BLayoutItem::BLayoutItem(BMessage* from)
27	:
28	BArchivable(BUnarchiver::PrepareArchive(from)),
29	fLayout(NULL),
30	fLayoutData(NULL)
31{
32	BUnarchiver(from).Finish();
33}
34
35
36BLayoutItem::~BLayoutItem()
37{
38	if (fLayout)
39		fLayout->RemoveItem(this);
40}
41
42
43BLayout*
44BLayoutItem::Layout() const
45{
46	return fLayout;
47}
48
49
50void
51BLayoutItem::SetExplicitSize(BSize size)
52{
53	SetExplicitMinSize(size);
54	SetExplicitMaxSize(size);
55	SetExplicitPreferredSize(size);
56}
57
58
59bool
60BLayoutItem::HasHeightForWidth()
61{
62	// no "height for width" by default
63	return false;
64}
65
66
67void
68BLayoutItem::GetHeightForWidth(float width, float* min, float* max,
69	float* preferred)
70{
71	// no "height for width" by default
72}
73
74
75BView*
76BLayoutItem::View()
77{
78	return NULL;
79}
80
81
82void
83BLayoutItem::InvalidateLayout(bool children)
84{
85	LayoutInvalidated(children);
86	if (fLayout)
87		fLayout->InvalidateLayout(children);
88}
89
90
91void
92BLayoutItem::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
102void*
103BLayoutItem::LayoutData() const
104{
105	return fLayoutData;
106}
107
108
109void
110BLayoutItem::SetLayoutData(void* data)
111{
112	fLayoutData = data;
113}
114
115
116void
117BLayoutItem::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
144status_t
145BLayoutItem::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
157status_t
158BLayoutItem::AllArchived(BMessage* into) const
159{
160	BArchiver archiver(into);
161	return BArchivable::AllArchived(into);
162}
163
164
165status_t
166BLayoutItem::AllUnarchived(const BMessage* from)
167{
168	return BArchivable::AllUnarchived(from);
169}
170
171
172void
173BLayoutItem::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
197status_t
198BLayoutItem::Perform(perform_code code, void* _data)
199{
200	return BArchivable::Perform(code, _data);
201}
202
203
204void
205BLayoutItem::LayoutInvalidated(bool children)
206{
207	// hook method
208}
209
210
211void
212BLayoutItem::AttachedToLayout()
213{
214	// hook method
215}
216
217
218void
219BLayoutItem::DetachedFromLayout(BLayout* oldLayout)
220{
221	// hook method
222}
223
224
225void
226BLayoutItem::AncestorVisibilityChanged(bool shown)
227{
228	// hook method
229}
230
231
232// Binary compatibility stuff
233
234
235void BLayoutItem::_ReservedLayoutItem1() {}
236void BLayoutItem::_ReservedLayoutItem2() {}
237void BLayoutItem::_ReservedLayoutItem3() {}
238void BLayoutItem::_ReservedLayoutItem4() {}
239void BLayoutItem::_ReservedLayoutItem5() {}
240void BLayoutItem::_ReservedLayoutItem6() {}
241void BLayoutItem::_ReservedLayoutItem7() {}
242void BLayoutItem::_ReservedLayoutItem8() {}
243void BLayoutItem::_ReservedLayoutItem9() {}
244void BLayoutItem::_ReservedLayoutItem10() {}
245
246