source: Dev/trunk/src/client/dojox/calc/Standard.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 11.8 KB
Line 
1define([
2        "dojo/_base/declare",
3        "dojo/_base/lang",
4        "dojo/_base/sniff",
5        "dojo/_base/window",
6        "dojo/_base/event",
7        "dojo/dom-style",
8        "dojo/ready",
9        "dojo/keys",
10        "dijit/registry",
11        "dijit/typematic",
12        "dijit/_WidgetBase",
13        "dijit/_WidgetsInTemplateMixin",
14        "dijit/_TemplatedMixin",
15        "dijit/form/_TextBoxMixin",
16        "dojox/math/_base",
17        "dijit/TooltipDialog",
18        "dojo/text!./templates/Standard.html",
19        "dojox/calc/_Executor", // template
20        "dijit/Menu", // template
21        "dijit/MenuItem", // template
22        "dijit/form/ComboButton", // template
23        "dijit/form/Button", // template
24        "dijit/form/TextBox" // template
25], function(declare, lang, has, win, event, domStyle, ready, keys, registry, typematic, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, _TextBoxMixin, math, TooltipDialog, template, calc){
26
27        return declare(
28                "dojox.calc.Standard",
29                [WidgetBase, TemplatedMixin, WidgetsInTemplateMixin],
30        {
31                // summary:
32                //              The dialog layout for a standard 4 function/algebraic calculator
33
34                templateString: template,
35
36                readStore:null,
37                writeStore:null,
38                functions: [],
39
40                executorLoaded: function(){
41                        // summary:
42                        //              load in the stores after executor is loaded (the stores need executor to be loaded because it parses them)
43                        ready(lang.hitch(this, function(){
44                                this.loadStore(this.readStore, true);
45                                this.loadStore(this.writeStore);
46                        }));
47                },
48
49                saveFunction: function(name, args, body){
50                        // summary:
51                        //              make the function with executor
52                        this.functions[name] = this.executor.normalizedFunction(name, args, body);
53                        this.functions[name].args = args;
54                        this.functions[name].body = body;
55                },
56
57                loadStore: function(store, isReadOnly){
58                        // summary:
59                        //              load an entire store, and make it publicly editable/viewable based on isReadOnly
60                        if(!store){
61                                return;
62                        }
63                        store.query({}).forEach(lang.hitch(this, function(item){
64                                lang.hitch(this, isReadOnly ? this.executor.normalizedFunction : this.saveFunction)(item.name, item.args, item.body);
65                        }));
66                },
67
68                parseTextbox: function(){
69                        // summary:
70                        //              parse the contents of the textboxWidget and display the answer somewhere (depending on the layout)
71                        var text = this.textboxWidget.textbox.value;
72                        if(text == "" && this.commandList.length > 0){
73                                this.setTextboxValue(this.textboxWidget, this.commandList[this.commandList.length-1]);
74                                text = this.textboxWidget.textbox.value;
75                        }
76                        if(text!=""){
77                                var ans = this.executor.eval(text);
78
79                                if((typeof ans == "number" && isNaN(ans))){
80                                        if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
81                                                this.commandList.push(text);
82                                        }
83                                        this.print(text, false);
84                                        this.print("Not a Number", true);
85                                }else if(((typeof ans == "object" && "length" in ans) || typeof ans != "object") && typeof ans != "function" && ans != null){
86                                        this.executor.eval("Ans="+ans);
87                                        // add it to the command list as well
88                                        if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
89                                                this.commandList.push(text);
90                                        }
91                                        this.print(text, false);
92                                        this.print(ans, true);
93                                }
94                                this.commandIndex = this.commandList.length-1;
95                                //this.displayBox.textbox.scrollTop=this.displayBox.textbox.scrollHeight;
96                                if(this.hasDisplay){
97                                        this.displayBox.scrollTop=this.displayBox.scrollHeight;
98                                }
99                                //this.clearText();
100                                //this.textboxWidget.focus();
101                                _TextBoxMixin.selectInputText(this.textboxWidget.textbox);
102
103                        }else{
104                                this.textboxWidget.focus();
105                        }
106                },
107                cycleCommands: function(count, node, event){
108                        // summary:
109                        //              Cycle through the commands that the user has entered.
110                        //              It does not wrap around.
111                        if(count == -1 || this.commandList.length==0){
112                                return;
113                        }
114                        var keyNum = event.charOrCode;
115                        //up arrow
116                        if(keyNum == keys.UP_ARROW){
117                                this.cycleCommandUp();
118                        }else if(keyNum == keys.DOWN_ARROW){
119                                this.cycleCommandDown();
120                        }
121                },
122                cycleCommandUp: function(){
123                        // summary:
124                        //              cycle up through the list of commands the user has entered already
125                        if(this.commandIndex-1<0){
126                                this.commandIndex=0;
127                        }else{
128                                this.commandIndex--;
129                        }
130                        this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
131                },
132                cycleCommandDown: function(){
133                        // summary:
134                        //              cycle down through the list of commands the user has entered already
135                        if(this.commandIndex+1>=this.commandList.length){
136                                this.commandIndex=this.commandList.length;
137                                this.setTextboxValue(this.textboxWidget, "");
138                        }else{
139                                this.commandIndex++;
140                                this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
141                        }
142
143                },
144                onBlur: function(){
145                        // summary:
146                        //              IE is lacking in function when it comes to the text boxes, so here, make it work like other browsers do by forcing a node.selectionStart and End onto it
147                        if(has('ie')){
148                                var tr = win.doc.selection.createRange().duplicate();
149                                var selectedText = tr.text || '';
150                                var ntr = this.textboxWidget.textbox.createTextRange();
151                                tr.move("character",0);
152                                ntr.move("character",0);
153                                try{
154                                        ntr.setEndPoint("EndToEnd", tr);
155                                        this.textboxWidget.textbox.selectionEnd = (this.textboxWidget.textbox.selectionStart = String(ntr.text).replace(/\r/g,"").length) + selectedText.length;
156
157                                }catch(e){}
158                        }
159                },
160                onKeyPress: function(e){
161                        // summary:
162                        //              handle key input for Enter and operators
163                        if(e.charOrCode == keys.ENTER){
164                                this.parseTextbox();
165                                // stop form submissions
166                                event.stop(e);
167                        }else if(e.charOrCode == '!' || e.charOrCode == '^' || e.charOrCode == '*' || e.charOrCode == '/' || e.charOrCode == '-' || e.charOrCode == '+'){
168                                if(has('ie')){
169                                        var tr = win.doc.selection.createRange().duplicate();
170                                        var selectedText = tr.text || '';
171                                        var ntr = this.textboxWidget.textbox.createTextRange();
172                                        tr.move("character",0);
173                                        ntr.move("character",0);
174                                        try{
175                                                ntr.setEndPoint("EndToEnd", tr);
176                                                this.textboxWidget.textbox.selectionEnd = (this.textboxWidget.textbox.selectionStart = String(ntr.text).replace(/\r/g,"").length) + selectedText.length;
177
178                                        }catch(e){}
179                                }
180
181                                if(this.textboxWidget.get("value")==""){
182                                        this.setTextboxValue(this.textboxWidget, "Ans");
183                                }else if(this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox, event.charOrCode)){
184                                        this.setTextboxValue(this.textboxWidget, "Ans");//this.insertText("Ans");
185                                        // move the cursor to the end of "Ans"
186                                        _TextBoxMixin.selectInputText(this.textboxWidget.textbox, this.textboxWidget.textbox.value.length, this.textboxWidget.textbox.value.length);
187                                }
188                        }
189                },
190                insertMinus: function(){
191                        // summary:
192                        //              insert a minus sign when they press (-) in the combo button
193                        this.insertText('-');
194                },
195                print: function(text, isRight){
196                        // summary:
197                        //              print the answer (typically) to the display or the input box
198                        var t = "<span style='display:block;";
199                        if(isRight){
200                                t += "text-align:right;'>";
201                        }else{
202                                t += "text-align:left;'>";
203                        }
204                        t += text+"<br></span>";
205                        if(this.hasDisplay){
206                                this.displayBox.innerHTML += t;
207                        }else{// if there is not a display box, put the answer in the input box
208                                this.setTextboxValue(this.textboxWidget, text);
209                        }
210                        //this.setTextboxValue(this.displayBox, this.displayBox.get('value')+'\n'+text);
211                },
212                setTextboxValue: function(widget, val){
213                        // summary:
214                        //              set a widget's value
215                        widget.set('value', val);
216                },
217                putInAnsIfTextboxIsHighlighted: function(node){
218                        // summary:
219                        //              try seeing if the textbox is highlighted completely so you know if Ans should be put in for an operator like +
220
221                        //console.log("Entered "+node.selectionStart + " "+ node.selectionEnd);
222                        if(typeof node.selectionStart == "number"){ // not-IE
223                                if(node.selectionStart==0 && node.selectionEnd == node.value.length){
224                                        //node.value = "Ans";
225                                        //dijit.selectInputText(node, node.value.length, node.value.length);
226                                        return true;
227                                }
228                        }else if(document.selection){ // IE
229                                //console.log("Entered 2");
230                                var range = document.selection.createRange();
231                                //console.log("Range: "+range.text +" Node: "+node.value);
232                                if(node.value == range.text){
233                                        //this.insertText("Ans");
234                                        return true;
235                                }
236                        }
237                        return false;
238                },
239                clearText: function(){
240                        // summary:
241                        //              this clears the input box if it has content, but if it does not it clears the display
242                        if(this.hasDisplay && this.textboxWidget.get('value')==""){
243                                this.displayBox.innerHTML = "";//this.setTextboxValue(this.displayBox, "");
244                        }else{
245                                this.setTextboxValue(this.textboxWidget, "");
246                        }
247                        this.textboxWidget.focus();
248                },
249                /*insertMinusSign: function(){
250                        //
251                        var v = this.subtract.get('label');
252                        if(v != '(-)' && this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
253                                this.insertText("Ans-");
254                                return;
255                        }
256                        this.insertText('-');
257                },*/
258                insertOperator: function(newText){
259                        // summary:
260                        //              insert an operator with a button
261                        if(typeof newText == "object"){
262                                newText = newText = registry.getEnclosingWidget(newText["target"]).value;
263                        }
264                        if(this.textboxWidget.get("value") == "" || this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
265                                newText = "Ans"+newText;
266                        }
267                        this.insertText(newText);
268                },
269                insertText: function(newText){//(node, newText){
270                        // summary:
271                        //              insert text to the textboxWidget node
272                        setTimeout(lang.hitch(this, function(){
273
274                        var node = this.textboxWidget.textbox;
275                        if(node.value==""){
276                                node.selectionStart = 0;
277                                node.selectionEnd = 0;
278                        }
279                        if(typeof newText == "object"){
280                                newText = newText = registry.getEnclosingWidget(newText["target"]).value;
281                        }
282
283                        var value = node.value.replace(/\r/g,'');
284                        if(typeof node.selectionStart == "number"){ // not-IE
285                                var pos = node.selectionStart;
286                                var cr = 0;
287                                if(has('opera')){
288                                        cr = (node.value.substring(0,pos).match(/\r/g) || []).length;
289                                }
290                                node.value = value.substring(0, node.selectionStart-cr) + newText + value.substring(node.selectionEnd-cr);
291                                node.focus();
292                                pos += newText.length;
293                                //node.setSelectionRange(pos, pos);
294                                _TextBoxMixin.selectInputText(this.textboxWidget.textbox, pos, pos);
295                        }else if(document.selection){ // IE
296                                if(this.handle){
297                                        clearTimeout(this.handle);
298                                        this.handle = null;
299                                }
300                                node.focus();
301                                this.handle = setTimeout(function(){
302                                        var range = document.selection.createRange();
303                                        range.text = newText;
304                                        // show cursor
305                                        range.select();
306                                        this.handle = null;
307                                }, 0);
308
309                        }
310                        }), 0);
311                },
312                hasDisplay: false,
313                postCreate: function(){
314                        // summary:
315                        //              run startup, see if there is an upper display box, etc
316                        this.handle = null;
317                        this.commandList = [];
318                        this.commandIndex = 0;
319
320                        if(this.displayBox){
321                                this.hasDisplay = true;
322                        }
323                        if(this.toFracButton && !calc.toFrac){
324                                domStyle.set(this.toFracButton.domNode, { visibility: "hidden" });
325                        }
326                        if(this.functionMakerButton && !calc.FuncGen){
327                                domStyle.set(this.functionMakerButton.domNode, { visibility: "hidden" });
328                        }
329                        if(this.grapherMakerButton && !calc.Grapher){
330                                domStyle.set(this.grapherMakerButton.domNode, { visibility: "hidden" });
331                        }
332                        this._connects.push(typematic.addKeyListener(this.textboxWidget.textbox,
333                                        {
334                                                charOrCode:keys.UP_ARROW,
335                                                shiftKey:false,
336                                                metaKey:false,
337                                                ctrlKey:false // ALT is optional since its unspecified
338                                        },
339                                        this, this.cycleCommands, 200, 200));
340                        this._connects.push(typematic.addKeyListener(this.textboxWidget.textbox,
341                                        {
342                                                charOrCode:keys.DOWN_ARROW,
343                                                shiftKey:false,
344                                                metaKey:false,
345                                                ctrlKey:false // ALT is optional since its unspecified
346                                        },
347                                        this, this.cycleCommands, 200, 200));
348
349
350                        //onClick="this.insertText(document.getElementById('textbox'), '\u221A')"
351                        //this.sqrt.set("onClick", lang.hitch(this, "insertText", this.textboxWidget, '\u221A'));
352                        //this.pi.set("onClick", lang.hitch(this, "insertText", this.textboxWidget, '\u03C0'));
353                        this.startup()
354                }
355        });
356
357});
Note: See TracBrowser for help on using the repository browser.