1 module rpui.widgets.drop_list_menu.drop_menu_delegate; 2 3 import rpui.primitives; 4 import rpui.math; 5 import rpui.widget; 6 import rpui.widgets.list_menu.widget; 7 8 struct DropMenuDelegate { 9 private ListMenu menu; 10 private Widget widget; 11 12 bool isInVisibilityArea = false; 13 bool isInMenuArea = false; 14 private bool isAttached_ = false; 15 16 bool isAttached() const { 17 return isAttached_; 18 } 19 20 void attach(ListMenu menu, Widget widget) { 21 this.menu = menu; 22 this.widget = widget; 23 isAttached_ = true; 24 } 25 26 void onProgress(in vec2 dropOffset) { 27 const visibleBorderStart = vec2( 28 menu.measure.extraMenuVisibleBorder.left, 29 menu.measure.extraMenuVisibleBorder.top 30 ); 31 const visibleBorderEnd = vec2( 32 menu.measure.extraMenuVisibleBorder.right, 33 menu.measure.extraMenuVisibleBorder.bottom 34 ); 35 36 const extraStartArea = vec2(menu.measure.popupExtraPadding.left, menu.measure.popupExtraPadding.top); 37 const extraEndArea = vec2(menu.measure.popupExtraPadding.right, menu.measure.popupExtraPadding.bottom); 38 39 const visibileArea = Rect( 40 widget.absolutePosition - visibleBorderStart, 41 dropOffset + menu.size + visibleBorderEnd + visibleBorderStart 42 ); 43 44 const menuArea = Rect( 45 menu.absolutePosition + extraStartArea, 46 menu.size - extraStartArea - extraEndArea 47 ); 48 49 bool oneOfItemIsEnter = false; 50 51 foreach (Widget child; menu.children) { 52 const row = child.associatedWidget; 53 oneOfItemIsEnter = oneOfItemIsEnter || row.isEnter || row.overrideIsEnter; 54 } 55 56 isInVisibilityArea = pointInRect(menu.view.mousePos, visibileArea) || oneOfItemIsEnter; 57 isInMenuArea = pointInRect(menu.view.mousePos, menuArea); 58 59 if (!isInVisibilityArea) { 60 hideMenu(); 61 } 62 } 63 64 void toggleMenu(in vec2 dropOffset) { 65 if (!menu.isVisible) { 66 dropMenu(dropOffset); 67 } else { 68 hideMenu(); 69 } 70 } 71 72 void dropMenu(in vec2 dropOffset) { 73 menu.position = widget.absolutePosition + dropOffset + menu.measure.downPopupOffset; 74 menu.isVisible = true; 75 } 76 77 void hideMenu() { 78 menu.isVisible = false; 79 menu.hideAllSubMenus(); 80 } 81 }