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 }