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