1 module rpui.widgets.list_menu_item.widget;
2 
3 import rpui.events;
4 import rpui.widget_events;
5 import rpui.input;
6 import rpui.math;
7 import rpui.primitives;
8 import rpui.widget;
9 import rpui.widgets.button.widget;
10 import rpui.widgets.list_menu.widget;
11 import rpui.widgets.list_menu_item.renderer;
12 import rpui.widgets.drop_list_menu.drop_menu_delegate;
13 
14 interface MenuActions {
15     void hideMenu();
16 
17     MenuActions parentActions();
18 }
19 
20 class ListMenuItem : Button, MenuActions {
21     @field string shortcut = "";
22 
23     private ListMenu parentMenu = null;
24     package ListMenu menu = null;
25     private DropMenuDelegate dropMenuDelegate;
26 
27     this(in string style = "ListMenuItem") {
28         super(style);
29 
30         this.renderer = new ListMenuItemRenderer();
31         this.textAlign = Align.left;
32         this.widthType = SizeType.matchParent;
33         this.focusable = false;
34     }
35 
36     protected override void onPostCreate() {
37         super.onPostCreate();
38 
39         if (menu !is null)
40             return;
41 
42         // Because item places in wrapper called Cell.
43         parentMenu = cast(ListMenu) parent.parent;
44         assert(parentMenu !is null);
45 
46         events.subscribe!ClickEvent(&onClick);
47 
48         if (children.empty)
49             return;
50 
51         menu = cast(ListMenu)(children.front);
52 
53         if (menu is null)
54             return;
55 
56         menu.isVisible = false;
57         menu.focusable = false;
58         view.moveWidgetToFront(menu);
59 
60         dropMenuDelegate.attach(menu, this);
61 
62         // submenuDisplayTimeout = createTimeout(menu.displayDelay, delegate() {
63             if (isEnter) {
64                 dropMenuDelegate.dropMenu(vec2(size.x, 0) + menu.measure.rightPopupOffset);
65             }
66         // });
67     }
68 
69     override void onProgress(in ProgressEvent event) {
70         super.onProgress(event);
71 
72         // submenuDisplayTimeout.onProgress(app.deltaTime);
73 
74         if (isEnter) {
75             parentMenu.hideAllSubMenusExcept(this);
76         }
77 
78         // if (isEnter && !submenuDisplayTimeout.isStarted()) {
79             // submenuDisplayTimeout.start();
80         // }
81 
82         if (dropMenuDelegate.isAttached()) {
83             dropMenuDelegate.onProgress(vec2(size.x, 0) + menu.measure.rightPopupOffset);
84             overrideIsEnter = dropMenuDelegate.isInVisibilityArea && menu.isVisible;
85         }
86     }
87 
88     private void onClick() {
89         if (menu is null)
90             hideRootMenu();
91 
92         if (dropMenuDelegate.isAttached()) {
93             dropMenuDelegate.dropMenu(vec2(size.x, 0) + menu.measure.rightPopupOffset);
94         }
95     }
96 
97     override void focus() {
98         /* Ignore */
99     }
100 
101     override void hideMenu() {
102         if (dropMenuDelegate.isAttached()) {
103             dropMenuDelegate.hideMenu();
104         }
105     }
106 
107     private void hideRootMenu() {
108         MenuActions currentMenuActions = this;
109         MenuActions parentMenuActions = parentActions();
110 
111         while (parentMenuActions !is null) {
112             currentMenuActions = parentMenuActions;
113             parentMenuActions = parentMenuActions.parentActions();
114         }
115 
116         currentMenuActions.hideMenu();
117     }
118 
119     override MenuActions parentActions() {
120         auto actions = cast(MenuActions) parentMenu.owner;
121         return actions;
122     }
123 }