@@ -7,14 +7,17 @@ import { OwlComponent } from '../../../plugin-owl/src/OwlComponent';
77import { CommandIdentifier , CommandParams } from '../../../core/src/Dispatcher' ;
88import { nodeName } from '../../../utils/src/utils' ;
99import { hooks } from '@odoo/owl' ;
10+ import { ProcessKeydownParams } from '../../../plugin-dom-layout/src/DomLayout' ;
1011
11- ////////////////////////////// todo: use API ///////////////////////////////////
12+ const keystrokeDiv = document . createElement ( 'div' ) ;
13+ keystrokeDiv . id = 'keys_log' ;
1214
1315interface DevToolsState {
1416 closed : boolean ; // Are the devtools open?
1517 height : number ; // In px
1618 currentTab : string ; // Name of the current tab
1719 commands : Array < [ CommandIdentifier , CommandParams ] > ;
20+ displayKeystrokes : boolean ;
1821}
1922
2023export class DevToolsComponent < T = { } > extends OwlComponent < T > {
@@ -33,18 +36,34 @@ export class DevToolsComponent<T = {}> extends OwlComponent<T> {
3336 currentTab : 'inspector' ,
3437 height : 300 ,
3538 commands : [ ] , // Stack of all commands executed since init.
39+ displayKeystrokes : false ,
3640 } ;
37- localStorage = [ 'closed' , 'currentTab' , 'height' ] ;
41+ localStorage = [ 'closed' , 'currentTab' , 'height' , 'displayKeystrokes' ] ;
3842 // For resizing/opening (see toggleClosed)
3943 _heightOnLastMousedown : number ;
4044
4145 async willStart ( ) : Promise < void > {
4246 this . env . editor . dispatcher . registerCommandHook ( '*' , this . addCommand . bind ( this ) ) ;
4347 this . env . editor . dispatcher . registerCommandHook ( '@commit' , this . render . bind ( this ) ) ;
48+ this . env . editor . dispatcher . registerCommandHook (
49+ '@layout-keydown' ,
50+ this . displayKeystroke . bind ( this ) ,
51+ ) ;
4452 return super . willStart ( ) ;
4553 }
54+ async mounted ( ) : Promise < void > {
55+ if ( this . state . displayKeystrokes ) {
56+ if ( ! document . getElementById ( 'keys_log' ) ) {
57+ document . body . appendChild ( keystrokeDiv ) ;
58+ }
59+ }
60+ return super . mounted ( ) ;
61+ }
4662 willUnmount ( ) : void {
4763 this . state . commands = [ ] ;
64+ if ( this . state . displayKeystrokes && keystrokeDiv . parentNode === document . body ) {
65+ document . body . removeChild ( keystrokeDiv ) ;
66+ }
4867 }
4968
5069 //--------------------------------------------------------------------------
@@ -69,6 +88,45 @@ export class DevToolsComponent<T = {}> extends OwlComponent<T> {
6988 this . state . currentTab = 'inspector' ;
7089 ( this . inspectorRef . comp as InspectorComponent ) ?. inspectDom ( ) ;
7190 }
91+ /**
92+ * Toggle display keystrokes.
93+ */
94+ toggleKeystrokes ( ) : void {
95+ this . state . displayKeystrokes = ! this . state . displayKeystrokes ;
96+ if ( this . state . displayKeystrokes ) {
97+ if ( ! document . getElementById ( 'keys_log' ) ) {
98+ document . body . appendChild ( keystrokeDiv ) ;
99+ }
100+ } else if ( keystrokeDiv . parentNode === document . body ) {
101+ document . body . removeChild ( keystrokeDiv ) ;
102+ }
103+ }
104+ /**
105+ * Display the key hit on the screen.
106+ *
107+ * @param params
108+ */
109+ displayKeystroke ( params : ProcessKeydownParams ) : void {
110+ if ( ! this . state . displayKeystrokes ) return ;
111+ const ev = params . event ;
112+ keystrokeDiv . textContent = '' ;
113+ keystrokeDiv . className = '' ;
114+ if ( [ 'Control' , 'Alt' , 'Shift' , 'Meta' ] . includes ( ev . key ) ) {
115+ keystrokeDiv . className = 'has-key' ;
116+ keystrokeDiv . textContent = `'${ ev . key } '` ;
117+ } else if ( ev . key ) {
118+ keystrokeDiv . className = 'has-key' ;
119+ const keyModifiers = [
120+ ev . metaKey ? 'Meta+' : false ,
121+ ev . ctrlKey ? 'Ctrl+' : false ,
122+ ev . shiftKey ? 'Shift+' : false ,
123+ ev . altKey ? 'Alt+' : false ,
124+ ]
125+ . filter ( mod => mod )
126+ . join ( '' ) ;
127+ keystrokeDiv . textContent = `${ keyModifiers } '${ ev . key } '` ;
128+ }
129+ }
72130 /**
73131 * Add the recent dispatching of the given command with the given arguments.
74132 */
0 commit comments