22/// <reference path="../../built/pxtsim.d.ts" />
33
44import * as Blockly from "blockly" ;
5+ import { DEFAULT_LED_COLORS } from "./field_ledmatrix_colorPicker" ;
56import { FieldMatrix } from "./field_matrix" ;
67import { FieldCustom } from "./field_utils" ;
78
@@ -27,9 +28,12 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
2728 public SERIALIZABLE = true ;
2829
2930 private params : any ;
30- private onColor = "#FFFFFF" ;
31- private offColor : string ;
31+
32+ private palette : string [ ] ;
33+
3234 private static DEFAULT_OFF_COLOR = "#000000" ;
35+ private static DEFAULT_ON_COLOR = "#FFFFFF" ;
36+ private offOpacity = 0.2 ;
3337
3438 private scale = 1 ;
3539
@@ -39,13 +43,18 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
3943 private yAxisLabel : LabelMode = LabelMode . None ;
4044 private xAxisLabel : LabelMode = LabelMode . None ;
4145
42- private cellState : boolean [ ] [ ] = [ ] ;
46+ private cellState : number [ ] [ ] = [ ] ;
4347
4448 private currentDragState_ : boolean ;
4549
4650 protected clearSelectionOnBlur = true ;
4751 protected forceFocusVisible = true ;
4852
53+ protected isColorMatrix = false ;
54+ protected colorNames : string [ ] ;
55+
56+ private activeColor = 1 ;
57+
4958 constructor ( text : string , params : any , validator ?: Blockly . FieldValidator ) {
5059 super ( text , validator ) ;
5160 this . params = params ;
@@ -64,12 +73,37 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
6473 }
6574 }
6675
67- if ( this . params . onColor !== undefined ) {
68- this . onColor = this . params . onColor ;
76+ this . isColorMatrix = ! ! this . params . isColorMatrix ;
77+
78+ if ( this . params . colors ) {
79+ this . palette = this . params . colors ;
80+ }
81+ else {
82+ this . palette = [
83+ FieldLedMatrix . DEFAULT_OFF_COLOR ,
84+ ...DEFAULT_LED_COLORS
85+ ] ;
86+ }
87+
88+ if ( this . params . colorNames ) {
89+ this . colorNames = this . params . colorNames ;
90+ }
91+ else {
92+ this . colorNames = [
93+ lf ( "off" ) ,
94+ ...DEFAULT_LED_COLORS
95+ ] ;
96+ }
97+
98+ if ( this . params . hasOffColor ) {
99+ this . offOpacity = 1.0 ;
69100 }
70101
71- if ( this . params . offColor !== undefined ) {
72- this . offColor = this . params . offColor ;
102+ if ( this . params . offOpacity ) {
103+ const val = parseFloat ( this . params . offOpacity ) ;
104+ if ( ! isNaN ( val ) && val >= 0 && val <= 1 ) {
105+ this . offOpacity = val ;
106+ }
73107 }
74108
75109 if ( this . params . scale !== undefined )
@@ -79,18 +113,27 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
79113 else if ( Math . max ( this . numMatrixCols , this . numMatrixRows ) > 10 )
80114 this . scale = 0.9 ;
81115
82- this . size_ . height = this . scale * Number ( this . numMatrixRows ) * ( FieldLedMatrix . CELL_WIDTH + FieldLedMatrix . CELL_VERTICAL_MARGIN ) + FieldLedMatrix . CELL_VERTICAL_MARGIN * 2 + FieldLedMatrix . BOTTOM_MARGIN + this . getXAxisHeight ( )
83- this . size_ . width = this . scale * Number ( this . numMatrixCols ) * ( FieldLedMatrix . CELL_WIDTH + FieldLedMatrix . CELL_HORIZONTAL_MARGIN ) + FieldLedMatrix . CELL_HORIZONTAL_MARGIN + this . getYAxisWidth ( ) ;
116+ const verticalMargin = isNaN ( this . params . verticalSpacing ) ? FieldLedMatrix . CELL_VERTICAL_MARGIN : this . params . verticalSpacing ;
117+ const horizontalMargin = isNaN ( this . params . horizontalSpacing ) ? FieldLedMatrix . CELL_HORIZONTAL_MARGIN : this . params . horizontalSpacing ;
118+
119+ this . size_ . height = this . scale * Number ( this . numMatrixRows ) * ( FieldLedMatrix . CELL_WIDTH + verticalMargin ) + verticalMargin * 2 + FieldLedMatrix . BOTTOM_MARGIN + this . getXAxisHeight ( )
120+ this . size_ . width = this . scale * Number ( this . numMatrixCols ) * ( FieldLedMatrix . CELL_WIDTH + horizontalMargin ) + horizontalMargin + this . getYAxisWidth ( ) ;
84121 }
85122
86123 protected getCellToggled ( x : number , y : number ) : boolean {
87- return this . cellState [ x ] [ y ] ;
124+ return ! ! this . cellState [ x ] [ y ] ;
88125 }
89126
90127 protected useTwoToneFocusIndicator ( x : number , y : number ) : boolean {
91128 return this . getCellToggled ( x , y ) ;
92129 }
93130
131+ setActiveColorIndex ( index : number ) {
132+ if ( index >= 0 && index < this . palette . length ) {
133+ this . activeColor = index ;
134+ }
135+ }
136+
94137 /**
95138 * Show the inline free-text editor on top of the text.
96139 * @private
@@ -136,31 +179,34 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
136179 for ( let i = 0 ; i < this . numMatrixCols ; i ++ ) {
137180 this . cellState . push ( [ ] )
138181 for ( let j = 0 ; j < this . numMatrixRows ; j ++ ) {
139- this . cellState [ i ] . push ( false ) ;
182+ this . cellState [ i ] . push ( 0 ) ;
140183 }
141184 }
142185
143186 this . restoreStateFromString ( ) ;
144187
188+ const verticalMargin = isNaN ( this . params . verticalSpacing ) ? FieldLedMatrix . CELL_VERTICAL_MARGIN : this . params . verticalSpacing ;
189+ const horizontalMargin = isNaN ( this . params . horizontalSpacing ) ? FieldLedMatrix . CELL_HORIZONTAL_MARGIN : this . params . horizontalSpacing ;
190+
145191 this . createMatrixDisplay ( {
146192 cellWidth : FieldLedMatrix . CELL_WIDTH ,
147193 cellHeight : FieldLedMatrix . CELL_WIDTH ,
148194 cellLabel : lf ( "LED" ) ,
149- cellHorizontalMargin : FieldLedMatrix . CELL_HORIZONTAL_MARGIN ,
150- cellVerticalMargin : FieldLedMatrix . CELL_VERTICAL_MARGIN ,
151- cornerRadius : FieldLedMatrix . CELL_CORNER_RADIUS ,
152- cellFill : this . offColor ,
195+ cellHorizontalMargin : horizontalMargin ,
196+ cellVerticalMargin : verticalMargin ,
197+ cornerRadius : isNaN ( this . params . borderRadius ) ? FieldLedMatrix . CELL_CORNER_RADIUS : this . params . borderRadius ,
198+ cellFill : this . palette [ 0 ] ,
153199 padLeft : this . getYAxisWidth ( ) ,
154200 scale : this . scale
155201 } ) ;
156202
157203 this . updateValue ( ) ;
158204
159205 if ( this . xAxisLabel !== LabelMode . None ) {
160- const y = this . scale * this . numMatrixRows * ( FieldLedMatrix . CELL_WIDTH + FieldLedMatrix . CELL_VERTICAL_MARGIN ) + FieldLedMatrix . CELL_VERTICAL_MARGIN * 2 + FieldLedMatrix . BOTTOM_MARGIN
206+ const y = this . scale * this . numMatrixRows * ( FieldLedMatrix . CELL_WIDTH + verticalMargin ) + verticalMargin * 2 + FieldLedMatrix . BOTTOM_MARGIN
161207 const xAxis = pxsim . svg . child ( this . matrixSvg , "g" , { transform : `translate(${ 0 } ${ y } )` } ) ;
162208 for ( let i = 0 ; i < this . numMatrixCols ; i ++ ) {
163- const x = this . getYAxisWidth ( ) + this . scale * i * ( FieldLedMatrix . CELL_WIDTH + FieldLedMatrix . CELL_HORIZONTAL_MARGIN ) + FieldLedMatrix . CELL_WIDTH / 2 + FieldLedMatrix . CELL_HORIZONTAL_MARGIN / 2 ;
209+ const x = this . getYAxisWidth ( ) + this . scale * i * ( FieldLedMatrix . CELL_WIDTH + horizontalMargin ) + FieldLedMatrix . CELL_WIDTH / 2 + horizontalMargin / 2 ;
164210 const lbl = pxsim . svg . child ( xAxis , "text" , { x, class : "blocklyText" } )
165211 lbl . textContent = this . getLabel ( i , this . xAxisLabel ) ;
166212 }
@@ -169,7 +215,7 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
169215 if ( this . yAxisLabel !== LabelMode . None ) {
170216 const yAxis = pxsim . svg . child ( this . matrixSvg , "g" , { } ) ;
171217 for ( let i = 0 ; i < this . numMatrixRows ; i ++ ) {
172- const y = this . scale * i * ( FieldLedMatrix . CELL_WIDTH + FieldLedMatrix . CELL_VERTICAL_MARGIN ) + FieldLedMatrix . CELL_WIDTH / 2 + FieldLedMatrix . CELL_VERTICAL_MARGIN * 2 ;
218+ const y = this . scale * i * ( FieldLedMatrix . CELL_WIDTH + verticalMargin ) + FieldLedMatrix . CELL_WIDTH / 2 + verticalMargin * 2 ;
173219 const lbl = pxsim . svg . child ( yAxis , "text" , { x : 0 , y, class : "blocklyText" } )
174220 lbl . textContent = this . getLabel ( i , this . yAxisLabel ) ;
175221 }
@@ -265,7 +311,7 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
265311 }
266312
267313 protected toggleCell = ( x : number , y : number , value ?: boolean ) => {
268- this . cellState [ x ] [ y ] = value ?? this . currentDragState_ ;
314+ this . cellState [ x ] [ y ] = ( value ?? this . currentDragState_ ) ? this . activeColor : 0 ;
269315 this . updateValue ( ) ;
270316 }
271317
@@ -293,11 +339,11 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
293339 }
294340
295341 private getColor ( x : number , y : number ) {
296- return this . cellState [ x ] [ y ] ? this . onColor : ( this . offColor || FieldLedMatrix . DEFAULT_OFF_COLOR ) ;
342+ return this . palette [ this . cellState [ x ] [ y ] ] ;
297343 }
298344
299345 private getOpacity ( x : number , y : number ) {
300- const offOpacity = this . offColor ? '1.0' : '0.2' ;
346+ const offOpacity = this . offOpacity + "" ;
301347 return this . cellState [ x ] [ y ] ? '1.0' : offOpacity ;
302348 }
303349
@@ -306,7 +352,10 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
306352 cellRect . setAttribute ( "fill" , this . getColor ( x , y ) ) ;
307353 cellRect . setAttribute ( "fill-opacity" , this . getOpacity ( x , y ) ) ;
308354 cellRect . setAttribute ( 'class' , `blocklyLed${ this . cellState [ x ] [ y ] ? 'On' : 'Off' } ` ) ;
309- cellRect . setAttribute ( "aria-checked" , this . cellState [ x ] [ y ] . toString ( ) ) ;
355+ cellRect . setAttribute ( "aria-checked" , ( ! ! this . cellState [ x ] [ y ] ) . toString ( ) ) ;
356+ if ( this . isColorMatrix ) {
357+ cellRect . setAttribute ( "aria-label" , this . colorNames [ this . cellState [ x ] [ y ] ] || this . palette [ this . cellState [ x ] [ y ] ] || lf ( "color {0}" , this . cellState [ x ] [ y ] ) ) ;
358+ }
310359 }
311360
312361 setValue ( newValue : string | number , restoreState = true ) {
@@ -357,12 +406,10 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
357406 const row = rows [ y ] ;
358407
359408 for ( let j = 0 ; j < row . length && x < this . numMatrixCols ; j ++ ) {
360- if ( isNegativeCharacter ( row [ j ] ) ) {
361- this . cellState [ x ] [ y ] = false ;
362- x ++ ;
363- }
364- else if ( isPositiveCharacter ( row [ j ] ) ) {
365- this . cellState [ x ] [ y ] = true ;
409+ const val = parseCharacter ( row [ j ] ) ;
410+
411+ if ( val !== - 1 ) {
412+ this . cellState [ x ] [ y ] = val ;
366413 x ++ ;
367414 }
368415 }
@@ -372,12 +419,13 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
372419
373420 // Composes the state into a string an updates the field's state
374421 private updateValue ( ) {
422+ const chars = ".#23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
375423 let res = "" ;
376424 for ( let y = 0 ; y < this . numMatrixRows ; y ++ ) {
377425 for ( let x = 0 ; x < this . numMatrixCols ; x ++ ) {
378- res += ( this . cellState [ x ] [ y ] ? "#" : "." ) + " "
426+ res += chars . charAt ( this . cellState [ x ] [ y ] ) + " " ;
379427 }
380- res += "\n" + FieldLedMatrix . TAB
428+ res += "\n" + FieldLedMatrix . TAB ;
381429 }
382430
383431 // Blockly stores the state of the field as a string
@@ -393,12 +441,20 @@ export class FieldLedMatrix extends FieldMatrix implements FieldCustom {
393441 }
394442}
395443
396- function isPositiveCharacter ( c : string ) {
397- return c === "#" || c === "*" || c === "1" ;
398- }
399-
400- function isNegativeCharacter ( c : string ) {
401- return c === "." || c === "_" || c === "0" ;
444+ function parseCharacter ( c : string ) : number {
445+ const chars = ".#23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
446+ switch ( c ) {
447+ case "#" :
448+ case "*" :
449+ case "1" :
450+ return 1 ;
451+ case "." :
452+ case "_" :
453+ case "0" :
454+ return 0 ;
455+ default :
456+ return chars . indexOf ( c . toUpperCase ( ) ) ;
457+ }
402458}
403459
404460
0 commit comments