From 9d8e314eac40165131bb3dc6e9278ff077c7ab68 Mon Sep 17 00:00:00 2001 From: and3md Date: Wed, 16 Aug 2017 20:33:10 +0200 Subject: [PATCH] Fix #404, percent layout values implemented in V/H layout. Only one widget with percent value allowed per layout. --- src/dlangui/widgets/layouts.d | 30 +++++++++++++++++++++++++----- src/dlangui/widgets/widget.d | 13 +++++-------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/dlangui/widgets/layouts.d b/src/dlangui/widgets/layouts.d index 9d866f94..25aebe0e 100644 --- a/src/dlangui/widgets/layouts.d +++ b/src/dlangui/widgets/layouts.d @@ -26,6 +26,7 @@ Authors: Vadim Lopatin, coolreader.org@gmail.com module dlangui.widgets.layouts; public import dlangui.widgets.widget; +import std.conv; /// helper for layouts struct LayoutItem { @@ -109,12 +110,31 @@ class LayoutItems { _maxSecondarySize = 0; _measureParentSize.x = parentWidth; _measureParentSize.y = parentHeight; + // bool + bool hasPercentSizeWidget = false; + size_t percenSizeWidgetIndex; // measure for (int i = 0; i < _count; i++) { LayoutItem * item = &_list[i]; + item.measure(parentWidth, parentHeight); + + if (isPercentSize(item._layoutSize)) { + if (!hasPercentSizeWidget) { + percenSizeWidgetIndex = i; + hasPercentSizeWidget = true; + } + } + else + _totalSize += item._measuredSize; + if (_maxSecondarySize < item._secondarySize) _maxSecondarySize = item._secondarySize; + } + if (hasPercentSizeWidget) { + LayoutItem * item = &_list[percenSizeWidgetIndex]; + + item._measuredSize = to!int(_totalSize * ((1 / (1 - cast (double) (fromPercentSize(item._layoutSize, 100))/100)) - 1)); _totalSize += item._measuredSize; } return _orientation == Orientation.Horizontal ? Point(_totalSize, _maxSecondarySize) : Point(_maxSecondarySize, _totalSize); @@ -161,7 +181,7 @@ class LayoutItems { maxItem = item.secondarySize; if (item._isResizer) { resizersSize += size; - } else if (item.fillParent) { + } else if (item.fillParent || isPercentSize(item.layoutSize)) { resizableWeight += weight; resizableSize += size * weight; } else { @@ -174,7 +194,7 @@ class LayoutItems { contentSecondarySize = maxItem; else contentSecondarySize = rc.width; - if (_layoutHeight == FILL_PARENT && totalSize < rc.height && resizableSize > 0) { + if ((_layoutHeight == FILL_PARENT || isPercentSize(_layoutHeight)) && totalSize < rc.height && resizableSize > 0) { delta = rc.height - totalSize; // total space to add to fit } else if (totalSize > rc.height) { delta = rc.height - totalSize; // total space to reduce to fit @@ -184,7 +204,7 @@ class LayoutItems { contentSecondarySize = maxItem; else contentSecondarySize = rc.height; - if (_layoutWidth == FILL_PARENT && totalSize < rc.width && resizableSize > 0) + if ((_layoutWidth == FILL_PARENT || isPercentSize(_layoutHeight)) && totalSize < rc.width && resizableSize > 0) delta = rc.width - totalSize; // total space to add to fit else if (totalSize > rc.width) delta = rc.width - totalSize; // total space to reduce to fit @@ -216,7 +236,7 @@ class LayoutItems { int resizerDelta = 0; for (int i = 0; i < _count; i++) { LayoutItem * item = &_list[i]; - if ((item.fillParent || needForceResize) && (delta < 0 || item.canExtend)) { + if ((item.fillParent || isPercentSize(item.layoutSize) || needForceResize) && (delta < 0 || item.canExtend)) { lastResized = i; } if (item._isResizer) { @@ -232,7 +252,7 @@ class LayoutItems { int layoutSize = item.layoutSize; int weight = item.weight; int size = item.measuredSize; - if (needResize && (layoutSize == FILL_PARENT || needForceResize)) { + if (needResize && (layoutSize == FILL_PARENT || isPercentSize(layoutSize) || needForceResize)) { // do resize int correction = (delta < 0 || item.canExtend) ? scaleFactor * weight * size / 10000 : 0; deltaTotal += correction; diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index 6993c33e..3e207670 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -623,9 +623,9 @@ public: /// set max height constraint (0 for no constraint) @property Widget minHeight(int value) { ownStyle.minHeight = value; return this; } - /// returns layout width options (WRAP_CONTENT, FILL_PARENT, or some constant value) + /// returns layout width options (WRAP_CONTENT, FILL_PARENT, some constant value or percent but only for one widget in layout) @property int layoutWidth() { return style.layoutWidth; } - /// returns layout height options (WRAP_CONTENT, FILL_PARENT, or some constant value) + /// returns layout height options (WRAP_CONTENT, FILL_PARENT, some constant value or percent but only for one widget in layout) @property int layoutHeight() { return style.layoutHeight; } /// returns layout weight (while resizing to fill parent, widget will be resized proportionally to this value) @property int layoutWeight() { return style.layoutWeight; } @@ -1371,13 +1371,10 @@ public: // check for fixed size set in layoutWidth, layoutHeight int lh = layoutHeight; int lw = layoutWidth; - if (isPercentSize(lh) && parentHeight != SIZE_UNSPECIFIED) - dy = fromPercentSize(lh, parentHeight); - else if (!isSpecialSize(lh)) + // constant value support + if (!(isPercentSize(lh) || isSpecialSize(lh))) dy = lh; - if (isPercentSize(lw) && parentWidth != SIZE_UNSPECIFIED) - dx = fromPercentSize(lw, parentWidth); - else if (!isSpecialSize(lw)) + if (!(isPercentSize(lw) || isSpecialSize(lw))) dx = lw; // apply min/max width and height constraints int minw = minWidth;