1 module rpui.widgets_container; 2 3 import std.container.array; 4 import rpui.widget; 5 import rpui.events; 6 7 package final class WidgetsContainer { 8 Widget rootWidget; 9 private Array!Widget widgets; 10 Widget delegate(Widget) decorator = null; 11 12 this(Widget widget) { 13 this.rootWidget = widget; 14 } 15 16 package void decorateWidgets(Widget delegate(Widget) decorator) { 17 if (this.decorator is null) { 18 this.decorator = decorator; 19 } 20 } 21 22 void deleteWidget(Widget targetWidget) { 23 deleteWidget(targetWidget.id); 24 } 25 26 void deleteWidget(in size_t id) { 27 } 28 29 void clear() { 30 widgets.clear(); 31 } 32 33 void addWidget(Widget widget) { 34 if (decorator is null) { 35 addWidgetWithoutDecorator(widget); 36 return; 37 } 38 39 auto decoratedWidget = decorator(widget); 40 addWidgetWithoutDecorator(decoratedWidget); 41 decoratedWidget.children.addWidget(widget); 42 } 43 44 void addWidgetWithoutDecorator(Widget widget) { 45 widget.view_ = rootWidget.view_; 46 47 widget.events.subscribeWidget(widget); 48 rootWidget.events.join(widget.events, windowEvents ~ commands); 49 50 if (widgets.length == 0) { 51 rootWidget.p_firstWidget = widget; 52 rootWidget.p_lastWidget = widget; 53 } 54 55 // Links 56 widget.p_parent = rootWidget; 57 widget.owner = rootWidget; 58 widget.p_nextWidget = rootWidget.p_firstWidget; 59 widget.p_prevWidget = rootWidget.p_lastWidget; 60 widget.p_depth = rootWidget.p_depth + 1; 61 62 rootWidget.p_lastWidget.p_nextWidget = widget; 63 rootWidget.p_firstWidget.p_prevWidget = widget; 64 rootWidget.p_lastWidget = widget; 65 66 // Insert 67 widgets.insert(widget); 68 rootWidget.view.widgetOrdering.insert(widget); 69 widget.onCreate(); 70 } 71 72 @property size_t length() const { 73 return widgets.length(); 74 } 75 76 @property bool empty() const { 77 return widgets.empty; 78 } 79 80 @property ref inout(Widget) front() inout { 81 return widgets.front; 82 } 83 84 @property ref inout(Widget) back() inout { 85 return widgets.back; 86 } 87 88 int opApply(int delegate(Widget) apply) { 89 int result = 0; 90 91 foreach (widget; widgets) { 92 result = apply(widget); 93 94 if (result) { 95 break; 96 } 97 } 98 99 return result; 100 } 101 }