1- /// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
2- /// <reference path="../node_modules/pxt-core/built/pxtblocks.d.ts"/>
3- /// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
1+ /// <reference path="../node_modules/pxt-core/localtypings/pxtblockly.d.ts"/>
42
5- export interface FieldGesturesOptions extends pxtblockly . FieldImagesOptions {
3+ const pxtblockly = pxt . blocks . requirePxtBlockly ( )
4+ const Blockly = pxt . blocks . requireBlockly ( ) ;
5+
6+ export interface FieldGesturesOptions {
67 columns ?: string ;
78 width ?: string ;
89}
910
10- export class FieldGestures extends pxtblockly . FieldImages implements Blockly . FieldCustom {
11+ export class FieldGestures extends pxtblockly . FieldImages {
1112 public isFieldCustom_ = true ;
1213
1314 constructor ( text : string , options : FieldGesturesOptions , validator ?: Function ) {
14- super ( text , options , validator ) ;
15-
15+ super ( text , options as any , validator ) ;
1616 this . columns_ = parseInt ( options . columns ) || 4 ;
1717 this . width_ = parseInt ( options . width ) || 350 ;
18+
1819 this . addLabel_ = true ;
20+ }
1921
20- this . renderSelectedImage_ = Blockly . FieldDropdown . prototype . renderSelectedText_ ;
21- this . updateSize_ = ( Blockly . Field as any ) . prototype . updateSize_ ;
22+ protected render_ ( ) : void {
23+ if ( this . addLabel_ ) {
24+ this . renderSelectedText_ ( )
25+ this . positionBorderRect_ ( ) ;
26+ }
27+ else {
28+ super . render_ ( ) ;
29+ }
2230 }
2331
24- trimOptions_ ( ) {
32+ /** Renders the selected option, which must be text. */
33+ protected renderSelectedText_ ( ) {
34+ // Retrieves the selected option to display through getText_.
35+ this . getTextContent ( ) . nodeValue = this . getDisplayText_ ( ) ;
36+ const textElement = this . getTextElement ( ) ;
37+ Blockly . utils . dom . addClass ( textElement , 'blocklyDropdownText' ) ;
38+ textElement . setAttribute ( 'text-anchor' , 'start' ) ;
39+
40+ // Height and width include the border rect.
41+ const hasBorder = ! ! this . borderRect_ ;
42+ const height = Math . max (
43+ hasBorder ? this . getConstants ( ) ! . FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0 ,
44+ this . getConstants ( ) ! . FIELD_TEXT_HEIGHT ,
45+ ) ;
46+ const textWidth = Blockly . utils . dom . getFastTextWidth (
47+ this . getTextElement ( ) ,
48+ this . getConstants ( ) ! . FIELD_TEXT_FONTSIZE ,
49+ this . getConstants ( ) ! . FIELD_TEXT_FONTWEIGHT ,
50+ this . getConstants ( ) ! . FIELD_TEXT_FONTFAMILY ,
51+ ) ;
52+ const xPadding = hasBorder
53+ ? this . getConstants ( ) ! . FIELD_BORDER_RECT_X_PADDING
54+ : 0 ;
55+ let arrowWidth = 0 ;
56+ if ( this . getSvgArrow ( ) ) {
57+ arrowWidth = this . positionSVGArrow_ (
58+ textWidth + xPadding ,
59+ height / 2 - this . getConstants ( ) ! . FIELD_DROPDOWN_SVG_ARROW_SIZE / 2 ,
60+ ) ;
61+ }
62+ this . size_ . width = textWidth + arrowWidth + xPadding * 2 ;
63+ this . size_ . height = height ;
64+
65+ this . positionTextElement_ ( xPadding , textWidth ) ;
2566 }
2667
27- protected buttonClick_ = function ( e : any ) {
28- let value = e . target . getAttribute ( 'data-value' ) ;
29- this . setValue ( value ) ;
30- Blockly . DropDownDiv . hide ( ) ;
31- } ;
68+ positionSVGArrow_ ( x : number , y : number ) : number {
69+ const svgArrow = this . getSvgArrow ( ) ;
70+ if ( ! svgArrow ) {
71+ return 0 ;
72+ }
73+ const block = this . getSourceBlock ( ) ;
74+ const hasBorder = ! ! this . borderRect_ ;
75+ const xPadding = hasBorder
76+ ? this . getConstants ( ) ! . FIELD_BORDER_RECT_X_PADDING
77+ : 0 ;
78+ const textPadding = this . getConstants ( ) ! . FIELD_DROPDOWN_SVG_ARROW_PADDING ;
79+ const svgArrowSize = this . getConstants ( ) ! . FIELD_DROPDOWN_SVG_ARROW_SIZE ;
80+ const arrowX = block . RTL ? xPadding : x + textPadding ;
81+ svgArrow . setAttribute (
82+ 'transform' ,
83+ 'translate(' + arrowX + ',' + y + ')' ,
84+ ) ;
85+ return svgArrowSize + textPadding ;
86+ }
87+
88+ // This hack exists because svgArrow is private in Blockly's field dropdown.
89+ // It should always be the last image element in the field group
90+ protected getSvgArrow ( ) {
91+ if ( this . fieldGroup_ ) {
92+ const children = this . fieldGroup_ . children ;
93+
94+ let lastImage : SVGImageElement ;
95+
96+ for ( let i = 0 ; i < children . length ; i ++ ) {
97+ if ( children . item ( i ) . tagName . toLowerCase ( ) === "image" ) {
98+ lastImage = children . item ( i ) as SVGImageElement ;
99+ }
100+ }
101+
102+ return lastImage ;
103+ }
104+
105+ return undefined ;
106+ }
32107}
0 commit comments