nim_duilib/duilib/Box/HBox.cpp
jiajia_deng 4933d1f2bc Remove dependency on shared
Signed-off-by: jiajia_deng <2894220@gmail.com>
2019-09-20 16:27:58 +08:00

147 lines
4.6 KiB
C++

#include "stdafx.h"
#include "HBox.h"
namespace ui
{
HLayout::HLayout()
{
}
CSize HLayout::ArrangeChild(const std::vector<Control*>& items, UiRect rc)
{
// Determine the width of elements that are sizeable
CSize szAvailable(rc.right - rc.left, rc.bottom - rc.top);
int nAdjustables = 0;
int cxFixed = 0;
int nEstimateNum = 0;
for( auto it = items.begin(); it != items.end(); it++ ) {
auto pControl = *it;
if( !pControl->IsVisible() ) continue;
if( pControl->IsFloat() ) continue;
CSize sz = pControl->EstimateSize(szAvailable);
if( sz.cx == DUI_LENGTH_STRETCH ) {
nAdjustables++;
cxFixed += pControl->GetMargin().left + pControl->GetMargin().right;
}
else {
if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
if( pControl->GetMaxWidth() >= 0 && sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
cxFixed += sz.cx + pControl->GetMargin().left + pControl->GetMargin().right;
}
nEstimateNum++;
}
cxFixed += (nEstimateNum - 1) * m_iChildMargin;
int cxExpand = 0;
int cxNeeded = 0;
if( nAdjustables > 0 ) cxExpand = MAX(0, (szAvailable.cx - cxFixed) / nAdjustables);
int deviation = szAvailable.cx - cxFixed - cxExpand * nAdjustables;
// Position the elements
CSize szRemaining = szAvailable;
int iPosX = rc.left;
int iPosTop = rc.top;
int iPosBottom = rc.bottom;
int iAdjustable = 0;
int max_height = 0;
for( auto it = items.begin(); it != items.end(); it++ ) {
auto pControl = *it;
if( !pControl->IsVisible() ) continue;
if( pControl->IsFloat() ) {
SetFloatPos(pControl, rc);
continue;
}
UiRect rcMargin = pControl->GetMargin();
szRemaining.cx -= rcMargin.left;
CSize sz = pControl->EstimateSize(szRemaining);
if( sz.cx == DUI_LENGTH_STRETCH ) {
iAdjustable++;
sz.cx = cxExpand;
if (deviation > 0) {
sz.cx += 1;
deviation--;
}
}
if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
if( pControl->GetMaxWidth() >= 0 && sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
if( sz.cy == DUI_LENGTH_STRETCH ) sz.cy = szAvailable.cy - rcMargin.top - rcMargin.bottom;
if( sz.cy < 0 ) sz.cy = 0;
if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
int childTop = 0;
int childBottm = 0;
VerAlignType verAlignType = pControl->GetVerAlignType();
if (verAlignType == kVerAlignTop) {
childTop = iPosTop + rcMargin.top;
childBottm = childTop + sz.cy;
}
else if (verAlignType == kVerAlignBottom) {
childBottm = iPosBottom - rcMargin.bottom;
childTop = childBottm - sz.cy;
}
else if (verAlignType == kVerAlignCenter) {
childTop = iPosTop + (iPosBottom - iPosTop + rcMargin.top - rcMargin.bottom - sz.cy) / 2;
childBottm = childTop + sz.cy;
}
UiRect rcChildPos(iPosX + rcMargin.left, childTop, iPosX + rcMargin.left + sz.cx, childBottm);
max_height = MAX(max_height, rcChildPos.GetHeight());
pControl->SetPos(rcChildPos);
iPosX += sz.cx + m_iChildMargin + rcMargin.left + rcMargin.right;
cxNeeded += sz.cx + rcMargin.left + rcMargin.right;
szRemaining.cx -= sz.cx + m_iChildMargin + rcMargin.right;
}
cxNeeded += (nEstimateNum - 1) * m_iChildMargin;
CSize size(cxNeeded, max_height);
return size;
}
CSize HLayout::AjustSizeByChild(const std::vector<Control*>& items, CSize szAvailable)
{
CSize totalSize;
CSize itemSize;
Control* pChildControl = NULL;
int count = (int)items.size();
int estimateChildCount = 0;
for(int it = 0; it < count; it++)
{
pChildControl = (Control*)items[it];
if (!pChildControl->IsVisible() || pChildControl->IsFloat()){
continue;
}
estimateChildCount++;
itemSize = pChildControl->EstimateSize(szAvailable);
if( itemSize.cx < pChildControl->GetMinWidth() ) itemSize.cx = pChildControl->GetMinWidth();
if( pChildControl->GetMaxWidth() >= 0 && itemSize.cx > pChildControl->GetMaxWidth() ) itemSize.cx = pChildControl->GetMaxWidth();
if( itemSize.cy < pChildControl->GetMinHeight() ) itemSize.cy = pChildControl->GetMinHeight();
if( itemSize.cy > pChildControl->GetMaxHeight() ) itemSize.cy = pChildControl->GetMaxHeight();
totalSize.cx += itemSize.cx + pChildControl->GetMargin().left + pChildControl->GetMargin().right;
totalSize.cy = MAX(itemSize.cy + pChildControl->GetMargin().top + pChildControl->GetMargin().bottom, totalSize.cy);
}
if (estimateChildCount - 1 > 0) {
totalSize.cx += (estimateChildCount - 1) * m_iChildMargin;
}
totalSize.cx += m_rcPadding.left + m_rcPadding.right;
totalSize.cy += m_rcPadding.top + m_rcPadding.bottom;
return totalSize;
}
HBox::HBox() : Box(new HLayout())
{
}
}