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