~f-riccardo87/ubuntu-calculator-app/new-design

« back to all changes in this revision

Viewing changes to Scientific/ScientificPage.qml

  • Committer: Riccardo Ferrazzo
  • Date: 2013-03-08 09:35:39 UTC
  • Revision ID: f.riccardo87@gmail.com-20130308093539-4x88cnd6qswxwobe
scientific calculator merged

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import QtQuick 2.0
 
2
import Ubuntu.Components 0.1
 
3
import "../engine.js" as CALC
 
4
 
 
5
Page {
 
6
 
 
7
    property string formula_text: '';
 
8
    property string brackets_added: '';
 
9
    property string formula_text_for_engine: '';
 
10
    property var formula: [];
 
11
    property string answer: '';
 
12
    property string angularUnit: 'RAD';
 
13
 
 
14
    function formulaPush(visual, engine, type) {
 
15
        var prev = null;
 
16
        if (formula.length > 0)
 
17
            prev = formula[formula.length-1];
 
18
 
 
19
        var result = CALC.getFormulaTexts(prev, visual, engine, type, brackets_added.length/2)
 
20
 
 
21
        var visual_text = result[0];
 
22
        var engine_text = result[1];
 
23
        var fixed_type = result[2];
 
24
        var brackets_count = result[3];
 
25
 
 
26
        brackets_added = brackets_added.substr(0, brackets_count*2);
 
27
 
 
28
        if (visual_text !== null && engine_text !== null) {
 
29
            formula_text += visual_text;
 
30
            formula_text_for_engine += engine_text;
 
31
            formula.push({'visual': visual_text, 'engine': engine_text, 'type': fixed_type});
 
32
 
 
33
            answer = calculate()
 
34
        }
 
35
        else {
 
36
            formulaView.showError();
 
37
        }
 
38
    }
 
39
 
 
40
    function formulaPop() {
 
41
        if (formula.length > 0) {
 
42
            var prev = formula[formula.length-1];
 
43
            formula_text = formula_text.substring(0, formula_text.length - prev.visual.length);
 
44
            formula_text_for_engine = formula_text_for_engine.substring(0, formula_text_for_engine.length - prev.engine.length);
 
45
            if (prev.type === 'function' || (prev.type === 'group' && prev.engine === '(' || prev.engine === '*('))
 
46
                brackets_added = brackets_added.substring(0, brackets_added.length-2)
 
47
            else if (prev.type === 'group' && prev.engine === ')')
 
48
                brackets_added += " )"
 
49
            formula.pop();
 
50
 
 
51
            answer = calculate()
 
52
        }
 
53
    }
 
54
 
 
55
    function formulaReset() {
 
56
        formula_text = '';
 
57
        formula_text_for_engine = '';
 
58
        formula = [];
 
59
        answer = "";
 
60
        brackets_added = '';
 
61
    }
 
62
 
 
63
    function calculate() {
 
64
 
 
65
        console.debug('Formula for engine: ' + formula_text_for_engine)
 
66
 
 
67
        var result = 0;
 
68
        try {
 
69
            result = CALC.parse(angularUnit + formula_text_for_engine + brackets_added);
 
70
            if (result === Number.POSITIVE_INFINITY)
 
71
                result = '∞';
 
72
            else if (result === Number.NEGATIVE_INFINITY)
 
73
                result = '-∞';
 
74
        } catch(exception) {
 
75
            if(exception instanceof CALC.DivisionByZeroError){
 
76
                result = "division by zero error";
 
77
            } else if(exception instanceof SyntaxError){
 
78
                result = "";
 
79
            } else if(exception instanceof CALC.ParenthesisError){
 
80
                if(exception.missing === '(')
 
81
                    brackets_added = brackets_added.substr(0, brackets_added.length-2);
 
82
                else
 
83
                    brackets_added+=(' '+exception.missing);
 
84
                result = calculate();
 
85
            }
 
86
        }
 
87
        return result;
 
88
    }
 
89
 
 
90
    function addFromMemory(answerToAdd, formulaData) {
 
91
        if (answerToAdd !== '' && answerToAdd.indexOf('error') === -1 && answerToAdd.indexOf('∞') === -1) {
 
92
            for (var i = 0; i < answerToAdd.length; i++)
 
93
                formulaPush(answerToAdd[i], answerToAdd[i], answerToAdd[i] === '.' ? 'real' : 'number')
 
94
        }
 
95
        else {
 
96
            var fd = JSON.parse(formulaData);
 
97
 
 
98
            var prev = null;
 
99
            if (formula.length > 0)
 
100
                prev = formula[formula.length-1];
 
101
 
 
102
            var result = CALC.getFormulaTexts(prev, fd[0].engine, fd[0].engine, fd[0].type, brackets_added.length/2)
 
103
 
 
104
            if (result[0] !== null && result[1] !== null) {
 
105
                for (var idx = 0; idx < fd.length; idx++) {
 
106
                    formula_text += fd[idx].visual;
 
107
                    formula_text_for_engine += fd[idx].engine;
 
108
                    formula.push({'visual': fd[idx].visual, 'engine': fd[idx].engine, 'type': fd[idx].type});
 
109
                }
 
110
                answer = calculate()
 
111
            }
 
112
        }
 
113
    }
 
114
 
 
115
    Item {
 
116
        anchors.fill: parent
 
117
 
 
118
        ListView {
 
119
            id: formulaView
 
120
            anchors.fill: parent
 
121
            snapMode: ListView.SnapOneItem
 
122
            clip: true
 
123
 
 
124
            property string currentFormula: '%1<font color="lightgray">%2</font>'.arg(formula_text).arg(brackets_added)
 
125
            property string currentAnswer: answer
 
126
            property color color: "#FFFFFF";
 
127
            property bool positionedAtEnd: true;
 
128
 
 
129
            function addCurrentToMemory() {
 
130
                if (formula_text !== '') {
 
131
                    memory.get(memory.count-1).isLastItem = false
 
132
                    memory.get(memory.count-1).formula_data = JSON.stringify(formula)
 
133
                    memory.append({'formula': memory.get(memory.count-1).formula, 'answer': memory.get(count-1).answer, 'formula_data': '', 'isLastItem': true})
 
134
                    positionViewAtEnd();
 
135
                }
 
136
            }
 
137
 
 
138
            function showError() {
 
139
                animateError.start()
 
140
            }
 
141
 
 
142
            PropertyAnimation {id: animateError; target: formulaView; properties: "color"; from: "#FFA0A0"; to: "#FFFFFF"; duration: 100}
 
143
 
 
144
            add: Transition{
 
145
                SequentialAnimation {
 
146
                    NumberAnimation {property: "y"; from: formulaView.footerItem.y; to: formulaView.contentY; duration: 200; }
 
147
                    ParallelAnimation{
 
148
                        NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 200 }
 
149
                        NumberAnimation { property: "y"; from: formulaView.contentY; duration: 0 }
 
150
                    }
 
151
                }
 
152
            }
 
153
 
 
154
            onCurrentFormulaChanged: {
 
155
                memory.get(memory.count-1).formula = currentFormula
 
156
                positionViewAtEnd();
 
157
            }
 
158
 
 
159
            onCurrentAnswerChanged: {
 
160
                memory.get(memory.count-1).answer = currentAnswer
 
161
            }
 
162
 
 
163
            onContentYChanged: {
 
164
                positionedAtEnd = formulaView.indexAt(0, contentY+0) == formulaView.model.count-1
 
165
            }
 
166
 
 
167
            model: Memory{
 
168
                id: memory
 
169
            }
 
170
 
 
171
            delegate: Screen {
 
172
                id: screen
 
173
                width: formulaView.width
 
174
 
 
175
                onUseAnswer: addFromMemory(answerToUse, formulaData)
 
176
            }
 
177
 
 
178
            footer: KeyboardsView {
 
179
                height: formulaView.height - units.gu(24)
 
180
            }
 
181
 
 
182
            Scrollbar {
 
183
                flickableItem: formulaView
 
184
                align: Qt.AlignTrailing
 
185
            }
 
186
        }
 
187
    }
 
188
}