1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | "use strict" ;
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | const Element = require( './Element.js' ) ;
|
36 | const Button = require( './Button.js' ) ;
|
37 |
|
38 |
|
39 |
|
40 | function BaseMenu( options = {} ) {
|
41 | Element.call( this , options ) ;
|
42 |
|
43 | this.backgroundAttr = options.backgroundAttr || { bgColor: 'white' , color: 'black' } ;
|
44 | this.contentEllipsis = options.contentEllipsis || '…' ;
|
45 | this.previousPageContent = options.previousPageContent || '«' ;
|
46 | this.previousPageContentHasMarkup = !! options.previousPageContentHasMarkup ;
|
47 | this.nextPageContent = options.nextPageContent || '»' ;
|
48 | this.nextPageContentHasMarkup = !! options.nextPageContentHasMarkup ;
|
49 | this.itemsDef = options.items || [] ;
|
50 | this.previousPageDef = options.previousPage ;
|
51 | this.nextPageDef = options.nextPage ;
|
52 | this.masterDef = options.master ;
|
53 | this.separatorDef = options.separator ;
|
54 | this.buttons = [] ;
|
55 | this.focusChild = null ;
|
56 |
|
57 |
|
58 | this.page = 0 ;
|
59 | this.maxPage = 0 ;
|
60 |
|
61 | this.onButtonSubmit = this.onButtonSubmit.bind( this ) ;
|
62 | this.onButtonToggle = this.onButtonToggle.bind( this ) ;
|
63 | this.onKey = this.onKey.bind( this ) ;
|
64 | this.onWheel = this.onWheel.bind( this ) ;
|
65 | this.onFocus = this.onFocus.bind( this ) ;
|
66 |
|
67 |
|
68 | this.buttonBlurAttr = options.buttonBlurAttr || this.defaultOptions.buttonBlurAttr || { bgColor: 'black' , color: 'white' , bold: true } ;
|
69 | this.buttonEvenBlurAttr = options.buttonEvenBlurAttr || null ;
|
70 | this.buttonFocusAttr = options.buttonFocusAttr || this.defaultOptions.buttonFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;
|
71 | this.buttonDisabledAttr = options.buttonDisabledAttr || this.defaultOptions.buttonDisabledAttr || { bgColor: 'black' , color: 'brightBlack' , bold: true } ;
|
72 | this.buttonSubmittedAttr = options.buttonSubmittedAttr || this.defaultOptions.buttonSubmittedAttr || { bgColor: 'brightBlack' , color: 'brightWhite' , bold: true } ;
|
73 | this.turnedOnBlurAttr = options.turnedOnBlurAttr || this.defaultOptions.turnedOnBlurAttr || { bgColor: 'cyan' } ;
|
74 | this.turnedOnFocusAttr = options.turnedOnFocusAttr || this.defaultOptions.turnedOnFocusAttr || { bgColor: 'brightCyan' , bold: true } ;
|
75 | this.turnedOffBlurAttr = options.turnedOffBlurAttr || this.defaultOptions.turnedOffBlurAttr || { bgColor: 'gray' , dim: true } ;
|
76 | this.turnedOffFocusAttr = options.turnedOffFocusAttr || this.defaultOptions.turnedOffFocusAttr || { bgColor: 'white' , color: 'black' , bold: true } ;
|
77 |
|
78 |
|
79 | this.blurLeftPadding = options.blurLeftPadding || options.leftPadding || '' ;
|
80 | this.blurRightPadding = options.blurRightPadding || options.rightPadding || '' ;
|
81 | this.focusLeftPadding = options.focusLeftPadding || options.leftPadding || '' ;
|
82 | this.focusRightPadding = options.focusRightPadding || options.rightPadding || '' ;
|
83 | this.disabledLeftPadding = options.disabledLeftPadding || options.leftPadding || '' ;
|
84 | this.disabledRightPadding = options.disabledRightPadding || options.rightPadding || '' ;
|
85 | this.submittedLeftPadding = options.submittedLeftPadding || options.leftPadding || '' ;
|
86 | this.submittedRightPadding = options.submittedRightPadding || options.rightPadding || '' ;
|
87 | this.turnedOnFocusLeftPadding = options.turnedOnFocusLeftPadding || options.turnedOnLeftPadding || options.leftPadding || '' ;
|
88 | this.turnedOnFocusRightPadding = options.turnedOnFocusRightPadding || options.turnedOnRightPadding || options.rightPadding || '' ;
|
89 | this.turnedOffFocusLeftPadding = options.turnedOffFocusLeftPadding || options.turnedOffLeftPadding || options.leftPadding || '' ;
|
90 | this.turnedOffFocusRightPadding = options.turnedOffFocusRightPadding || options.turnedOffRightPadding || options.rightPadding || '' ;
|
91 | this.turnedOnBlurLeftPadding = options.turnedOnBlurLeftPadding || options.turnedOnLeftPadding || options.leftPadding || '' ;
|
92 | this.turnedOnBlurRightPadding = options.turnedOnBlurRightPadding || options.turnedOnRightPadding || options.rightPadding || '' ;
|
93 | this.turnedOffBlurLeftPadding = options.turnedOffBlurLeftPadding || options.turnedOffLeftPadding || options.leftPadding || '' ;
|
94 | this.turnedOffBlurRightPadding = options.turnedOffBlurRightPadding || options.turnedOffRightPadding || options.rightPadding || '' ;
|
95 | this.paddingHasMarkup = !! options.paddingHasMarkup ;
|
96 |
|
97 | if ( options.keyBindings ) { this.keyBindings = options.keyBindings ; }
|
98 | if ( options.buttonKeyBindings ) { this.buttonKeyBindings = options.buttonKeyBindings ; }
|
99 | if ( options.buttonActionKeyBindings ) { this.buttonActionKeyBindings = options.buttonActionKeyBindings ; }
|
100 | if ( options.toggleButtonKeyBindings ) { this.toggleButtonKeyBindings = options.toggleButtonKeyBindings ; }
|
101 | if ( options.toggleButtonActionKeyBindings ) { this.toggleButtonActionKeyBindings = options.toggleButtonActionKeyBindings ; }
|
102 |
|
103 | this.on( 'key' , this.onKey ) ;
|
104 | this.on( 'wheel' , this.onWheel ) ;
|
105 | this.on( 'focus' , this.onFocus ) ;
|
106 | }
|
107 |
|
108 | module.exports = BaseMenu ;
|
109 |
|
110 | BaseMenu.prototype = Object.create( Element.prototype ) ;
|
111 | BaseMenu.prototype.constructor = BaseMenu ;
|
112 | BaseMenu.prototype.elementType = 'BaseMenu' ;
|
113 |
|
114 |
|
115 |
|
116 | BaseMenu.prototype.destroy = function( isSubDestroy ) {
|
117 | this.off( 'key' , this.onKey ) ;
|
118 | this.off( 'wheel' , this.onWheel ) ;
|
119 | this.off( 'focus' , this.onFocus ) ;
|
120 |
|
121 | Element.prototype.destroy.call( this , isSubDestroy ) ;
|
122 | } ;
|
123 |
|
124 |
|
125 |
|
126 | BaseMenu.prototype.previousPage = function( focusType ) {
|
127 | var focusAware ;
|
128 |
|
129 | if ( this.maxPage && this.page > 0 ) {
|
130 | this.page -- ;
|
131 | this.initPage() ;
|
132 | this.focusChild = this.children[ this.children.length - 2 ] ;
|
133 | focusAware = this.document.giveFocusTo_( this.focusChild , focusType ) ;
|
134 | if ( ! focusAware ) { this.document.focusPrevious() ; }
|
135 | this.draw() ;
|
136 | }
|
137 | } ;
|
138 |
|
139 |
|
140 |
|
141 | BaseMenu.prototype.nextPage = function( focusType ) {
|
142 | var focusAware ;
|
143 |
|
144 | if ( this.maxPage && this.page < this.maxPage ) {
|
145 | this.page ++ ;
|
146 | this.initPage() ;
|
147 | this.focusChild = this.children[ 1 ] ;
|
148 | focusAware = this.document.giveFocusTo_( this.focusChild , focusType ) ;
|
149 | if ( ! focusAware ) { this.document.focusNext() ; }
|
150 | this.draw() ;
|
151 | }
|
152 | } ;
|
153 |
|
154 |
|
155 |
|
156 | BaseMenu.prototype.toPage = function( page , focusType ) {
|
157 | var focusAware ;
|
158 |
|
159 | if ( this.maxPage && page !== this.page ) {
|
160 | this.page = page ;
|
161 | this.initPage() ;
|
162 | this.focusChild = this.children[ 1 ] ;
|
163 | focusAware = this.document.giveFocusTo_( this.focusChild , focusType ) ;
|
164 | if ( ! focusAware ) { this.document.focusNext() ; }
|
165 | this.draw() ;
|
166 | }
|
167 | } ;
|
168 |
|
169 |
|
170 |
|
171 | BaseMenu.prototype.focusValue = function( value , focusType ) {
|
172 | var focusAware , itemDef , item ;
|
173 |
|
174 | itemDef = this.itemsDef.find( it => ! it.disabled && it.value === value ) ;
|
175 | if ( ! itemDef ) { return ; }
|
176 |
|
177 | if ( this.page !== itemDef.page ) {
|
178 | this.page = itemDef.page ;
|
179 | this.initPage() ;
|
180 | }
|
181 |
|
182 | item = this.buttons.find( it => it.def === itemDef ) ;
|
183 | if ( ! item ) { return ; }
|
184 |
|
185 | this.focusChild = item ;
|
186 |
|
187 | focusAware = this.document.giveFocusTo_( this.focusChild , focusType ) ;
|
188 | if ( ! focusAware ) { this.document.focusNext() ; }
|
189 |
|
190 | this.draw() ;
|
191 | } ;
|
192 |
|
193 |
|
194 |
|
195 | BaseMenu.prototype.onKey = function( key , trash , data ) {
|
196 | switch( this.keyBindings[ key ] ) {
|
197 | case 'previous' :
|
198 | this.focusChild = this.focusPreviousChild( ! this.maxPage ) ;
|
199 | if ( this.focusChild === this.children[ 0 ] && this.maxPage && this.page > 0 ) {
|
200 | this.previousPage( 'cycle' ) ;
|
201 | }
|
202 | break ;
|
203 | case 'next' :
|
204 | this.focusChild = this.focusNextChild( ! this.maxPage ) ;
|
205 | if ( this.focusChild === this.children[ this.children.length - 1 ] && this.maxPage && this.page < this.maxPage ) {
|
206 | this.nextPage( 'cycle' ) ;
|
207 | }
|
208 | break ;
|
209 | case 'previousPage' :
|
210 | if ( this.maxPage && this.page > 0 ) {
|
211 | this.previousPage( 'cycle' ) ;
|
212 | }
|
213 | break ;
|
214 | case 'nextPage' :
|
215 | if ( this.maxPage && this.page < this.maxPage ) {
|
216 | this.nextPage( 'cycle' ) ;
|
217 | }
|
218 | break ;
|
219 | case 'firstPage' :
|
220 | if ( this.maxPage && this.page !== 0 ) {
|
221 | this.toPage( 0 , 'cycle' ) ;
|
222 | }
|
223 | break ;
|
224 | case 'lastPage' :
|
225 | if ( this.maxPage && this.page !== this.maxPage ) {
|
226 | this.toPage( this.maxPage , 'cycle' ) ;
|
227 | }
|
228 | break ;
|
229 | default :
|
230 | return ;
|
231 | }
|
232 |
|
233 | return true ;
|
234 | } ;
|
235 |
|
236 |
|
237 |
|
238 | BaseMenu.prototype.onWheel = function( data ) {
|
239 | if ( data.yDirection < 0 ) { this.previousPage( 'cycle' ) ; }
|
240 | else if ( data.yDirection > 0 ) { this.nextPage( 'cycle' ) ; }
|
241 | } ;
|
242 |
|
243 |
|
244 |
|
245 | BaseMenu.prototype.onFocus = function( focus , type ) {
|
246 | if ( type === 'cycle' ) { return ; }
|
247 |
|
248 | if ( focus ) {
|
249 | if ( this.focusChild ) { this.document.giveFocusTo( this.focusChild , 'delegate' ) ; }
|
250 | else { this.focusChild = this.focusNextChild() ; }
|
251 | }
|
252 | } ;
|
253 |
|
254 |
|
255 |
|
256 | BaseMenu.prototype.onButtonSubmit = function( buttonValue , action , button ) {
|
257 | switch ( button.internalRole ) {
|
258 | case 'previousPage' :
|
259 | this.previousPage() ;
|
260 | break ;
|
261 | case 'nextPage' :
|
262 | this.nextPage() ;
|
263 | break ;
|
264 | default :
|
265 | this.emit( 'submit' , buttonValue , action , this ) ;
|
266 | }
|
267 | } ;
|
268 |
|
269 |
|
270 |
|
271 |
|
272 | BaseMenu.prototype.defaultOptions = {} ;
|
273 | BaseMenu.prototype.keyBindings = {} ;
|
274 | BaseMenu.prototype.buttonKeyBindings = {} ;
|
275 | BaseMenu.prototype.buttonActionKeyBindings = {} ;
|
276 | BaseMenu.prototype.toggleButtonKeyBindings = {} ;
|
277 | BaseMenu.prototype.toggleButtonActionKeyBindings = {} ;
|
278 | BaseMenu.prototype.initPage = function() {} ;
|
279 | BaseMenu.prototype.onButtonToggle = function() {} ;
|
280 | BaseMenu.prototype.childUseParentKeyValue = false ;
|
281 |
|