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 }