1 module rpui.widgets.stack_layout.stack_locator; 2 3 import std.math; 4 5 import rpui.widget; 6 import rpui.primitives; 7 import rpui.math; 8 9 struct StackLocator { 10 Widget holder; 11 Orientation orientation = Orientation.vertical; 12 13 private vec2 maxSize = vec2(0, 0); 14 private vec2 lastWidgetPosition = vec2(0, 0); 15 private Widget lastWidgetInStack = null; 16 17 void attach(Widget widget) { 18 holder = widget; 19 holder.widthType = Widget.SizeType.wrapContent; 20 holder.heightType = Widget.SizeType.wrapContent; 21 setDecorator(); 22 } 23 24 private void setDecorator() { 25 holder.children.decorateWidgets(delegate(Widget widget) { 26 Widget cell = new Widget(); 27 cell.associatedWidget = widget; 28 cell.skipFocus = true; 29 return cell; 30 }); 31 } 32 33 void updateWidgetsPosition() { 34 with (holder) { 35 startWidgetsPositioning(); 36 37 foreach (Widget cell; children) { 38 pushWidgetPosition(cell); 39 } 40 } 41 } 42 43 void startWidgetsPositioning() { 44 lastWidgetPosition = vec2(0, 0); 45 lastWidgetInStack = null; 46 } 47 48 void pushWidgetPosition(Widget cell) { 49 with (holder) { 50 lastWidgetInStack = cell.firstWidget; 51 52 if (orientation == Orientation.vertical) { 53 cell.widthType = SizeType.matchParent; 54 cell.size.y = lastWidgetInStack.outerSize.y; 55 cell.position.y = lastWidgetPosition.y; 56 cell.updateSize(); 57 } else { 58 cell.size.x = lastWidgetInStack.outerSize.x; 59 cell.heightType = SizeType.matchParent; 60 cell.position.x = lastWidgetPosition.x; 61 cell.updateSize(); 62 } 63 64 lastWidgetPosition += lastWidgetInStack.size + lastWidgetInStack.outerOffsetEnd; 65 66 if (lastWidgetInStack.widthType != SizeType.matchParent) { 67 maxSize.x = fmax(maxSize.x, lastWidgetInStack.outerSize.x); 68 } 69 70 if (lastWidgetInStack.heightType != SizeType.matchParent) { 71 maxSize.y = fmax(maxSize.y, lastWidgetInStack.outerSize.y); 72 } 73 } 74 } 75 76 void updateSize() { 77 with (holder) { 78 if (orientation == Orientation.vertical) { 79 if (widthType == SizeType.wrapContent) { 80 size.x = maxSize.x > innerSize.x ? maxSize.x : innerSize.x; 81 } 82 83 if (heightType == SizeType.wrapContent) { 84 if (lastWidgetInStack !is null) { 85 size.y = lastWidgetPosition.y + lastWidgetInStack.outerOffset.bottom + innerOffsetSize.y; 86 } else { 87 // TODO(Andrey): why *2 ? 88 size.y = innerOffsetSize.y * 2; 89 } 90 } 91 } 92 93 if (orientation == Orientation.horizontal) { 94 if (heightType == SizeType.wrapContent) { 95 size.y = maxSize.y > innerSize.y ? maxSize.y : innerSize.y; 96 } 97 98 if (widthType == SizeType.wrapContent) { 99 if (lastWidgetInStack !is null) { 100 size.x = lastWidgetPosition.x + lastWidgetInStack.outerOffset.right + innerOffsetSize.x; 101 } 102 } 103 } 104 } 105 } 106 }