2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
11 #include <AbstractLayout.h>
12 #include <ScrollBar.h>
14 #include "ViewLayoutItem.h"
20 // #pragma mark - ViewPortLayout
23 class BViewPort::ViewPortLayout
: public BAbstractLayout
{
25 ViewPortLayout(BViewPort
* viewPort
)
37 BView
* ChildView() const
41 if (BViewLayoutItem
* item
= dynamic_cast<BViewLayoutItem
*>(ItemAt(0)))
46 void SetChildView(BView
* view
)
50 if (view
!= NULL
&& AddView(0, view
) != NULL
)
54 BLayoutItem
* ChildItem() const
59 void SetChildItem(BLayoutItem
* item
)
67 virtual BSize
BaseMinSize()
73 virtual BSize
BaseMaxSize()
79 virtual BSize
BasePreferredSize()
85 virtual BAlignment
BaseAlignment()
87 return BAbstractLayout::BaseAlignment();
90 virtual bool HasHeightForWidth()
94 // TODO: Support height-for-width!
97 virtual void GetHeightForWidth(float width
, float* min
, float* max
,
100 if (!HasHeightForWidth())
103 // TODO: Support height-for-width!
106 virtual void LayoutInvalidated(bool children
)
108 fIsCacheValid
= false;
111 virtual void DoLayout()
115 BLayoutItem
* child
= ItemAt(0);
119 // Determine the layout area: LayoutArea() will only give us the size
120 // of the view port's frame.
121 BSize viewSize
= LayoutArea().Size();
122 BSize layoutSize
= viewSize
;
124 BSize childMin
= child
->MinSize();
125 BSize childMax
= child
->MaxSize();
127 // apply the maximum constraints
128 layoutSize
.width
= std::min(layoutSize
.width
, childMax
.width
);
129 layoutSize
.height
= std::min(layoutSize
.height
, childMax
.height
);
131 // apply the minimum constraints
132 layoutSize
.width
= std::max(layoutSize
.width
, childMin
.width
);
133 layoutSize
.height
= std::max(layoutSize
.height
, childMin
.height
);
135 // TODO: Support height-for-width!
137 child
->AlignInFrame(BRect(BPoint(0, 0), layoutSize
));
139 _UpdateScrollBar(fViewPort
->ScrollBar(B_HORIZONTAL
), viewSize
.width
,
141 _UpdateScrollBar(fViewPort
->ScrollBar(B_VERTICAL
), viewSize
.height
,
148 if (CountItems() > 0) {
149 BLayoutItem
* item
= RemoveItem((int32
)0);
152 fHasViewChild
= false;
156 void _ValidateMinMax()
161 if (BLayoutItem
* child
= ItemAt(0)) {
162 fMin
= child
->MinSize();
163 if (_IsHorizontallyScrollable())
165 if (_IsVerticallyScrollable())
167 fMax
= child
->MaxSize();
168 fPreferred
= child
->PreferredSize();
169 // TODO: Support height-for-width!
172 fMax
.Set(B_SIZE_UNLIMITED
, B_SIZE_UNLIMITED
);
173 fPreferred
.Set(20, 20);
176 fIsCacheValid
= true;
179 bool _IsHorizontallyScrollable() const
181 return fViewPort
->ScrollBar(B_HORIZONTAL
) != NULL
;
184 bool _IsVerticallyScrollable() const
186 return fViewPort
->ScrollBar(B_VERTICAL
) != NULL
;
189 void _UpdateScrollBar(BScrollBar
* scrollBar
, float viewPortSize
,
192 if (scrollBar
== NULL
)
195 if (viewPortSize
< dataSize
) {
196 scrollBar
->SetRange(0, dataSize
- viewPortSize
);
197 scrollBar
->SetProportion(viewPortSize
/ dataSize
);
199 scrollBar
->GetSteps(&smallStep
, NULL
);
200 scrollBar
->SetSteps(smallStep
, viewPortSize
);
202 scrollBar
->SetRange(0, 0);
203 scrollBar
->SetProportion(1);
208 BViewPort
* fViewPort
;
217 // #pragma mark - BViewPort
220 BViewPort::BViewPort(BView
* child
)
230 BViewPort::BViewPort(BLayoutItem
* child
)
240 BViewPort::BViewPort(const char* name
, BView
* child
)
250 BViewPort::BViewPort(const char* name
, BLayoutItem
* child
)
260 BViewPort::~BViewPort()
266 BViewPort::ChildView() const
268 return fLayout
->ChildView();
273 BViewPort::SetChildView(BView
* child
)
275 fLayout
->SetChildView(child
);
281 BViewPort::ChildItem() const
283 return fLayout
->ChildItem();
288 BViewPort::SetChildItem(BLayoutItem
* child
)
290 fLayout
->SetChildItem(child
);
298 fLayout
= new ViewPortLayout(this);
303 } // namespace BPrivate
306 using ::BPrivate::BViewPort
;