summaryrefslogtreecommitdiff
path: root/SkinEngine/src/skin_layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SkinEngine/src/skin_layout.cpp')
-rw-r--r--SkinEngine/src/skin_layout.cpp167
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(&params->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(&params->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(&params->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);
+}