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 }