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.
9 #include <GroupLayout.h>
11 #include <ControlLook.h>
12 #include <LayoutItem.h>
22 const char* const kItemWeightField
= "BGroupLayout:item:weight";
23 const char* const kVerticalField
= "BGroupLayout:vertical";
27 struct BGroupLayout::ItemLayoutData
{
37 BGroupLayout::BGroupLayout(orientation orientation
, float spacing
)
39 BTwoDimensionalLayout(),
40 fOrientation(orientation
)
46 BGroupLayout::BGroupLayout(BMessage
* from
)
48 BTwoDimensionalLayout(from
)
51 if (from
->FindBool(kVerticalField
, &isVertical
) != B_OK
)
53 fOrientation
= isVertical
? B_VERTICAL
: B_HORIZONTAL
;
57 BGroupLayout::~BGroupLayout()
63 BGroupLayout::Spacing() const
70 BGroupLayout::SetSpacing(float spacing
)
72 spacing
= BControlLook::ComposeSpacing(spacing
);
73 if (spacing
!= fHSpacing
) {
82 BGroupLayout::Orientation() const
89 BGroupLayout::SetOrientation(orientation orientation
)
91 if (orientation
!= fOrientation
) {
92 fOrientation
= orientation
;
100 BGroupLayout::ItemWeight(int32 index
) const
102 if (index
< 0 || index
>= CountItems())
105 ItemLayoutData
* data
= _LayoutDataForItem(ItemAt(index
));
106 return (data
? data
->weight
: 0);
111 BGroupLayout::SetItemWeight(int32 index
, float weight
)
113 if (index
< 0 || index
>= CountItems())
116 if (ItemLayoutData
* data
= _LayoutDataForItem(ItemAt(index
)))
117 data
->weight
= weight
;
124 BGroupLayout::AddView(BView
* child
)
126 return BTwoDimensionalLayout::AddView(child
);
131 BGroupLayout::AddView(int32 index
, BView
* child
)
133 return BTwoDimensionalLayout::AddView(index
, child
);
138 BGroupLayout::AddView(BView
* child
, float weight
)
140 return AddView(-1, child
, weight
);
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
;
156 BGroupLayout::AddItem(BLayoutItem
* item
)
158 return BTwoDimensionalLayout::AddItem(item
);
163 BGroupLayout::AddItem(int32 index
, BLayoutItem
* item
)
165 return BTwoDimensionalLayout::AddItem(index
, item
);
170 BGroupLayout::AddItem(BLayoutItem
* item
, float weight
)
172 return AddItem(-1, item
, weight
);
177 BGroupLayout::AddItem(int32 index
, BLayoutItem
* item
, float weight
)
179 bool success
= AddItem(index
, item
);
181 if (ItemLayoutData
* data
= _LayoutDataForItem(item
))
182 data
->weight
= weight
;
190 BGroupLayout::Archive(BMessage
* into
, bool deep
) const
192 BArchiver
archiver(into
);
193 status_t result
= BTwoDimensionalLayout::Archive(into
, deep
);
196 result
= into
->AddBool(kVerticalField
, fOrientation
== B_VERTICAL
);
198 return archiver
.Finish(result
);
203 BGroupLayout::AllArchived(BMessage
* into
) const
205 return BTwoDimensionalLayout::AllArchived(into
);
210 BGroupLayout::AllUnarchived(const BMessage
* from
)
212 return BTwoDimensionalLayout::AllUnarchived(from
);
217 BGroupLayout::Instantiate(BMessage
* from
)
219 if (validate_instantiation(from
, "BGroupLayout"))
220 return new(nothrow
) BGroupLayout(from
);
226 BGroupLayout::ItemArchived(BMessage
* into
,
227 BLayoutItem
* item
, int32 index
) const
229 return into
->AddFloat(kItemWeightField
, _LayoutDataForItem(item
)->weight
);
234 BGroupLayout::ItemUnarchived(const BMessage
* from
,
235 BLayoutItem
* item
, int32 index
)
238 status_t result
= from
->FindFloat(kItemWeightField
, index
, &weight
);
241 _LayoutDataForItem(item
)->weight
= weight
;
248 BGroupLayout::ItemAdded(BLayoutItem
* item
, int32 atIndex
)
250 item
->SetLayoutData(new(nothrow
) ItemLayoutData
);
251 return item
->LayoutData() != NULL
;
256 BGroupLayout::ItemRemoved(BLayoutItem
* item
, int32 fromIndex
)
258 if (ItemLayoutData
* data
= _LayoutDataForItem(item
)) {
259 item
->SetLayoutData(NULL
);
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
);
280 BGroupLayout::InternalCountColumns()
282 return (fOrientation
== B_HORIZONTAL
? fVisibleItems
.CountItems() : 1);
287 BGroupLayout::InternalCountRows()
289 return (fOrientation
== B_VERTICAL
? fVisibleItems
.CountItems() : 1);
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
;
304 constraints
->weight
= 1;
310 BGroupLayout::GetItemDimensions(BLayoutItem
* item
, Dimensions
* dimensions
)
312 int32 index
= fVisibleItems
.IndexOf(item
);
316 if (fOrientation
== B_HORIZONTAL
) {
317 dimensions
->x
= index
;
319 dimensions
->width
= 1;
320 dimensions
->height
= 1;
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();
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() {}