1 // Written in the D programming language. 2 /++ 3 + Authors: KanzakiKino 4 + Copyright: KanzakiKino 2018 5 + License: LGPL-3.0 6 ++/ 7 module w4d.widget.popup.menu; 8 import w4d.layout.lineup, 9 w4d.parser.colorset, 10 w4d.style.rect, 11 w4d.style.scalar, 12 w4d.task.window, 13 w4d.widget.popup.base, 14 w4d.widget.wrapper, 15 w4d.event; 16 import g4d.ft.font; 17 import gl3n.linalg; 18 19 /// A widget of popup menu. 20 class PopupMenuWidget : PopupWidget 21 { 22 /// 23 override bool handleMouseButton ( MouseButton b, bool status, vec2 pos ) 24 { 25 if ( super.handleMouseButton(b,status,pos) ) return true; 26 27 if ( status && !style.isPointInside( pos ) ) { 28 close(); 29 return true; 30 } 31 return false; 32 } 33 34 /// 35 this () 36 { 37 super(); 38 39 parseColorSetsFromFile!"colorset/menu.yaml"( style ); 40 setLayout!VerticalLineupLayout; 41 style.box.borderWidth = Rect(1.pixel); 42 } 43 mixin DisableModifyChildren; 44 45 /// Adds the item. 46 void addItem ( MenuItemWidget i ) 47 { 48 i._parentMenu = this; 49 super.addChild( i ); 50 } 51 /// Removes the item. 52 void removeItem ( MenuItemWidget i ) 53 { 54 super.removeChild( i ); 55 } 56 /// Removes all items. 57 void removeAllItems () 58 { 59 super.removeAllChildren(); 60 } 61 } 62 63 /// A handler that handles pressing menu items. 64 alias PressHandler = EventHandler!( bool ); 65 66 /// A widget of menu item. 67 class MenuItemWidget : WrapperWidget 68 { 69 protected PopupMenuWidget _parentMenu; 70 71 /// 72 PressHandler onPress; 73 74 /// 75 override bool handleMouseButton ( MouseButton btn, bool status, vec2 pos ) 76 { 77 if ( super.handleMouseButton(btn,status,pos) ) return true; 78 79 if ( !style.isPointInside( pos ) ) return false; 80 if ( btn == MouseButton.Left && !status ) { 81 if ( onPress.call() ) { 82 _parentMenu.close(); 83 } 84 return true; 85 } 86 return false; 87 } 88 89 /// 90 this () 91 { 92 super(); 93 94 _parentMenu = null; 95 96 parseColorSetsFromFile!"colorset/menuitem.yaml"( style ); 97 setLayout!HorizontalLineupLayout; 98 style.box.paddings = Rect(1.mm); 99 } 100 }