diff options
Diffstat (limited to 'skinengine/src/skin_layout.cpp')
-rw-r--r-- | skinengine/src/skin_layout.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/skinengine/src/skin_layout.cpp b/skinengine/src/skin_layout.cpp new file mode 100644 index 0000000..4f5f209 --- /dev/null +++ b/skinengine/src/skin_layout.cpp @@ -0,0 +1,167 @@ +#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);
+}
|