xref: /haiku/src/kits/interface/LayoutItem.cpp (revision c90684742e7361651849be4116d0e5de3a817194)
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 
13 #include <algorithm>
14 
15 
16 BLayoutItem::BLayoutItem()
17 	:
18 	fLayout(NULL),
19 	fLayoutData(NULL)
20 {
21 }
22 
23 
24 BLayoutItem::BLayoutItem(BMessage* from)
25 	:
26 	BArchivable(BUnarchiver::PrepareArchive(from)),
27 	fLayout(NULL),
28 	fLayoutData(NULL)
29 {
30 	BUnarchiver(from).Finish();
31 }
32 
33 
34 BLayoutItem::~BLayoutItem()
35 {
36 	if (fLayout)
37 		fLayout->RemoveItem(this);
38 }
39 
40 
41 BLayout*
42 BLayoutItem::Layout() const
43 {
44 	return fLayout;
45 }
46 
47 
48 bool
49 BLayoutItem::HasHeightForWidth()
50 {
51 	// no "height for width" by default
52 	return false;
53 }
54 
55 
56 void
57 BLayoutItem::GetHeightForWidth(float width, float* min, float* max,
58 	float* preferred)
59 {
60 	// no "height for width" by default
61 }
62 
63 
64 BView*
65 BLayoutItem::View()
66 {
67 	return NULL;
68 }
69 
70 
71 void
72 BLayoutItem::InvalidateLayout(bool children)
73 {
74 	if (fLayout)
75 		fLayout->InvalidateLayout(children);
76 }
77 
78 
79 void
80 BLayoutItem::Relayout(bool immediate)
81 {
82 	BView* view = View();
83 	if (view && !immediate)
84 		view->Relayout();
85 	else if (view && immediate)
86 		view->Layout(false);
87 }
88 
89 
90 void*
91 BLayoutItem::LayoutData() const
92 {
93 	return fLayoutData;
94 }
95 
96 
97 void
98 BLayoutItem::SetLayoutData(void* data)
99 {
100 	fLayoutData = data;
101 }
102 
103 
104 void
105 BLayoutItem::AlignInFrame(BRect frame)
106 {
107 	BSize maxSize = MaxSize();
108 	BAlignment alignment = Alignment();
109 
110 	if (HasHeightForWidth()) {
111 		// The item has height for width, so we do the horizontal alignment
112 		// ourselves and restrict the height max constraint respectively.
113 		if (maxSize.width < frame.Width()
114 			&& alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) {
115 			frame.left += (int)((frame.Width() - maxSize.width)
116 				* alignment.horizontal);
117 			frame.right = frame.left + maxSize.width;
118 		}
119 		alignment.horizontal = B_ALIGN_USE_FULL_WIDTH;
120 
121 		float minHeight;
122 		GetHeightForWidth(frame.Width(), &minHeight, NULL, NULL);
123 
124 		frame.bottom = frame.top + max_c(frame.Height(), minHeight);
125 		maxSize.height = minHeight;
126 	}
127 
128 	SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment));
129 }
130 
131 
132 status_t
133 BLayoutItem::Archive(BMessage* into, bool deep) const
134 {
135 	BArchiver archiver(into);
136 	status_t err = BArchivable::Archive(into, deep);
137 
138 	if (err == B_OK)
139 		err = archiver.Finish();
140 
141 	return err;
142 }
143 
144 
145 status_t
146 BLayoutItem::AllArchived(BMessage* into) const
147 {
148 	BArchiver archiver(into);
149 	return BArchivable::AllArchived(into);
150 }
151 
152 
153 status_t
154 BLayoutItem::AllUnarchived(const BMessage* from)
155 {
156 	return BArchivable::AllUnarchived(from);
157 }
158 
159 
160 void
161 BLayoutItem::SetLayout(BLayout* layout)
162 {
163 	if (layout == fLayout)
164 		return;
165 
166 	std::swap(fLayout, layout);
167 	if (layout)
168 		DetachedFromLayout(layout);
169 
170 	if (fLayout)
171 		AttachedToLayout();
172 }
173 
174 
175 void
176 BLayoutItem::AttachedToLayout()
177 {
178 	// hook method
179 }
180 
181 
182 void
183 BLayoutItem::DetachedFromLayout(BLayout* oldLayout)
184 {
185 	// hook method
186 }
187 
188 
189 void
190 BLayoutItem::AncestorVisibilityChanged(bool shown)
191 {
192 	// hook method
193 }
194 
195