#include "stdafx.h" #include "HBox.h" namespace ui { HLayout::HLayout() { } CSize HLayout::ArrangeChild(const std::vector& 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& 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()) { } }