vfs: check userland buffers before reading them.
[haiku.git] / src / kits / interface / GroupLayout.cpp
blob55608aa8ba9da8684025610e9458464da9503212
1 /*
2 * Copyright 2010 Haiku, Inc. All rights reserved.
3 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
5 * Distributed under the terms of the MIT License.
6 */
9 #include <GroupLayout.h>
11 #include <ControlLook.h>
12 #include <LayoutItem.h>
13 #include <Message.h>
15 #include <new>
18 using std::nothrow;
21 namespace {
22 const char* const kItemWeightField = "BGroupLayout:item:weight";
23 const char* const kVerticalField = "BGroupLayout:vertical";
27 struct BGroupLayout::ItemLayoutData {
28 float weight;
30 ItemLayoutData()
31 : weight(1)
37 BGroupLayout::BGroupLayout(orientation orientation, float spacing)
39 BTwoDimensionalLayout(),
40 fOrientation(orientation)
42 SetSpacing(spacing);
46 BGroupLayout::BGroupLayout(BMessage* from)
48 BTwoDimensionalLayout(from)
50 bool isVertical;
51 if (from->FindBool(kVerticalField, &isVertical) != B_OK)
52 isVertical = false;
53 fOrientation = isVertical ? B_VERTICAL : B_HORIZONTAL;
57 BGroupLayout::~BGroupLayout()
62 float
63 BGroupLayout::Spacing() const
65 return fHSpacing;
69 void
70 BGroupLayout::SetSpacing(float spacing)
72 spacing = BControlLook::ComposeSpacing(spacing);
73 if (spacing != fHSpacing) {
74 fHSpacing = spacing;
75 fVSpacing = spacing;
76 InvalidateLayout();
81 orientation
82 BGroupLayout::Orientation() const
84 return fOrientation;
88 void
89 BGroupLayout::SetOrientation(orientation orientation)
91 if (orientation != fOrientation) {
92 fOrientation = orientation;
94 InvalidateLayout();
99 float
100 BGroupLayout::ItemWeight(int32 index) const
102 if (index < 0 || index >= CountItems())
103 return 0;
105 ItemLayoutData* data = _LayoutDataForItem(ItemAt(index));
106 return (data ? data->weight : 0);
110 void
111 BGroupLayout::SetItemWeight(int32 index, float weight)
113 if (index < 0 || index >= CountItems())
114 return;
116 if (ItemLayoutData* data = _LayoutDataForItem(ItemAt(index)))
117 data->weight = weight;
119 InvalidateLayout();
123 BLayoutItem*
124 BGroupLayout::AddView(BView* child)
126 return BTwoDimensionalLayout::AddView(child);
130 BLayoutItem*
131 BGroupLayout::AddView(int32 index, BView* child)
133 return BTwoDimensionalLayout::AddView(index, child);
137 BLayoutItem*
138 BGroupLayout::AddView(BView* child, float weight)
140 return AddView(-1, child, weight);
144 BLayoutItem*
145 BGroupLayout::AddView(int32 index, BView* child, float weight)
147 BLayoutItem* item = AddView(index, child);
148 if (ItemLayoutData* data = _LayoutDataForItem(item))
149 data->weight = weight;
151 return item;
155 bool
156 BGroupLayout::AddItem(BLayoutItem* item)
158 return BTwoDimensionalLayout::AddItem(item);
162 bool
163 BGroupLayout::AddItem(int32 index, BLayoutItem* item)
165 return BTwoDimensionalLayout::AddItem(index, item);
169 bool
170 BGroupLayout::AddItem(BLayoutItem* item, float weight)
172 return AddItem(-1, item, weight);
176 bool
177 BGroupLayout::AddItem(int32 index, BLayoutItem* item, float weight)
179 bool success = AddItem(index, item);
180 if (success) {
181 if (ItemLayoutData* data = _LayoutDataForItem(item))
182 data->weight = weight;
185 return success;
189 status_t
190 BGroupLayout::Archive(BMessage* into, bool deep) const
192 BArchiver archiver(into);
193 status_t result = BTwoDimensionalLayout::Archive(into, deep);
195 if (result == B_OK)
196 result = into->AddBool(kVerticalField, fOrientation == B_VERTICAL);
198 return archiver.Finish(result);
202 status_t
203 BGroupLayout::AllArchived(BMessage* into) const
205 return BTwoDimensionalLayout::AllArchived(into);
209 status_t
210 BGroupLayout::AllUnarchived(const BMessage* from)
212 return BTwoDimensionalLayout::AllUnarchived(from);
216 BArchivable*
217 BGroupLayout::Instantiate(BMessage* from)
219 if (validate_instantiation(from, "BGroupLayout"))
220 return new(nothrow) BGroupLayout(from);
221 return NULL;
225 status_t
226 BGroupLayout::ItemArchived(BMessage* into,
227 BLayoutItem* item, int32 index) const
229 return into->AddFloat(kItemWeightField, _LayoutDataForItem(item)->weight);
233 status_t
234 BGroupLayout::ItemUnarchived(const BMessage* from,
235 BLayoutItem* item, int32 index)
237 float weight;
238 status_t result = from->FindFloat(kItemWeightField, index, &weight);
240 if (result == B_OK)
241 _LayoutDataForItem(item)->weight = weight;
243 return result;
247 bool
248 BGroupLayout::ItemAdded(BLayoutItem* item, int32 atIndex)
250 item->SetLayoutData(new(nothrow) ItemLayoutData);
251 return item->LayoutData() != NULL;
255 void
256 BGroupLayout::ItemRemoved(BLayoutItem* item, int32 fromIndex)
258 if (ItemLayoutData* data = _LayoutDataForItem(item)) {
259 item->SetLayoutData(NULL);
260 delete data;
265 void
266 BGroupLayout::PrepareItems(orientation orientation)
268 // filter the visible items
269 fVisibleItems.MakeEmpty();
270 int32 itemCount = CountItems();
271 for (int i = 0; i < itemCount; i++) {
272 BLayoutItem* item = ItemAt(i);
273 if (item->IsVisible())
274 fVisibleItems.AddItem(item);
279 int32
280 BGroupLayout::InternalCountColumns()
282 return (fOrientation == B_HORIZONTAL ? fVisibleItems.CountItems() : 1);
286 int32
287 BGroupLayout::InternalCountRows()
289 return (fOrientation == B_VERTICAL ? fVisibleItems.CountItems() : 1);
293 void
294 BGroupLayout::GetColumnRowConstraints(orientation orientation, int32 index,
295 ColumnRowConstraints* constraints)
297 if (index >= 0 && index < fVisibleItems.CountItems()) {
298 BLayoutItem* item = (BLayoutItem*)fVisibleItems.ItemAt(index);
299 constraints->min = -1;
300 constraints->max = B_SIZE_UNLIMITED;
301 if (ItemLayoutData* data = _LayoutDataForItem(item))
302 constraints->weight = data->weight;
303 else
304 constraints->weight = 1;
309 void
310 BGroupLayout::GetItemDimensions(BLayoutItem* item, Dimensions* dimensions)
312 int32 index = fVisibleItems.IndexOf(item);
313 if (index < 0)
314 return;
316 if (fOrientation == B_HORIZONTAL) {
317 dimensions->x = index;
318 dimensions->y = 0;
319 dimensions->width = 1;
320 dimensions->height = 1;
321 } else {
322 dimensions->x = 0;
323 dimensions->y = index;
324 dimensions->width = 1;
325 dimensions->height = 1;
330 BGroupLayout::ItemLayoutData*
331 BGroupLayout::_LayoutDataForItem(BLayoutItem* item) const
333 return item == NULL ? NULL : (ItemLayoutData*)item->LayoutData();
337 status_t
338 BGroupLayout::Perform(perform_code code, void* _data)
340 return BTwoDimensionalLayout::Perform(code, _data);
344 void BGroupLayout::_ReservedGroupLayout1() {}
345 void BGroupLayout::_ReservedGroupLayout2() {}
346 void BGroupLayout::_ReservedGroupLayout3() {}
347 void BGroupLayout::_ReservedGroupLayout4() {}
348 void BGroupLayout::_ReservedGroupLayout5() {}
349 void BGroupLayout::_ReservedGroupLayout6() {}
350 void BGroupLayout::_ReservedGroupLayout7() {}
351 void BGroupLayout::_ReservedGroupLayout8() {}
352 void BGroupLayout::_ReservedGroupLayout9() {}
353 void BGroupLayout::_ReservedGroupLayout10() {}