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 }