@@ -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