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