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 if (!cell.associatedWidget.isVisible) { 50 return; 51 } 52 53 with (holder) { 54 lastWidgetInStack = cell.firstWidget; 55 56 if (orientation == Orientation.vertical) { 57 cell.widthType = SizeType.matchParent; 58 cell.size.y = lastWidgetInStack.outerSize.y; 59 cell.position.y = lastWidgetPosition.y; 60 cell.updateSize(); 61 } else { 62 cell.size.x = lastWidgetInStack.outerSize.x; 63 cell.heightType = SizeType.matchParent; 64 cell.position.x = lastWidgetPosition.x; 65 cell.updateSize(); 66 } 67 68 lastWidgetPosition += lastWidgetInStack.size + lastWidgetInStack.outerOffsetEnd; 69 70 if (lastWidgetInStack.widthType != SizeType.matchParent) { 71 maxSize.x = fmax(maxSize.x, lastWidgetInStack.outerSize.x); 72 } 73 74 if (lastWidgetInStack.heightType != SizeType.matchParent) { 75 maxSize.y = fmax(maxSize.y, lastWidgetInStack.outerSize.y); 76 } 77 } 78 } 79 80 void updateSize() { 81 with (holder) { 82 if (orientation == Orientation.vertical) { 83 if (widthType == SizeType.wrapContent) { 84 size.x = maxSize.x > innerSize.x ? maxSize.x : innerSize.x; 85 } 86 87 if (heightType == SizeType.wrapContent) { 88 if (lastWidgetInStack !is null) { 89 size.y = lastWidgetPosition.y + lastWidgetInStack.outerOffset.bottom + innerOffsetSize.y; 90 } else { 91 // TODO(Andrey): why *2 ? 92 size.y = innerOffsetSize.y * 2; 93 } 94 } 95 } 96 97 if (orientation == Orientation.horizontal) { 98 if (heightType == SizeType.wrapContent) { 99 size.y = maxSize.y > innerSize.y ? maxSize.y : innerSize.y; 100 } 101 102 if (widthType == SizeType.wrapContent) { 103 if (lastWidgetInStack !is null) { 104 size.x = lastWidgetPosition.x + lastWidgetInStack.outerOffset.right + innerOffsetSize.x; 105 } 106 } 107 } 108 } 109 } 110 }