2 * Copyright 2006-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include <CardLayout.h>
8 #include <LayoutItem.h>
14 const char* kVisibleItemField
= "BCardLayout:visibleItem";
18 BCardLayout::BCardLayout()
22 fMax(B_SIZE_UNLIMITED
, B_SIZE_UNLIMITED
),
30 BCardLayout::BCardLayout(BMessage
* from
)
32 BAbstractLayout(BUnarchiver::PrepareArchive(from
)),
34 fMax(B_SIZE_UNLIMITED
, B_SIZE_UNLIMITED
),
39 BUnarchiver(from
).Finish();
43 BCardLayout::~BCardLayout()
49 BCardLayout::VisibleItem() const
56 BCardLayout::VisibleIndex() const
58 return IndexOfItem(fVisibleItem
);
63 BCardLayout::SetVisibleItem(int32 index
)
65 SetVisibleItem(ItemAt(index
));
70 BCardLayout::SetVisibleItem(BLayoutItem
* item
)
72 if (item
== fVisibleItem
)
75 if (item
!= NULL
&& IndexOfItem(item
) < 0)
78 if (fVisibleItem
!= NULL
)
79 fVisibleItem
->SetVisible(false);
83 if (fVisibleItem
!= NULL
) {
84 fVisibleItem
->SetVisible(true);
92 BCardLayout::BaseMinSize()
100 BCardLayout::BaseMaxSize()
108 BCardLayout::BasePreferredSize()
116 BCardLayout::BaseAlignment()
118 return BAlignment(B_ALIGN_USE_FULL_WIDTH
, B_ALIGN_USE_FULL_HEIGHT
);
123 BCardLayout::HasHeightForWidth()
125 int32 count
= CountItems();
126 for (int32 i
= 0; i
< count
; i
++) {
127 if (ItemAt(i
)->HasHeightForWidth())
136 BCardLayout::GetHeightForWidth(float width
, float* min
, float* max
,
141 // init with useful values
142 float minHeight
= fMin
.height
;
143 float maxHeight
= fMax
.height
;
144 float preferredHeight
= fPreferred
.height
;
146 // apply the items' constraints
147 int32 count
= CountItems();
148 for (int32 i
= 0; i
< count
; i
++) {
149 BLayoutItem
* item
= ItemAt(i
);
150 if (item
->HasHeightForWidth()) {
153 float itemPreferredHeight
;
154 item
->GetHeightForWidth(width
, &itemMinHeight
, &itemMaxHeight
,
155 &itemPreferredHeight
);
156 minHeight
= max_c(minHeight
, itemMinHeight
);
157 maxHeight
= min_c(maxHeight
, itemMaxHeight
);
158 preferredHeight
= min_c(preferredHeight
, itemPreferredHeight
);
162 // adjust max and preferred, if necessary
163 maxHeight
= max_c(maxHeight
, minHeight
);
164 preferredHeight
= max_c(preferredHeight
, minHeight
);
165 preferredHeight
= min_c(preferredHeight
, maxHeight
);
172 *preferred
= preferredHeight
;
177 BCardLayout::LayoutInvalidated(bool children
)
179 fMinMaxValid
= false;
184 BCardLayout::DoLayout()
188 BSize
size(LayoutArea().Size());
190 // this cannot be done when we are viewless, as our children
191 // would not get cut off in the right place.
193 size
.width
= max_c(size
.width
, fMin
.width
);
194 size
.height
= max_c(size
.height
, fMin
.height
);
197 if (fVisibleItem
!= NULL
)
198 fVisibleItem
->AlignInFrame(BRect(LayoutArea().LeftTop(), size
));
203 BCardLayout::Archive(BMessage
* into
, bool deep
) const
205 BArchiver
archiver(into
);
206 status_t err
= BAbstractLayout::Archive(into
, deep
);
208 if (err
== B_OK
&& deep
)
209 err
= into
->AddInt32(kVisibleItemField
, IndexOfItem(fVisibleItem
));
211 return archiver
.Finish(err
);
216 BCardLayout::AllArchived(BMessage
* archive
) const
218 return BAbstractLayout::AllArchived(archive
);
223 BCardLayout::AllUnarchived(const BMessage
* from
)
225 status_t err
= BLayout::AllUnarchived(from
);
230 err
= from
->FindInt32(kVisibleItemField
, &visibleIndex
);
232 SetVisibleItem(visibleIndex
);
239 BCardLayout::ItemArchived(BMessage
* into
, BLayoutItem
* item
, int32 index
) const
241 return BAbstractLayout::ItemArchived(into
, item
, index
);
246 BCardLayout::ItemUnarchived(const BMessage
* from
, BLayoutItem
* item
,
249 return BAbstractLayout::ItemUnarchived(from
, item
, index
);
255 BCardLayout::Instantiate(BMessage
* from
)
257 if (validate_instantiation(from
, "BCardLayout"))
258 return new BCardLayout(from
);
264 BCardLayout::ItemAdded(BLayoutItem
* item
, int32 atIndex
)
266 item
->SetVisible(false);
272 BCardLayout::ItemRemoved(BLayoutItem
* item
, int32 fromIndex
)
274 if (fVisibleItem
== item
) {
275 BLayoutItem
* newVisibleItem
= NULL
;
276 SetVisibleItem(newVisibleItem
);
282 BCardLayout::_ValidateMinMax()
289 fMax
.width
= B_SIZE_UNLIMITED
;
290 fMax
.height
= B_SIZE_UNLIMITED
;
291 fPreferred
.width
= 0;
292 fPreferred
.height
= 0;
294 int32 itemCount
= CountItems();
295 for (int32 i
= 0; i
< itemCount
; i
++) {
296 BLayoutItem
* item
= ItemAt(i
);
298 BSize min
= item
->MinSize();
299 BSize max
= item
->MaxSize();
300 BSize preferred
= item
->PreferredSize();
302 fMin
.width
= max_c(fMin
.width
, min
.width
);
303 fMin
.height
= max_c(fMin
.height
, min
.height
);
305 fMax
.width
= min_c(fMax
.width
, max
.width
);
306 fMax
.height
= min_c(fMax
.height
, max
.height
);
308 fPreferred
.width
= max_c(fPreferred
.width
, preferred
.width
);
309 fPreferred
.height
= max_c(fPreferred
.height
, preferred
.height
);
312 fMax
.width
= max_c(fMax
.width
, fMin
.width
);
313 fMax
.height
= max_c(fMax
.height
, fMin
.height
);
315 fPreferred
.width
= max_c(fPreferred
.width
, fMin
.width
);
316 fPreferred
.height
= max_c(fPreferred
.height
, fMin
.height
);
317 fPreferred
.width
= min_c(fPreferred
.width
, fMax
.width
);
318 fPreferred
.height
= min_c(fPreferred
.height
, fMax
.height
);
321 ResetLayoutInvalidation();
326 BCardLayout::Perform(perform_code d
, void* arg
)
328 return BAbstractLayout::Perform(d
, arg
);
332 void BCardLayout::_ReservedCardLayout1() {}
333 void BCardLayout::_ReservedCardLayout2() {}
334 void BCardLayout::_ReservedCardLayout3() {}
335 void BCardLayout::_ReservedCardLayout4() {}
336 void BCardLayout::_ReservedCardLayout5() {}
337 void BCardLayout::_ReservedCardLayout6() {}
338 void BCardLayout::_ReservedCardLayout7() {}
339 void BCardLayout::_ReservedCardLayout8() {}
340 void BCardLayout::_ReservedCardLayout9() {}
341 void BCardLayout::_ReservedCardLayout10() {}