Fix #404, percent layout values implemented in V/H layout.

Only one widget with percent value allowed per layout.
This commit is contained in:
and3md 2017-08-16 20:33:10 +02:00
parent 40b267d6c2
commit 9d8e314eac
2 changed files with 30 additions and 13 deletions

View File

@ -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;

View File

@ -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;