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 }