Commit 23f569c3e7fa10f87ef9124592f2e68a4e4ed3a5
1 parent
55b10506
Exists in
master
and in
90 other branches
Give the possibility to have more than one 'prompted argument' for a function in…
… CalculatorUI + Add selection list for frame selection (#8540 & #5110)
Showing
4 changed files
with
309 additions
and
27 deletions
Show diff stats
generic_data/Functions/functions.xml
1 | 1 | <?xml version="1.0"?> |
2 | 2 | <functions xml:id="functions"> |
3 | 3 | <function name="mean_(,)" args="1" kind="time" group="stat"> |
4 | - <prompt>input averaging time in secs</prompt> | |
4 | + <prompts> | |
5 | + <prompt>input averaging time in secs</prompt> | |
6 | + </prompts> | |
5 | 7 | <info_brief>average</info_brief> |
6 | 8 | <new_kernel>#sampling_classic</new_kernel> |
7 | 9 | </function> |
8 | 10 | <function name="median_(,)" args="1" kind="time" group="stat"> |
9 | - <prompt>input averaging time in secs</prompt> | |
11 | + <prompts> | |
12 | + <prompt>input averaging time in secs</prompt> | |
13 | + </prompts> | |
10 | 14 | <info_brief>median average</info_brief> |
11 | 15 | <new_kernel>#median</new_kernel> |
12 | 16 | </function> |
13 | 17 | <function name="rms_(,)" args="1" kind="time" group="stat"> |
14 | - <prompt>input averaging time in secs</prompt> | |
18 | + <prompts> | |
19 | + <prompt>input averaging time in secs</prompt> | |
20 | + </prompts> | |
15 | 21 | <info_brief>root mean square</info_brief> |
16 | 22 | <new_kernel>#rms</new_kernel> |
17 | 23 | </function> |
18 | 24 | <function name="min_(,)" args="1" kind="time" group="stat"> |
19 | - <prompt>input window time in secs</prompt> | |
25 | + <prompts> | |
26 | + <prompt>input window time in secs</prompt> | |
27 | + </prompts> | |
20 | 28 | <info_brief>min() function</info_brief> |
21 | 29 | <new_kernel>#min</new_kernel> |
22 | 30 | </function> |
23 | 31 | <function name="max_(,)" args="1" kind="time" group="stat"> |
24 | - <prompt>input window time in secs</prompt> | |
32 | + <prompts> | |
33 | + <prompt>input window time in secs</prompt> | |
34 | + </prompts> | |
25 | 35 | <info_brief>max() function</info_brief> |
26 | 36 | <new_kernel>#max</new_kernel> |
27 | 37 | </function> |
28 | 38 | <function name="var_(,)" args="1" kind="time" group="stat"> |
29 | - <prompt>input window time in secs</prompt> | |
39 | + <prompts> | |
40 | + <prompt>input window time in secs</prompt> | |
41 | + </prompts> | |
30 | 42 | <info_brief>variance() function</info_brief> |
31 | 43 | <new_kernel>#var</new_kernel> |
32 | 44 | </function> |
33 | 45 | <function name="skew_(,)" args="1" kind="time" group="stat"> |
34 | - <prompt>input window time in secs</prompt> | |
46 | + <prompts> | |
47 | + <prompt>input window time in secs</prompt> | |
48 | + </prompts> | |
35 | 49 | <info_brief>skewness() function</info_brief> |
36 | 50 | <new_kernel>#skew</new_kernel> |
37 | 51 | </function> |
38 | 52 | <function name="mean_sm_(,)" args="1" kind="sliding" group="stat"> |
39 | - <prompt>input averaging time in secs</prompt> | |
53 | + <prompts> | |
54 | + <prompt>input averaging time in secs</prompt> | |
55 | + </prompts> | |
40 | 56 | <info_brief>average</info_brief> |
41 | 57 | <new_kernel>#sliding_average</new_kernel> |
42 | 58 | </function> |
43 | 59 | <function name="rms_sm_(,)" args="1" kind="sliding" group="stat"> |
44 | - <prompt>input averaging time in secs</prompt> | |
60 | + <prompts> | |
61 | + <prompt>input averaging time in secs</prompt> | |
62 | + </prompts> | |
45 | 63 | <info_brief>root mean square</info_brief> |
46 | 64 | <new_kernel>#rms_sm</new_kernel> |
47 | 65 | </function> |
48 | 66 | <function name="min_sm_(,)" args="1" kind="sliding" group="stat"> |
49 | - <prompt>input window time in secs</prompt> | |
67 | + <prompts> | |
68 | + <prompt>input window time in secs</prompt> | |
69 | + </prompts> | |
50 | 70 | <info_brief>min() function</info_brief> |
51 | 71 | <new_kernel>#min_sm</new_kernel> |
52 | 72 | </function> |
53 | 73 | <function name="max_sm_(,)" args="1" kind="sliding" group="stat"> |
54 | - <prompt>input window time in secs</prompt> | |
74 | + <prompts> | |
75 | + <prompt>input window time in secs</prompt> | |
76 | + </prompts> | |
55 | 77 | <info_brief>max() function</info_brief> |
56 | 78 | <new_kernel>#max_sm</new_kernel> |
57 | 79 | </function> |
58 | 80 | <function name="var_sm_(,)" args="1" kind="sliding" group="stat"> |
59 | - <prompt>input window time in secs</prompt> | |
81 | + <prompts> | |
82 | + <prompt>input window time in secs</prompt> | |
83 | + </prompts> | |
60 | 84 | <info_brief>variance() function</info_brief> |
61 | 85 | <new_kernel>#var_sm</new_kernel> |
62 | 86 | </function> |
63 | 87 | <function name="skew_sm_(,)" args="1" kind="sliding" group="stat"> |
64 | - <prompt>input window time in secs</prompt> | |
88 | + <prompts> | |
89 | + <prompt>input window time in secs</prompt> | |
90 | + </prompts> | |
65 | 91 | <info_brief>skewness() function</info_brief> |
66 | 92 | <new_kernel>#skew_sm</new_kernel> |
67 | 93 | </function> |
68 | 94 | <function name="smooth_(,)" args="1" kind="sliding" group="stat"> |
69 | - <prompt>input averaging time in secs</prompt> | |
95 | + <prompts> | |
96 | + <prompt>input averaging time in secs</prompt> | |
97 | + </prompts> | |
70 | 98 | <info_brief>smooths with a boxcar average</info_brief> |
71 | 99 | <new_kernel>#boxcar</new_kernel> |
72 | 100 | </function> |
... | ... | @@ -75,7 +103,9 @@ |
75 | 103 | <info_brief>Delays array by N points back (N < 0) and forth (N > 0)</info_brief> |
76 | 104 | </function>--> |
77 | 105 | <function name="shiftT_(,)" args="1" kind="amda" group="space"> |
78 | - <prompt>input time interval T in secs to delay by</prompt> | |
106 | + <prompts> | |
107 | + <prompt>input time interval T in secs to delay by</prompt> | |
108 | + </prompts> | |
79 | 109 | <info_brief>Shifts parameter by T secs back (T < 0) and forth (T > 0))</info_brief> |
80 | 110 | <new_kernel>#timeShift</new_kernel> |
81 | 111 | </function> |
... | ... | @@ -122,11 +152,15 @@ |
122 | 152 | </info_brief> |
123 | 153 | <new_kernel>lopez90</new_kernel> |
124 | 154 | </function> |
125 | - <!-- <function name="frameTransformation(,,)" args="3" kind="vectors"> | |
126 | - <prompt>FROM, TO, isPosition</prompt> | |
127 | - <info_brief>frame transformation</info_brief> | |
155 | + <function name="framesTransformation(,,,)" args="1" kind="frames" group="space"> | |
156 | + <prompts> | |
157 | + <prompt type="list" subtype="frames">Input frame:</prompt> | |
158 | + <prompt type="list" subtype="frames">Output frame:</prompt> | |
159 | + <prompt type="boolean">Transform a position?</prompt> | |
160 | + </prompts> | |
161 | + <info_brief>Frames transformation</info_brief> | |
128 | 162 | <new_kernel>#framesTransformation</new_kernel> |
129 | - </function>--> | |
163 | + </function> | |
130 | 164 | <function name="angle(,)" args="2" kind="vectors" group="math"> |
131 | 165 | <info_brief>Angle between two vectors</info_brief> |
132 | 166 | <new_kernel>angle</new_kernel> | ... | ... |
js/app/models/Function.js
... | ... | @@ -7,6 +7,15 @@ |
7 | 7 | * @author Benjamin |
8 | 8 | */ |
9 | 9 | |
10 | +Ext.define('amdaModel.PromptArg', { | |
11 | + extend: 'Ext.data.Model', | |
12 | + fields : [ | |
13 | + {name: 'type', mapping: '@type', type:'string', defaultValue: 'float'}, | |
14 | + {name: 'subtype', mapping: '@subtype', type:'string', defaultValue: null}, | |
15 | + {name: 'prompt', mapping: '/', type: 'string', defaultValue: ''} | |
16 | + ] | |
17 | +}); | |
18 | + | |
10 | 19 | Ext.define('amdaModel.Function', { |
11 | 20 | |
12 | 21 | extend: 'Ext.data.Model', |
... | ... | @@ -18,7 +27,6 @@ Ext.define('amdaModel.Function', { |
18 | 27 | {name: 'group', mapping: '@group', type: 'string', defaultValue: 'space'}, |
19 | 28 | {name: 'args', mapping: '@args', type: 'int', defaultValue: 1}, |
20 | 29 | {name: 'argv', mapping: '@argv', type: 'string'}, |
21 | - {name: 'prompt', type: 'string', defaultValue: ''}, | |
22 | 30 | {name: 'prompt_param', type: 'string', defaultValue: ''}, |
23 | 31 | {name: 'default_args', type: 'string', defaultValue: ''}, |
24 | 32 | {name: 'info_brief', type: 'string', defaultValue: ''} |
... | ... | @@ -30,7 +38,18 @@ Ext.define('amdaModel.Function', { |
30 | 38 | {type: 'presence', field: 'group'}/*, |
31 | 39 | {type: 'inclusion', field: 'kind', list: ['amda','time']}*/ |
32 | 40 | ], |
33 | - | |
41 | + | |
42 | + hasMany: { | |
43 | + associationKey : 'prompts', | |
44 | + name: 'prompts', | |
45 | + model: 'amdaModel.PromptArg', | |
46 | + reader : { | |
47 | + type: 'xml', | |
48 | + root: 'prompts', | |
49 | + record : 'prompt' | |
50 | + } | |
51 | + }, | |
52 | + | |
34 | 53 | proxy: { |
35 | 54 | type: 'ajax', |
36 | 55 | url : 'generic_data/Functions/functions.xml', |
... | ... | @@ -40,4 +59,44 @@ Ext.define('amdaModel.Function', { |
40 | 59 | record: 'function' |
41 | 60 | } |
42 | 61 | } |
62 | + | |
63 | +}); | |
64 | + | |
65 | +Ext.define('amdaModel.ArgListValue', { | |
66 | + extend: 'Ext.data.Model', | |
67 | + fields : [ | |
68 | + {name: 'key', mapping: '@key', type:'string'}, | |
69 | + {name: 'value', mapping: '@value', type: 'string'}, | |
70 | + {name: 'info', mapping: '@info', type: 'string', defaultValue: ''} | |
71 | + ] | |
72 | +}); | |
73 | + | |
74 | +Ext.define('amdaModel.ArgList', { | |
75 | + extend: 'Ext.data.Model', | |
76 | + idProperty: 'id', | |
77 | + | |
78 | + fields : [ | |
79 | + {name: 'id', mapping: '@id', type: 'string'} | |
80 | + ], | |
81 | + | |
82 | + hasMany: { | |
83 | + associationKey : 'values', | |
84 | + name: 'values', | |
85 | + model: 'amdaModel.ArgListValue', | |
86 | + reader : { | |
87 | + type: 'xml', | |
88 | + root: 'values', | |
89 | + record : 'value' | |
90 | + } | |
91 | + }, | |
92 | + | |
93 | + proxy: { | |
94 | + type: 'ajax', | |
95 | + url : 'generic_data/Functions/functions_args_list.xml', | |
96 | + reader: { | |
97 | + type: 'xml', | |
98 | + root: 'argslist', | |
99 | + record: 'arglist' | |
100 | + } | |
101 | + } | |
43 | 102 | }); | ... | ... |
js/app/views/CalculatorUI.js
... | ... | @@ -16,22 +16,177 @@ |
16 | 16 | |
17 | 17 | var CalculatorData = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '(', ')', '[', ']', '+', '-', '*', '/', '^', '.', '>', '>=', '=', '!=', '<=', '<', '&', '|']; |
18 | 18 | |
19 | +Ext.define('amdaUI.PromptArgsWin', { | |
20 | + extend: 'Ext.window.Window', | |
21 | + | |
22 | + fieldsForm: null, | |
23 | + applyCallback: null, | |
24 | + | |
25 | + constructor: function(config) { | |
26 | + this.init(config); | |
27 | + this.callParent(arguments); | |
28 | + }, | |
29 | + | |
30 | + promptArgs : function(prompts, fn, scope) { | |
31 | + var me = this; | |
32 | + if (fn) | |
33 | + this.applyCallback = Ext.Function.bind(fn, scope); | |
34 | + else | |
35 | + this.applyCallback = null; | |
36 | + this.fieldsForm.removeAll(); | |
37 | + prompts.each(function(promptObj, index) { | |
38 | + switch (promptObj.get('type')) { | |
39 | + case 'float': | |
40 | + me.addFloatField(promptObj.get('prompt'), index); | |
41 | + break; | |
42 | + case 'list': | |
43 | + me.addComboField(promptObj.get('prompt'), promptObj.get('subtype'), index); | |
44 | + break; | |
45 | + case 'boolean': | |
46 | + me.addBooleanField(promptObj.get('prompt'), index); | |
47 | + break; | |
48 | + case 'string': | |
49 | + me.addStringField(promptObj.get('prompt'), index); | |
50 | + break; | |
51 | + default: | |
52 | + console.log('Unknown arg type: ' + promptObj.get('type')); | |
53 | + break; | |
54 | + } | |
55 | + }); | |
56 | + this.show(); | |
57 | + }, | |
58 | + | |
59 | + addFloatField: function(label, index) { | |
60 | + this.fieldsForm.add({ | |
61 | + xtype: 'numberfield', | |
62 | + name: 'arg' + index, | |
63 | + fieldLabel: label, | |
64 | + decimalPrecision : 20, | |
65 | + allowBlank: false | |
66 | + }); | |
67 | + }, | |
68 | + | |
69 | + addComboField: function(label, listtype, index) { | |
70 | + var argslistStore = amdaUI.CalculatorUI.argslistStore; | |
71 | + if (!argslistStore) { | |
72 | + return; | |
73 | + } | |
74 | + | |
75 | + var valuesStore = null; | |
76 | + argslistStore.each(function(arglist) { | |
77 | + if (arglist.get('id') == listtype) { | |
78 | + valuesStore = arglist.valuesStore; | |
79 | + } | |
80 | + }); | |
81 | + if (!valuesStore) { | |
82 | + return; | |
83 | + } | |
84 | + | |
85 | + | |
86 | + var listData = []; | |
87 | + valuesStore.each(function (item) { | |
88 | + listData.push({'key': item.get('key'), 'value': item.get('value')}); | |
89 | + }); | |
90 | + | |
91 | + var comboStore = Ext.create('Ext.data.Store', { | |
92 | + fields: ['key', 'value'], | |
93 | + data : listData | |
94 | + }); | |
95 | + | |
96 | + this.fieldsForm.add({ | |
97 | + xtype: 'combo', | |
98 | + name: 'arg' + index, | |
99 | + fieldLabel: label, | |
100 | + store: comboStore, | |
101 | + queryMode: 'local', | |
102 | + displayField: 'value', | |
103 | + valueField: 'key', | |
104 | + editable: false | |
105 | + }); | |
106 | + }, | |
107 | + | |
108 | + addBooleanField: function(label, index) { | |
109 | + this.fieldsForm.add({ | |
110 | + xtype: 'checkbox', | |
111 | + name: 'arg' + index, | |
112 | + boxLabel: label, | |
113 | + inputValue: '1', | |
114 | + uncheckedValue: '0' | |
115 | + }); | |
116 | + }, | |
117 | + | |
118 | + addStringField: function(label, index) { | |
119 | + this.fieldsForm.add({ | |
120 | + xtype: 'textfield', | |
121 | + name: 'arg' + index, | |
122 | + fieldLabel: label | |
123 | + }); | |
124 | + }, | |
125 | + | |
126 | + init : function(config) { | |
127 | + this.fieldsForm = Ext.create('Ext.form.Panel', { | |
128 | + layout: { | |
129 | + type: 'vbox', | |
130 | + pack: 'start', | |
131 | + align: 'stretch' | |
132 | + } | |
133 | + }); | |
134 | + | |
135 | + var myConf = { | |
136 | + layout: 'fit', | |
137 | + title: 'Function arguments', | |
138 | + modal: true, | |
139 | + closeAction: 'hide', | |
140 | + width: 300, | |
141 | + height: 200, | |
142 | + items: [ | |
143 | + this.fieldsForm | |
144 | + ], | |
145 | + buttons: [ | |
146 | + { | |
147 | + text: 'Apply', | |
148 | + scope : this, | |
149 | + handler: function(bt,event) { | |
150 | + if (this.applyCallback) | |
151 | + this.applyCallback(this.fieldsForm.getValues()); | |
152 | + this.close(); | |
153 | + }, | |
154 | + }, | |
155 | + { | |
156 | + text: 'Cancel', | |
157 | + scope : this, | |
158 | + handler: function(bt,event) { | |
159 | + this.close(); | |
160 | + } | |
161 | + } | |
162 | + ] | |
163 | + }; | |
164 | + | |
165 | + Ext.apply(this, Ext.apply(arguments, myConf)); | |
166 | + } | |
167 | +}); | |
168 | + | |
169 | + | |
170 | + | |
19 | 171 | Ext.define('amdaUI.CalculatorUI', { |
20 | 172 | extend: 'Ext.util.Observable', |
21 | 173 | |
22 | 174 | requires: [ |
23 | 175 | 'amdaModel.Constant', |
24 | - 'amdaModel.Function' | |
176 | + 'amdaModel.Function', | |
177 | + 'amdaUI.PromptArgsWin' | |
25 | 178 | ], |
26 | 179 | |
27 | 180 | alias: 'plugin.calculator', |
28 | 181 | |
29 | 182 | statics: { |
30 | 183 | constantStore: null, |
31 | - functionStore: null | |
184 | + functionStore: null, | |
185 | + argslistStore: null | |
32 | 186 | }, |
33 | 187 | |
34 | 188 | win: null, |
189 | + promptArgsWin: null, | |
35 | 190 | |
36 | 191 | constructor: function (config) { |
37 | 192 | Ext.apply(this, config); |
... | ... | @@ -40,6 +195,8 @@ Ext.define('amdaUI.CalculatorUI', { |
40 | 195 | |
41 | 196 | init: function (cmp) |
42 | 197 | { |
198 | + this.promptArgsWin = Ext.create('amdaUI.PromptArgsWin', {}); | |
199 | + | |
43 | 200 | this.hostCmp = cmp; |
44 | 201 | this.hostCmp.on({ |
45 | 202 | scope: this, |
... | ... | @@ -113,7 +270,16 @@ Ext.define('amdaUI.CalculatorUI', { |
113 | 270 | } else |
114 | 271 | this.createAllBtns(); |
115 | 272 | |
116 | - | |
273 | + if (!amdaUI.CalculatorUI.argslistStore) | |
274 | + { | |
275 | + amdaUI.CalculatorUI.argslistStore = Ext.create('Ext.data.Store', {model: 'amdaModel.ArgList'}); | |
276 | + amdaUI.CalculatorUI.argslistStore.load({ | |
277 | + scope: this, | |
278 | + callback: function (records, operation, success) | |
279 | + { | |
280 | + } | |
281 | + }); | |
282 | + } | |
117 | 283 | }, |
118 | 284 | |
119 | 285 | onShow: function () { |
... | ... | @@ -185,14 +351,23 @@ Ext.define('amdaUI.CalculatorUI', { |
185 | 351 | */ |
186 | 352 | preProcessFormula: function (sel, currentBtn, params) { |
187 | 353 | |
188 | - if (currentBtn.initialConfig.args != 0 && currentBtn.initialConfig.prompt != "") { | |
354 | + if (currentBtn.initialConfig.args != 0 && currentBtn.initialConfig.prompts.count() > 0) { | |
189 | 355 | // Prompt for user precision and process the result using a callback |
190 | - Ext.Msg.prompt('Argument', currentBtn.initialConfig.prompt, function (bt2, text) { | |
356 | + /*Ext.Msg.prompt('Argument', currentBtn.initialConfig.prompts.getAt(0).get('prompt'), function (bt2, text) { | |
191 | 357 | if (bt2 === 'ok') { |
192 | 358 | var afterParamsText = text + ")"; |
193 | 359 | //TODO: more than one args and prompt |
194 | 360 | this.processFormula(sel, currentBtn, params, afterParamsText); |
195 | 361 | } |
362 | + }, this);*/ | |
363 | + this.promptArgsWin.promptArgs(currentBtn.initialConfig.prompts, function (values) { | |
364 | + var afterParamsText = ''; | |
365 | + Ext.Object.each(values, function(key, value) { | |
366 | + afterParamsText += (afterParamsText == '' ? '' : ','); | |
367 | + afterParamsText += value; | |
368 | + }); | |
369 | + afterParamsText += ')'; | |
370 | + this.processFormula(sel, currentBtn, params, afterParamsText); | |
196 | 371 | }, this); |
197 | 372 | } else { |
198 | 373 | if ( currentBtn.initialConfig.prompt_param != "" ) { |
... | ... | @@ -389,6 +564,7 @@ Ext.define('amdaUI.CalculatorUI', { |
389 | 564 | this.createFunctionBtns('PhysicsFunctions', 'Derived', '#calc_tab_func_id'); |
390 | 565 | this.createFunctionBtns('ModelFunctions', 'Models', '#calc_tab_func_id'); |
391 | 566 | this.createFunctionBtns('AmdaFunctions', 'TimeShift', '#calc_tab_func_id'); |
567 | + this.createFunctionBtns('FramesFunctions', 'Frames', '#calc_tab_func_id'); | |
392 | 568 | amdaUI.CalculatorUI.functionStore.clearFilter(); |
393 | 569 | |
394 | 570 | // group stat |
... | ... | @@ -492,6 +668,10 @@ Ext.define('amdaUI.CalculatorUI', { |
492 | 668 | amdaUI.CalculatorUI.functionStore.filter('kind', 'physics'); |
493 | 669 | width = .25; |
494 | 670 | break; |
671 | + case 'FramesFunctions' : | |
672 | + amdaUI.CalculatorUI.functionStore.filter('kind', 'frames'); | |
673 | + width = .45; | |
674 | + break; | |
495 | 675 | } |
496 | 676 | |
497 | 677 | var crtTab = funcTab[0].add( |
... | ... | @@ -507,7 +687,7 @@ Ext.define('amdaUI.CalculatorUI', { |
507 | 687 | text: f.get('name'), |
508 | 688 | args: f.get('args'), |
509 | 689 | defaultArgs: f.get('default_args'), |
510 | - prompt: f.get('prompt'), | |
690 | + prompts: f.prompts(), | |
511 | 691 | prompt_param: f.get('prompt_param'), |
512 | 692 | tooltip: f.get('info_brief'), |
513 | 693 | scope: this, | ... | ... |