@@ -4,10 +4,16 @@ import chalk from "chalk";
4
4
export default class IRenderable {
5
5
6
6
// Constructor
7
- constructor ( viewport ) {
7
+ constructor ( name ) {
8
+ /*
8
9
if (viewport) {
9
10
this._nominal.viewportWidth = viewport.width ?? this.sizes.UNSET;
10
11
this._nominal.viewportHeight = viewport.height ?? this.sizes.UNSET;
12
+ }*/
13
+ if ( name ) {
14
+ this . name = name ;
15
+ } else {
16
+ throw new Error ( 'Name is required for all renderables' ) ;
11
17
}
12
18
}
13
19
@@ -48,9 +54,11 @@ export default class IRenderable {
48
54
BOTTOM_RIGHT : 7
49
55
}
50
56
51
- scrollbarStyle = {
57
+ styles = {
52
58
railColor : [ 45 , 55 , 80 ] ,
53
59
headColor : [ 80 , 100 , 120 ] ,
60
+ borderBlur : [ 100 , 110 , 140 ] ,
61
+ borderFocus : [ 255 , 255 , 255 ]
54
62
}
55
63
56
64
// Getters and setters
@@ -229,6 +237,61 @@ export default class IRenderable {
229
237
}
230
238
}
231
239
240
+ _debug = {
241
+ _enabled : false ,
242
+ enable : ( ) => { this . _debug . _enabled = true ; } ,
243
+ disable : ( ) => { this . _debug . _enabled = false ; } ,
244
+ getTitleBarInfo : ( delim ) => {
245
+ let { width, height } = this . getSize ( ) ;
246
+ let viewport = this . getViewport ( false ) ;
247
+ if ( this . _debug . _enabled ) {
248
+ let fill = width - 1 ;
249
+ let debugText = "" ;
250
+
251
+ useRealLength ( ) ;
252
+ //debugText = `${width}x${height}`;
253
+ let perecedence = [
254
+ { text : `${ width } x${ height } ` , prepend : false } ,
255
+ { text : `${ viewport . width } x${ viewport . height } ` , prepend : false } ,
256
+ { text : `${ this . _nominal . scrollX } x${ this . _nominal . scrollY } ` , prepend : false } ,
257
+ { text : this . name , prepend : true } ,
258
+ ] ;
259
+
260
+ let tempText = [ ] ;
261
+ let tempFill = fill ;
262
+ for ( let i = 0 ; i < perecedence . length ; i ++ ) {
263
+ let { text, prepend } = perecedence [ i ] ;
264
+ //let spacer = Math.min(tempText.length, 1);
265
+ tempFill = i === 0 ? tempFill - 1 : tempFill ;
266
+ if ( tempFill - 1 > text . realLength ( ) ) {
267
+ tempFill -= text . realLength ( ) + 1 ;
268
+ if ( prepend ) {
269
+ tempText . unshift ( text ) ;
270
+ } else {
271
+ tempText . push ( text ) ;
272
+ }
273
+ } else {
274
+ break ;
275
+ }
276
+ }
277
+ debugText = chalk . bgRgb ( 0 , 230 , 140 ) . black ( " " + tempText . join ( delim ?? "|" ) + " " ) ;
278
+ fill = tempFill ;
279
+
280
+ useRealLength ( false ) ;
281
+
282
+ return {
283
+ debugText,
284
+ borderWidth : fill
285
+ }
286
+ } else {
287
+ return {
288
+ debugText : "" ,
289
+ borderWidth : width - 1 ,
290
+ }
291
+ }
292
+ }
293
+ }
294
+
232
295
normalizePercents ( value , axis , includeMargins ) {
233
296
if ( typeof value === 'string' ) {
234
297
if ( value . endsWith ( '%' ) ) {
@@ -495,6 +558,13 @@ export default class IRenderable {
495
558
return size ;
496
559
}
497
560
561
+ _calculateRealWidth ( ) {
562
+ useRealLength ( ) ;
563
+ let wid = ( this . lastBuffer ?? this . aBuffer ) . reduce ( ( real , line ) => Math . max ( real , ( line && line . realLength ( ) ) ?? 0 ) , 0 ) ;
564
+ useRealLength ( false ) ;
565
+ return wid ;
566
+ }
567
+
498
568
// Applies the margin dimensions to the size
499
569
applyMarginSize ( size ) {
500
570
let { x, y } = this . getMargin ( ) ;
@@ -576,10 +646,10 @@ export default class IRenderable {
576
646
let headTop = Math . ceil ( ratio * this . _nominal . scrollX ) ;
577
647
let vBuffer = [ ] ;
578
648
for ( let i = 0 ; i < height ; i ++ ) {
579
- if ( i < headTop || i >= headTop + headHeight ) {
580
- vBuffer . push ( chalk . bgRgb ( ...this . scrollbarStyle . railColor ) ( " " ) ) ;
649
+ if ( i < headTop || i >= headTop + headHeight - 1 ) {
650
+ vBuffer . push ( chalk . bgRgb ( ...this . styles . railColor ) ( " " ) ) ;
581
651
} else {
582
- vBuffer . push ( chalk . bgRgb ( ...this . scrollbarStyle . headColor ) ( " " ) ) ;
652
+ vBuffer . push ( chalk . bgRgb ( ...this . styles . headColor ) ( " " ) ) ;
583
653
}
584
654
}
585
655
this . aBuffer = this . aBuffer . map ( ( line , i ) => { return line + vBuffer [ i ] } ) ;
@@ -589,6 +659,7 @@ export default class IRenderable {
589
659
applyBorder ( ) {
590
660
let { top, right, bottom, left } = this . getBorder ( ) ;
591
661
let { width } = this . unapplyPaddingSize ( this . getSize ( ) ) ;
662
+ let hasFocus = this . hasFocus ( ) ;
592
663
let borderTopLeft = this . _native . getBorderCharacter ( top , this . border_orientations . TOP_LEFT ) ;
593
664
let borderTop = this . _native . getBorderCharacter ( top , this . border_orientations . TOP ) ;
594
665
let borderTopRight = this . _native . getBorderCharacter ( top , this . border_orientations . TOP_RIGHT ) ;
@@ -598,17 +669,29 @@ export default class IRenderable {
598
669
let borderBottom = this . _native . getBorderCharacter ( bottom , this . border_orientations . BOTTOM ) ;
599
670
let borderBottomRight = this . _native . getBorderCharacter ( bottom , this . border_orientations . BOTTOM_RIGHT ) ;
600
671
672
+ borderTopLeft = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderTopLeft ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderTopLeft ) ;
673
+ borderTop = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderTop ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderTop ) ;
674
+ borderTopRight = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderTopRight ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderTopRight ) ;
675
+ borderRight = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderRight ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderRight ) ;
676
+ borderLeft = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderLeft ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderLeft ) ;
677
+ borderBottomLeft = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderBottomLeft ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderBottomLeft ) ;
678
+ borderBottom = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderBottom ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderBottom ) ;
679
+ borderBottomRight = hasFocus ? chalk . rgb ( ...this . styles . borderFocus ) ( borderBottomRight ) : chalk . rgb ( ...this . styles . borderBlur ) ( borderBottomRight ) ;
680
+
681
+
601
682
if ( left !== this . borders . NONE ) {
602
683
this . aBuffer = this . aBuffer . map ( x => borderLeft + x ) ;
603
684
}
604
685
if ( right !== this . borders . NONE ) {
605
686
this . aBuffer = this . aBuffer . map ( x => x + borderRight ) ;
606
687
}
607
688
if ( top !== this . borders . NONE ) {
608
- this . aBuffer . unshift ( borderTopLeft + borderTop . repeat ( width ) + borderTopRight ) ;
689
+ let { debugText, borderWidth } = this . _debug . getTitleBarInfo ( ) ;
690
+
691
+ this . aBuffer . unshift ( borderTopLeft + ( new Array ( borderWidth ) . fill ( borderTop ) ) . join ( "" ) + debugText + borderTop + borderTopRight ) ;
609
692
}
610
693
if ( bottom !== this . borders . NONE ) {
611
- this . aBuffer . push ( borderBottomLeft + borderBottom . repeat ( width ) + borderBottomRight ) ;
694
+ this . aBuffer . push ( borderBottomLeft + ( new Array ( width ) . fill ( borderBottom ) ) . join ( "" ) + borderBottomRight ) ;
612
695
}
613
696
}
614
697
@@ -733,7 +816,7 @@ export default class IRenderable {
733
816
if ( str . realLength ( ) < width ) {
734
817
out = s ( str , this . getSize ( ) . width ) ;
735
818
} else if ( str . realLength ( ) >= width ) {
736
- out = str . substring ( 0 , width ) ;
819
+ out = __EXPERIMENTAL__cutEnd ( str , Math . max ( str . realLength ( ) - width , 0 ) ) ;
737
820
}
738
821
useRealLength ( false ) ;
739
822
@@ -752,7 +835,7 @@ export default class IRenderable {
752
835
useRealLength ( true ) ;
753
836
754
837
this . aBuffer . forEach ( line => {
755
- if ( line . realLength ( ) !== width ) {
838
+ if ( line === null || line === undefined || line . realLength ( ) !== width ) {
756
839
throw new Error ( "Renderable buffer dimensions must be equal to control dimensions" ) ;
757
840
}
758
841
} ) ;
@@ -783,6 +866,14 @@ export default class IRenderable {
783
866
process . stdout . write ( renderBuffer . join ( "\n" ) ) ;
784
867
}
785
868
869
+ scrollDown ( ) {
870
+ this . _nominal . scrollX = Math . min ( this . lastBuffer . length - this . getSize ( ) . height , this . _nominal . scrollX + 1 ) ;
871
+ }
872
+
873
+ scrollUp ( ) {
874
+ this . _nominal . scrollX = Math . max ( 0 , this . _nominal . scrollX - 1 ) ;
875
+ }
876
+
786
877
streamConsoleViewportAsync = async ( getViewport , cancelCallback ) => {
787
878
const { readkey, consolekeys, cursor } = useContext ( ) ;
788
879
@@ -802,6 +893,7 @@ export default class IRenderable {
802
893
this . setViewport ( getViewport ( ) ) ;
803
894
}
804
895
896
+ this . focus ( ) ;
805
897
this . show ( ) ;
806
898
let key = await readkey ( true ) ;
807
899
switch ( key ) {
@@ -814,10 +906,10 @@ export default class IRenderable {
814
906
}
815
907
break ;
816
908
case consolekeys . up :
817
- this . _nominal . scrollX = Math . max ( 0 , this . _nominal . scrollX - 1 ) ;
909
+ this . scrollUp ( ) ;
818
910
break ;
819
911
case consolekeys . down :
820
- this . _nominal . scrollX = Math . min ( this . lastBuffer . length - this . getViewport ( ) . height , this . _nominal . scrollX + 1 ) ;
912
+ this . scrollDown ( ) ;
821
913
break ;
822
914
}
823
915
}
0 commit comments