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.input.select;
8 import w4d.parser.colorset,
9 w4d.style.rect,
10 w4d.style.scalar,
11 w4d.task.window,
12 w4d.widget.popup.menu,
13 w4d.widget.base,
14 w4d.widget.panel,
15 w4d.event,
16 w4d.exception;
17 import g4d.glfw.cursor;
18 import gl3n.linalg;
19
20 /// A handler that handles changing selection.
21 alias SelectChanged = EventHandler!( void, int );
22
23 /// A widget of select input.
24 class SelectInputWidget : PanelWidget
25 {
26 protected class CustomPopupMenuWidget : PopupMenuWidget
27 {
28 this ()
29 {
30 super();
31 }
32 }
33
34 protected CustomPopupMenuWidget _menu;
35 protected Widget _selected;
36
37 ///
38 override @property Widget[] children ()
39 {
40 return _selected? [_selected]: [];
41 }
42
43 ///
44 override bool handleMouseButton ( MouseButton btn, bool status, vec2 pos )
45 {
46 if ( super.handleMouseButton(btn,status,pos) ) return true;
47
48 if ( !style.isPointInside( pos ) ) return false;
49 if ( btn == MouseButton.Left && !status ) {
50 openMenu();
51 return true;
52 }
53 return false;
54 }
55
56 ///
57 override @property const(Cursor) cursor ()
58 {
59 return Cursor.Hand;
60 }
61
62 ///
63 this ()
64 {
65 super();
66 _menu = new CustomPopupMenuWidget;
67 _selected = null;
68
69 parseColorSetsFromFile!"colorset/selectinput.yaml"( style );
70 style.box.borderWidth = Rect(1.pixel);
71 style.box.paddings = Rect(1.mm);
72 style.box.margins = Rect(1.mm);
73 }
74
75 /// Changes selection.
76 void select ( MenuItemWidget s )
77 {
78 _selected = s.child;
79 requestLayout();
80 }
81 /// Opens select menu.
82 void openMenu ()
83 {
84 enforce( _context, "WindowContext is null." );
85
86 auto size = style.box.borderInsideSize;
87 auto late = style.box.borderInsideLeftTop;
88 late.y += size.y;
89 late += style.translate;
90
91 _context.setPopup( _menu );
92 _menu.move( late, vec2( size.x, 0 ) );
93 }
94
95 /// Adds an itme.
96 void addItem ( MenuItemWidget i )
97 {
98 i.onPress = () {
99 select( i );
100 return true;
101 };
102 _menu.addItem( i );
103 }
104 /// Removes an item.
105 void removeItem ( MenuItemWidget i )
106 {
107 _menu.removeItem( i );
108 }
109 /// Removes all items.
110 void removeAllItems ()
111 {
112 _menu.removeAllItems();
113 }
114
115 ///
116 override @property bool trackable () { return true; }
117 ///
118 override @property bool focusable () { return true; }
119 }