Skip to content

Commit

Permalink
New TextTable methods: .setCellAttr() and variations (methods named: …
Browse files Browse the repository at this point in the history
…set/reset + Cell/Row/Column/Table + Attr()) allowing to modify text attribute of cells (a first step for #166)
  • Loading branch information
cronvel committed Apr 30, 2021
1 parent 21607fb commit b38ff36
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 40 deletions.
6 changes: 2 additions & 4 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module.exports = {
'valid-typeof': 'error' ,
'no-unneeded-ternary': 'error' ,
'no-unused-vars': 'warn' , // During development phase, it's boring to clean unused var since they can be used later
'no-lonely-if': 'error' ,
'no-lonely-if': 'off' , // Can hurt semantic programming
'no-nested-ternary': 'off' , // Now I use the streamlined ternary operator a lot
'no-shadow': 'warn' ,
'no-shadow-restricted-names': 'error' ,
Expand Down Expand Up @@ -62,9 +62,7 @@ module.exports = {
'MemberExpression': 1 ,
'flatTernaryExpressions': true
} ] ,
'newline-per-chained-call': [ 'error', {
'ignoreChainWithDepth': 2
} ] ,
'newline-per-chained-call': 'off',
'no-multi-spaces': 'off' ,
'block-spacing': 'error' ,
'comma-spacing': [ 'error' , {
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@

v2.1.0
------

New TextTable methods: .setCellAttr() and variations (methods named: set/reset + Cell/Row/Column/Table + Attr()) allowing to modify text attribute of cells (a first step for #166)


v2.0.7
------

Expand Down
97 changes: 96 additions & 1 deletion doc/TextTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ TextTable features:

* Methods:
* [.setCellContent()](#ref.TextTable.setCellContent)
* [.setCellAttr()](#ref.TextTable.setCellAttr)
* [.resetCellAttr()](#ref.TextTable.resetCellAttr)
* [.setRowAttr()](#ref.TextTable.setRowAttr)
* [.resetRowAttr()](#ref.TextTable.resetRowAttr)
* [.setColumnAttr()](#ref.TextTable.setColumnAttr)
* [.resetColumnAttr()](#ref.TextTable.resetColumnAttr)
* [.setTableAttr()](#ref.TextTable.setTableAttr)
* [.resetTableAttr()](#ref.TextTable.resetTableAttr)

* Inherit methods and properties from [Element](Element.md#ref.Element.toc)

Expand Down Expand Up @@ -103,10 +111,97 @@ This creates a *TextTable element*.

* x,y `number` the cell coordinate to modify
* content `string` the new content for this table cell
* dontDraw `boolean` when set, the cell content's update does not trigger the *redraw* of the *textTable*
* dontDraw `boolean` when set, the cell content's update does not trigger the *redraw* of the *textTable* (or of the cell's *textBox*
if *dontUpdateLayout* is set)
* dontUpdateLayout `boolean` when set, the table layout is not updated

This update an existing cell content.
The table layout will be updated if needed, except if *dontUpdateLayout* is set.
The content may contain *markup*, but it should have been enabled on the *textTable* creation for this to work.



<a name="ref.TextTable.setCellAttr"></a>
### .setCellAttr( x , y , textAttr , [voidAttr] , [dontDraw] )

* x,y `number` the cell coordinate to modify
* textAttr `object` generic/default attributes for the cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the cell's *textBox*

This update an existing cell text attribute.



<a name="ref.TextTable.resetCellAttr"></a>
### .resetCellAttr( x , y , [dontDraw] )

* x,y `number` the cell coordinate to reset
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the cell's *textBox*

This reset an existing cell text attribute to what it should be, based upon the constructor's parameters.



<a name="ref.TextTable.setRowAttr"></a>
### .setRowAttr( y , textAttr , [voidAttr] , [dontDraw] )

* y `number` the row's index to modify
* textAttr `object` generic/default attributes for the row's cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the *textTable*

This update all cells' text attribute of a row.



<a name="ref.TextTable.resetRowAttr"></a>
### .resetRowAttr( y , [dontDraw] )

* y `number` the row's index to reset
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the *textTable*

This reset all cells' text attribute of a row to what it should be, based upon the constructor's parameters.



<a name="ref.TextTable.setColumnAttr"></a>
### .setColumnAttr( x , textAttr , voidAttr , [dontDraw] )

* x `number` the column's index to modify
* textAttr `object` generic/default attributes for the column's cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the *textTable*

This update all cells's text attribute of a column.



<a name="ref.TextTable.resetColumnAttr"></a>
### .resetColumnAttr( x , [dontDraw] )

* x `number` the column's index to reset
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the *textTable*

This reset all cells' text attribute of a column to what it should be, based upon the constructor's parameters.



<a name="ref.TextTable.setTableAttr"></a>
### .setTableAttr( textAttr , voidAttr , [dontDraw] )

* textAttr `object` generic/default attributes for the table's cell's content (*textBox*)
* voidAttr `object` attributes for the area of the cell (*textBox*) without any text content, default to the *textAttr* argument
* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the *textTable*

This update all cells's text attribute.



<a name="ref.TextTable.resetTableAttr"></a>
### .resetTableAttr( [dontDraw] )

* dontDraw `boolean` when set, the cell attr's update does not trigger the *redraw* of the *textTable*

This reset all cells's text attribute to what it should be, based upon the constructor's parameters.

30 changes: 19 additions & 11 deletions lib/document/TextBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ TextBox.prototype.initChildren = function() {
stateMachine: this.stateMachine
} ) ;

this.textBuffer.setDefaultAttr( this.textAttr ) ;
this.textBuffer.setVoidAttr( this.voidAttr ) ;
this.setAttr( undefined , undefined , true ) ;


if ( this.useAltTextBuffer ) {
Expand All @@ -184,8 +183,7 @@ TextBox.prototype.initChildren = function() {
//, stateMachine: this.stateMachine
} ) ;

this.altTextBuffer.setDefaultAttr( this.altTextAttr ) ;
this.altTextBuffer.setVoidAttr( this.voidAttr ) ;
this.setAltAttr() ;
this.textBuffer.setVoidTextBuffer( this.altTextBuffer ) ;
}

Expand Down Expand Up @@ -384,24 +382,34 @@ TextBox.prototype.autoScrollAndDraw = function( onlyDrawCursor = false ) {



TextBox.prototype.autoScrollAndDrawCursor = function() {
return this.autoScrollAndDraw( true ) ;
} ;
TextBox.prototype.autoScrollAndDrawCursor = function() { return this.autoScrollAndDraw( true ) ; } ;



TextBox.prototype.getContentSize = function() {
return this.textBuffer.getContentSize() ;
TextBox.prototype.setAttr = function( textAttr = this.textAttr , voidAttr = this.voidAttr , dontDraw = false , dontSetContent = false ) {
this.textAttr = textAttr ;
this.voidAttr = voidAttr ;
this.textBuffer.setDefaultAttr( this.textAttr ) ;
this.textBuffer.setVoidAttr( this.voidAttr ) ;

if ( ! dontSetContent ) { this.setContent( this.content , this.contentHasMarkup , dontDraw ) ; }
} ;



TextBox.prototype.getContent = function() {
return this.textBuffer.getText() ;
TextBox.prototype.setAltAttr = function( altTextAttr = this.altTextAttr ) {
this.altTextAttr = altTextAttr ;
this.altTextBuffer.setDefaultAttr( this.altTextAttr ) ;
this.altTextBuffer.setVoidAttr( this.voidAttr ) ;
} ;



TextBox.prototype.getContentSize = function() { return this.textBuffer.getContentSize() ; } ;
TextBox.prototype.getContent = function() { return this.textBuffer.getText() ; } ;



TextBox.prototype.setContent = function( content , hasMarkup , dontDraw ) {
var contentSize ;

Expand Down
137 changes: 116 additions & 21 deletions lib/document/TextTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ function TextTable( options ) {
this.checkerEvenCellTextAttr = options.checkerEvenCellTextAttr || null ;
this.checkerEvenCellVoidAttr = options.checkerEvenCellVoidAttr || null ;

/*
// Select attr
// /!\ NOT IMPLEMENTED YET /!\
// Would allow one to navigate the table (it could be useful for making editable cells)
this.selectedTextAttr = options.selectedTextAttr || null ;
this.selectedVoidAttr = options.selectedVoidAttr || null ;
this.selectable = options.selectable || null ; // Can be 'row', 'column' or 'cell'
this.selectedX = this.selectedY = 0 ;
*/

this.expandToWidth = options.expandToWidth !== undefined ? !! options.expandToWidth : !! options.fit ;
this.shrinkToWidth = options.shrinkToWidth !== undefined ? !! options.shrinkToWidth : !! options.fit ;
this.expandToHeight =
Expand Down Expand Up @@ -136,16 +146,118 @@ TextTable.prototype.setCellContent = function( x , y , content , dontDraw = fals
// We don't add cell, it should already exists
if ( ! textBox ) { return ; }

// For instance, .cellContents is rather useless, but we still update it
// Save cell content
this.cellContents[ y ][ x ] = content ;
textBox.setContent( content , this.contentHasMarkup , true ) ;

if ( ! dontUpdateLayout ) { this.computeCells() ; }
if ( ! dontUpdateLayout ) {
this.computeCells() ;
if ( ! dontDraw ) { this.draw() ; }
}
else {
if ( ! dontDraw ) { textBox.draw() ; }
}
} ;



TextTable.prototype.setCellAttr = function( x , y , textAttr , voidAttr , dontDraw = false ) {
var textBox = this.textBoxes[ y ] && this.textBoxes[ y ][ x ] ;
if ( ! textBox ) { return ; }

if ( voidAttr === undefined ) { voidAttr = textAttr ; }

textBox.setAttr( textAttr , voidAttr , dontDraw ) ;
} ;



TextTable.prototype.resetCellAttr = function( x , y , dontDraw = false ) {
var textBox = this.textBoxes[ y ] && this.textBoxes[ y ][ x ] ;
if ( ! textBox ) { return ; }

var textAttr = this.getTextAttrForCell( x , y ) ,
voidAttr = this.getVoidAttrForCell( x , y , textAttr ) ;

textBox.setAttr( textAttr , voidAttr , dontDraw ) ;
} ;



TextTable.prototype.setRowAttr = function( y , textAttr , voidAttr , dontDraw = false ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.setCellAttr( x , y , textAttr , voidAttr , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;



TextTable.prototype.resetRowAttr = function( y , dontDraw = false ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.resetCellAttr( x , y , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;



TextTable.prototype.setColumnAttr = function( x , textAttr , voidAttr , dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) { this.setCellAttr( x , y , textAttr , voidAttr , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;



TextTable.prototype.resetColumnAttr = function( x , dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) { this.resetCellAttr( x , y , true ) ; }
if ( ! dontDraw ) { this.draw() ; }
} ;



TextTable.prototype.setTableAttr = function( textAttr , voidAttr , dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.setCellAttr( x , y , textAttr , voidAttr , true ) ; }
}

if ( ! dontDraw ) { this.draw() ; }
} ;



TextTable.prototype.resetTableAttr = function( dontDraw = false ) {
for ( let y = 0 ; y < this.rowCount ; y ++ ) {
for ( let x = 0 ; x < this.columnCount ; x ++ ) { this.resetCellAttr( x , y , true ) ; }
}

if ( ! dontDraw ) { this.draw() ; }
} ;



TextTable.prototype.getTextAttrForCell = function( x , y ) {
return this.firstCellTextAttr && ! x && ! y ? this.firstCellTextAttr :
this.firstRowTextAttr && ! y ? this.firstRowTextAttr :
this.firstColumnTextAttr && ! x ? this.firstColumnTextAttr :
this.evenCellTextAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellTextAttr :
this.checkerEvenCellTextAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellTextAttr :
this.evenRowTextAttr && ! ( y % 2 ) ? this.evenRowTextAttr :
this.evenColumnTextAttr && ! ( y % 2 ) ? this.evenColumnTextAttr :
this.textAttr ;
} ;



TextTable.prototype.getVoidAttrForCell = function( x , y , textAttr ) {
return this.firstCellVoidAttr && ! x && ! y ? this.firstCellVoidAttr :
this.firstRowVoidAttr && ! y ? this.firstRowVoidAttr :
this.firstColumnVoidAttr && ! x ? this.firstColumnVoidAttr :
this.evenCellVoidAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellVoidAttr :
this.checkerEvenCellVoidAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellVoidAttr :
this.evenRowVoidAttr && ! ( y % 2 ) ? this.evenRowVoidAttr :
this.evenColumnVoidAttr && ! ( y % 2 ) ? this.evenColumnVoidAttr :
this.voidAttr || textAttr ;
} ;



TextTable.prototype.initChildren = function() {
var row , cellContent , textAttr , voidAttr ;

Expand All @@ -162,25 +274,8 @@ TextTable.prototype.initChildren = function() {
for ( cellContent of row ) {
if ( x >= this.columnCount ) { this.columnCount = x + 1 ; }

textAttr =
this.firstCellTextAttr && ! x && ! y ? this.firstCellTextAttr :
this.firstRowTextAttr && ! y ? this.firstRowTextAttr :
this.firstColumnTextAttr && ! x ? this.firstColumnTextAttr :
this.evenCellTextAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellTextAttr :
this.checkerEvenCellTextAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellTextAttr :
this.evenRowTextAttr && ! ( y % 2 ) ? this.evenRowTextAttr :
this.evenColumnTextAttr && ! ( y % 2 ) ? this.evenColumnTextAttr :
this.textAttr ;

voidAttr =
this.firstCellVoidAttr && ! x && ! y ? this.firstCellVoidAttr :
this.firstRowVoidAttr && ! y ? this.firstRowVoidAttr :
this.firstColumnVoidAttr && ! x ? this.firstColumnVoidAttr :
this.evenCellVoidAttr && ! ( x % 2 ) && ! ( y % 2 ) ? this.evenCellVoidAttr :
this.checkerEvenCellVoidAttr && ! ( ( x + y ) % 2 ) ? this.checkerEvenCellVoidAttr :
this.evenRowVoidAttr && ! ( y % 2 ) ? this.evenRowVoidAttr :
this.evenColumnVoidAttr && ! ( y % 2 ) ? this.evenColumnVoidAttr :
this.voidAttr || textAttr ;
textAttr = this.getTextAttrForCell( x , y ) ;
voidAttr = this.getVoidAttrForCell( x , y , textAttr ) ;

this.textBoxes[ y ][ x ] = new TextBox( {
internal: true ,
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": "2.0.7",
"version": "2.1.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
Loading

0 comments on commit b38ff36

Please sign in to comment.