Skip to content

Commit

Permalink
Now Node.js v14 is required ; ColumnMenu now supports submenu (still …
Browse files Browse the repository at this point in the history
…beta) (#151)
  • Loading branch information
cronvel committed Feb 18, 2021
1 parent 01f1e3f commit c0a0323
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 97 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@

v1.49.0
-------

Now Node.js v14 is required
ColumnMenu now supports submenu (still beta) (#151)


v1.48.1
-------

Expand Down
112 changes: 106 additions & 6 deletions lib/document/BaseMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ function BaseMenu( options = {} ) {
// Things to clear or to force
internal: true ,
parent: null ,
items: null ,
x: undefined , outputX: undefined ,
y: undefined , outputY: undefined ,
items: null
//x: undefined , outputX: undefined ,
//y: undefined , outputY: undefined ,
//width: undefined , outputWidth: undefined ,
//height: undefined , outputHeight: undefined ,
//submenu: false
} ) ;

if ( options.submenu && typeof options.submenu === 'object' ) {
Object.assign( this.submenuOptions , options.submenu ) ;
}
Expand All @@ -90,6 +90,7 @@ function BaseMenu( options = {} ) {
this.onButtonToggle = this.onButtonToggle.bind( this ) ;
this.onButtonFocus = this.onButtonFocus.bind( this ) ;
this.onButtonBlinked = this.onButtonBlinked.bind( this ) ;
this.onSubmenuSubmit = this.onSubmenuSubmit.bind( this ) ;
this.onKey = this.onKey.bind( this ) ;
this.onWheel = this.onWheel.bind( this ) ;
this.onFocus = this.onFocus.bind( this ) ;
Expand Down Expand Up @@ -286,6 +287,20 @@ BaseMenu.prototype.onKey = function( key , trash , data ) {
this.toPage( this.maxPage , 'cycle' ) ;
}
break ;
case 'parentMenu' :
if ( this.isSubmenu ) {
// Back up the parent, because current instance can be destroyed by parent.closeSubmenu()
let parent = this.parent ;
if ( this.parent.submenuOptions.hideParent ) { this.parent.closeSubmenu() ; }
parent.document.giveFocusTo( parent ) ;
}
break ;
case 'submenu' :
if ( this.hasSubmenu && this.focusChild?.def?.items ) {
this.openSubmenu( this.focusChild.value , this.focusChild ) ;
if ( this.submenu ) { this.document.giveFocusTo( this.submenu ) ; }
}
break ;
default :
return ; // Bubble up
}
Expand Down Expand Up @@ -330,7 +345,7 @@ BaseMenu.prototype.onButtonSubmit = function( buttonValue , action , button ) {
if ( this.submenuOptions.openOn === 'parentSubmit' ) {
this.openSubmenu( button.value , button ) ;
}

if ( this.submenu ) {
this.document.giveFocusTo( this.submenu ) ;
}
Expand Down Expand Up @@ -378,6 +393,92 @@ BaseMenu.prototype.onButtonFocus = function( focus , type , button ) {



BaseMenu.prototype.onSubmenuSubmit = function( buttonValue , action , button ) {
button.once( 'blinked' , ( buttonValue_ , reserved , button_ ) => {
if ( this.submenuOptions.closeOn === 'childSubmit' ) {
this.closeSubmenu() ;
this.document.giveFocusTo( this.submenuParentButton || this ) ;
}
this.emit( 'blinked' , buttonValue_ , reserved , this ) ;
} ) ;

this.emit( 'submit' , buttonValue , action , this ) ;
} ;



// Userland: .submenu( itemValue )
// Internal: .submenu( itemValue , button )
BaseMenu.prototype.openSubmenu = function( itemValue , button = null ) {
var x , y , width , height ,
itemDef = button ? this.itemsDef.find( it => it === button.def ) :
this.itemsDef.find( it => it.value === itemValue ) ;

if ( ! itemDef || ! itemDef.items || ! itemDef.items.length ) { return ; }

if ( this.submenu ) {
if ( this.submenu.def === itemDef ) { return ; }
this.closeSubmenu() ;
}

this.submenuParentButton = button ;

switch ( this.submenuOptions.disposition ) {
case 'overwrite' :
x = this.outputX ;
y = this.outputY ;
//width = this.outputWidth ;
width = this.submenuOptions.width ;
//height = this.outputHeight ;
height = this.submenuOptions.height ;
break ;
case 'right' :
default :
x = this.outputX + this.outputWidth ;
y = this.outputY ;
width = this.submenuOptions.width || this.outputWidth ;
break ;
}

if ( this.submenuOptions.hideParent ) {
this.children.forEach( e => e.hidden = true ) ;
}

//this.submenu = new ColumnMenu( Object.assign( {} , this.submenuOptions , {
this.submenu = new this.constructor( Object.assign( {} , this.submenuOptions , {
internal: true ,
parent: this ,
isSubmenu: true ,
def: itemDef ,
outputX: x ,
outputY: y ,
outputWidth: width ,
outputHeight: height ,
items: itemDef.items ,
noDraw: true
} ) ) ;

this.redraw() ;

if ( this.submenuOptions.focusOnOpen ) {
this.document.giveFocusTo( this.submenu ) ;
}

this.submenu.on( 'submit' , this.onSubmenuSubmit ) ;
} ;



BaseMenu.prototype.closeSubmenu = function() {
if ( ! this.submenu ) { return false ; }
if ( this.submenuOptions.hideParent ) { this.children.forEach( e => e.hidden = false ) ; }
this.submenu.destroy() ;
this.submenu = null ;
return true ;
} ;



// Should be redefined in the derivative class
BaseMenu.prototype.defaultOptions = {} ;
BaseMenu.prototype.keyBindings = {} ;
Expand All @@ -387,6 +488,5 @@ BaseMenu.prototype.toggleButtonKeyBindings = {} ;
BaseMenu.prototype.toggleButtonActionKeyBindings = {} ;
BaseMenu.prototype.initPage = function() {} ;
BaseMenu.prototype.onButtonToggle = function() {} ;
BaseMenu.prototype.submenu = function() {} ;
BaseMenu.prototype.childUseParentKeyValue = false ;

89 changes: 3 additions & 86 deletions lib/document/ColumnMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ function ColumnMenu( options ) {
options = ! options ? {} : options.internal ? options : Object.create( options ) ;
options.internal = true ;

this.onSubmenuSubmit = this.onSubmenuSubmit.bind( this ) ;
this.onParentResize = this.onParentResize.bind( this ) ;

// Overwritten by Element() when .autoWidth is set
Expand Down Expand Up @@ -135,7 +134,9 @@ ColumnMenu.prototype.keyBindings = {
// ENTER: 'submit' ,
// KP_ENTER: 'submit' ,
ALT_ENTER: 'submit' ,
ESC: 'parent'
ESC: 'parentMenu' ,
LEFT: 'parentMenu' ,
RIGHT: 'submenu'
} ;

ColumnMenu.prototype.buttonKeyBindings = {
Expand Down Expand Up @@ -430,90 +431,6 @@ ColumnMenu.prototype.initPage = function( page = this.page ) {



// Userland: .submenu( itemValue )
// Internal: .submenu( itemValue , button )
ColumnMenu.prototype.openSubmenu = function( itemValue , button = null ) {
var x , y , width , height ,
itemDef = button ? this.itemsDef.find( it => it === button.def ) :
this.itemsDef.find( it => it.value === itemValue ) ;

if ( ! itemDef || ! itemDef.items || ! itemDef.items.length ) { return ; }

if ( this.submenu ) {
if ( this.submenu.def === itemDef ) { return ; }
else { this.closeSubmenu() ; }
}

this.submenuParentButton = button ;

switch ( this.submenuOptions.disposition ) {
case 'overwrite' :
x = this.outputX ;
y = this.outputY ;
width = this.outputWidth ;
height = this.outputHeight ;
break ;
case 'right' :
default :
x = this.outputX + this.outputWidth ;
y = this.outputY ;
width = this.submenuOptions.width || this.outputWidth ;
break ;
}

if ( this.submenuOptions.hideParent ) {
this.children.forEach( e => e.hidden = true ) ;
}

this.submenu = new ColumnMenu( Object.assign( {} , this.submenuOptions , {
internal: true ,
parent: this ,
isSubmenu: true ,
def: itemDef ,
outputX: x ,
outputY: y ,
outputWidth: width ,
outputHeight: height ,
items: itemDef.items ,
noDraw: true
} ) ) ;

this.redraw() ;

if ( this.submenuOptions.focusOnOpen ) {
this.document.giveFocusTo( this.submenu ) ;
}

this.submenu.on( 'submit' , this.onSubmenuSubmit ) ;
} ;



ColumnMenu.prototype.closeSubmenu = function() {
if ( ! this.submenu ) { return false ; }
this.submenu.destroy() ;
this.submenu = null ;
return true ;
} ;



ColumnMenu.prototype.onSubmenuSubmit = function( buttonValue , action , button ) {
button.once( 'blinked' , ( buttonValue_ , reserved , button_ ) => {
if ( this.submenuOptions.hideParent ) { this.children.forEach( e => e.hidden = false ) ; }
if ( this.submenuOptions.closeOn === 'childSubmit' ) {
this.closeSubmenu() ;
this.document.giveFocusTo( this.submenuParentButton || this ) ;
//this.document.giveFocusTo( this ) ;
}
this.emit( 'blinked' , buttonValue_ , reserved , this ) ;
} ) ;

this.emit( 'submit' , buttonValue , action , this ) ;
} ;



ColumnMenu.prototype.onParentResize = function() {
if ( ! this.autoWidth && ! this.autoHeight ) { return ; }

Expand Down
6 changes: 3 additions & 3 deletions lib/terminfo/terminfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function getTerminfoBuffer( termName ) {


function parseTermBuffer( bufPair , termName ) {
var i , getInt , intSize ,
var i , j , getInt , intSize ,
buf = bufPair.buf ,
offset = 0 ;

Expand Down Expand Up @@ -148,8 +148,8 @@ function parseTermBuffer( bufPair , termName ) {
}
*/

boolOptions.forEach( ( opt , i ) => {
result[opt] = Boolean( buf.readInt8( offset + i ) ) ;
boolOptions.forEach( ( opt , j ) => {
result[ opt ] = Boolean( buf.readInt8( offset + j ) ) ;
} ) ;

offset += result.boolSize ;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "terminal-kit",
"version": "1.48.1",
"version": "1.49.0",
"description": "256 colors, keys and mouse, input field, progress bars, screen buffer (including 32-bit composition and image loading), text buffer, and many more... Whether you just need colors and styles, build a simple interactive command line tool or a complexe terminal app: this is the absolute terminal lib for Node.js!",
"main": "lib/termkit.js",
"directories": {
Expand Down
2 changes: 2 additions & 0 deletions sample/document/column-menu-submenu-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ var columnMenu = new termkit.ColumnMenu( {
disposition: 'overwrite' ,
hideParent: true ,
openOn: 'parentBlinked' ,
closeOn: 'childSubmit' ,
focusOnOpen: true ,
//*/

//*
disposition: 'right' ,
hideParent: false ,
Expand Down
2 changes: 1 addition & 1 deletion sample/document/column-menu-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ var submitCount = 0 , focusCount = 0 ;

function onSubmit( buttonValue , action ) {
//console.error( 'Submitted: ' , value ) ;
if ( buttonValue === 'view' ) { columnMenu.setItem( buttonValue , { content: 'bob' } ) ; }
//if ( buttonValue === 'view' ) { columnMenu.setItem( buttonValue , { content: 'bob' } ) ; }

term.saveCursor() ;
term.moveTo.styleReset.eraseLine( 1 , 22 , 'Submitted #%i: %s %s\n' , submitCount ++ , buttonValue , action ) ;
Expand Down

0 comments on commit c0a0323

Please sign in to comment.