#include "headers.h" void CSkinLayout::LoadFromXml(HXML hXml) { CSkinComplexObject::LoadFromXml(hXml); const TCHAR *s = xi.getAttrValue(hXml, _T("type")); if (!lstrcmp(s, _T("horizontal"))) m_layoutMode = MODE_HORIZONTAL; else if (!lstrcmp(s, _T("layered"))) m_layoutMode = MODE_LAYERED; else m_layoutMode = MODE_VERTICAL; } void CSkinLayout::Measure(SkinRenderParams *params) { switch (m_layoutMode) { case MODE_HORIZONTAL: MeasureHorizontal(params); break; case MODE_LAYERED: MeasureLayered(params); break; case MODE_VERTICAL: default: MeasureVertical(params); break; } } void CSkinLayout::MeasureHorizontal(SkinRenderParams *params) { int width = 0, height = 0; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(params); width += params->rc.right; height = max(height, params->rc.bottom); } SetRect(¶ms->rc, 0, 0, width, height); } void CSkinLayout::MeasureVertical(SkinRenderParams *params) { int width = 0, height = 0; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(params); width = max(width, params->rc.right); height += params->rc.bottom; } SetRect(¶ms->rc, 0, 0, width, height); } void CSkinLayout::MeasureLayered(SkinRenderParams *params) { int width = 0, height = 0; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(params); width = max(width, params->rc.right); height = max(height, params->rc.bottom); } SetRect(¶ms->rc, 0, 0, width, height); } void CSkinLayout::Layout(SkinRenderParams *params) { switch (m_layoutMode) { case MODE_HORIZONTAL: LayoutHorizontal(params); break; case MODE_LAYERED: LayoutLayered(params); break; case MODE_VERTICAL: default: LayoutVertical(params); break; } } void CSkinLayout::Paint(SkinRenderParams *params) { for (int i = 0; i < m_children.getCount(); ++i) m_children[i]->Paint(params); } void CSkinLayout::LayoutHorizontal(SkinRenderParams *params) { int usedWidth = 0, flexibleCount = 0; SkinRenderParams newParams = *params; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(&newParams); if (newParams.rc.right > 0) usedWidth += newParams.rc.right; else ++flexibleCount; } int flexibleWidth = flexibleCount ? ((params->rc.right - params->rc.left - usedWidth) / flexibleCount) : 0; int x = params->rc.left; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(&newParams); if (newParams.rc.right <= 0) newParams.rc.right = flexibleWidth; newParams.rc.left = x; newParams.rc.right = x + newParams.rc.right; newParams.rc.top = params->rc.top; newParams.rc.bottom = params->rc.bottom; x = newParams.rc.right; m_children[i]->Layout(&newParams); } } void CSkinLayout::LayoutVertical(SkinRenderParams *params) { int usedHeight = 0, flexibleCount = 0; SkinRenderParams newParams = *params; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(&newParams); if (newParams.rc.bottom > 0) usedHeight += newParams.rc.bottom; else ++flexibleCount; } int flexibleHeight = flexibleCount ? ((params->rc.bottom - params->rc.top - usedHeight) / flexibleCount) : 0; int y = params->rc.top; for (int i = 0; i < m_children.getCount(); ++i) { m_children[i]->Measure(&newParams); if (newParams.rc.bottom <= 0) newParams.rc.bottom = flexibleHeight; newParams.rc.left = params->rc.left; newParams.rc.right = params->rc.right; newParams.rc.top = y; newParams.rc.bottom = y + newParams.rc.bottom; y = newParams.rc.bottom; m_children[i]->Layout(&newParams); } } void CSkinLayout::LayoutLayered(SkinRenderParams *params) { for (int i = 0; i < m_children.getCount(); ++i) m_children[i]->Layout(params); }