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.base.keyboard; 8 9 /// A template that declares methods related to Keyboard. 10 template Keyboard () 11 { 12 protected Widget _focusChain; 13 @property focusChain () { return _focusChain; } 14 15 void setFocusChain ( Widget w ) 16 { 17 if ( w ) { 18 enforce( w.focusable, 19 "Cannot chain the unfocusable widget." ); 20 _focusChain = w; 21 } else { 22 _focusChain = null; 23 } 24 } 25 26 bool pullFocusChain () 27 { 28 if ( _focusChain && isFocused ) { 29 _context.setFocused( _focusChain ); 30 return true; 31 } 32 return false; 33 } 34 35 36 @property isFocused () 37 { 38 return _context && _context.focused is this; 39 } 40 @property bool focusable () 41 { 42 return true; 43 } 44 void focus () 45 { 46 if ( focusable ) { 47 enforce( _context, "WindowContext is null." ); 48 _context.setFocused( this ); 49 } 50 } 51 void dropFocus () 52 { 53 enforce( isFocused, "The widget has not been focused." ); 54 _context.setFocused( null ); 55 } 56 57 58 bool handleKey ( Key key, KeyState status ) 59 { 60 if ( !isFocused ) { 61 if ( _context.focused ) { 62 return _context.focused.handleKey( key, status ); 63 } else if ( calcedChildren.canFind!(x => x.handleKey( key, status )) ) { 64 return true; 65 } 66 } 67 68 const pressing = status != KeyState.Release; 69 if ( key == Key.LeftShift ) { 70 _context.setModkeyStatus( Modkey.Shift, pressing ); 71 } else if ( key == Key.LeftControl ) { 72 _context.setModkeyStatus( Modkey.Ctrl, pressing ); 73 74 } else if ( key == Key.Tab && pressing ) { 75 return pullFocusChain(); 76 } 77 return false; 78 } 79 80 bool handleTextInput ( dchar c ) 81 { 82 if ( _context.focused && !isFocused ) { 83 return _context.focused.handleTextInput( c ); 84 } 85 return false; 86 } 87 88 void handleFocused ( bool a ) 89 { 90 (a? &enableState: &disableState)( WidgetState.Focused ); 91 } 92 }