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