Merge lp:~zsombi/ubuntu-ui-toolkit/calculator-example into lp:ubuntu-ui-toolkit

Proposed by Zsombor Egri
Status: Merged
Approved by: Tim Peeters
Approved revision: 570
Merged at revision: 577
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/calculator-example
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 598 lines (+550/-1)
8 files modified
examples/calculator/calculator.desktop (+8/-0)
examples/calculator/calculator.pro (+18/-0)
examples/calculator/calculator.qml (+126/-0)
examples/calculator/calculator.qmlproject (+31/-0)
examples/calculator/components/DefaultLayout.qml (+100/-0)
examples/calculator/components/Functions.qml (+46/-0)
examples/calculator/components/calculator.js (+219/-0)
examples/examples.pro (+2/-1)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/calculator-example
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Pending
Review via email: mp+172534@code.launchpad.net

Commit message

Calculator example which turns from simple calculator (phone portrait mode) into scientific one (phone landscape mode) reflecting the use of Ubuntu.Layouts.

To post a comment you must log in.
567. By Zsombor Egri

makefile removed; pro-file added to fix application installation; desktop file corrected

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
568. By Zsombor Egri

license headers updated

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
569. By Zsombor Egri

trunk merge

570. By Zsombor Egri

memory indication added

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

on desktop, the text is very tiny, can we scale the text with the buttons?

Revision history for this message
Tim Peeters (tpeeters) wrote :

why add this example? We have a calculator app https://wiki.ubuntu.com/Touch/CoreApps/Calculator

Revision history for this message
Tim Peeters (tpeeters) wrote :

why do you have a Flickable? The buttons resize to fit in the view without flicking.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> on desktop, the text is very tiny, can we scale the text with the buttons?

Button label cannot be enlarged only with creating a different style for it.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> why add this example? We have a calculator app
> https://wiki.ubuntu.com/Touch/CoreApps/Calculator

As we discussed, the app we have does not forbid us to create a simplier one to illustrate what we can do with certain SDK building blocks.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> why do you have a Flickable? The buttons resize to fit in the view without
> flicking.

Without Flickable the content goes below the Header :(. Haven't found a better way atm to circumvent that...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'examples/calculator'
=== added file 'examples/calculator/calculator.desktop'
--- examples/calculator/calculator.desktop 1970-01-01 00:00:00 +0000
+++ examples/calculator/calculator.desktop 2013-07-03 06:43:28 +0000
@@ -0,0 +1,8 @@
1[Desktop Entry]
2Name=calculator
3Comment=My project description
4Exec=/usr/bin/qmlscene $@ /usr/lib/ubuntu-ui-toolkit/examples/calculator/calculator.qml
5Icon=qmlscene
6Terminal=false
7Type=Application
8X-Ubuntu-Touch=true
09
=== added file 'examples/calculator/calculator.pro'
--- examples/calculator/calculator.pro 1970-01-01 00:00:00 +0000
+++ examples/calculator/calculator.pro 2013-07-03 06:43:28 +0000
@@ -0,0 +1,18 @@
1TEMPLATE = subdirs
2
3filetypes = qml png svg js qmltheme jpg qmlproject desktop wav
4
5OTHER_FILES = ""
6
7for(filetype, filetypes) {
8 OTHER_FILES += *.$$filetype
9}
10
11desktop_files.path = /usr/share/applications
12desktop_files.files = calculator.desktop
13
14other_files.path = /usr/lib/ubuntu-ui-toolkit/examples/calculator
15other_files.files = $$OTHER_FILES
16
17INSTALLS += other_files desktop_files
18
019
=== added file 'examples/calculator/calculator.qml'
--- examples/calculator/calculator.qml 1970-01-01 00:00:00 +0000
+++ examples/calculator/calculator.qml 2013-07-03 06:43:28 +0000
@@ -0,0 +1,126 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Zsombor Egri <zsombor.egri@canonical.com>
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 0.1
21import Ubuntu.Layouts 0.1
22import "components"
23import "components/calculator.js" as Calculator
24
25/*!
26 \brief MainView with a Label and Button elements.
27*/
28
29MainView {
30 id: mainView
31 // objectName for functional testing purposes (autopilot-qt5)
32 objectName: "mainView"
33
34 // Note! applicationName needs to match the .desktop filename
35 applicationName: "calculator"
36
37 /*
38 This property enables the application to change orientation
39 when the device is rotated. The default is false.
40 */
41 automaticOrientation: true
42
43 width: units.gu(40)
44 height: units.gu(71)
45
46 property var calculator: new Calculator.Calculator(numericInput, memoryIndicator);
47
48 // default portrait layout
49 Page {
50 id: page
51 title: i18n.tr("Calculator")
52 anchors.fill: parent
53
54 Flickable {
55 anchors.fill: parent
56 contentWidth: column.width
57 contentHeight: column.height
58 Column {
59 id: column
60 width: page.width
61 height: childrenRect.height
62 spacing: units.gu(0.5)
63 TextField {
64 id: numericInput
65 anchors {
66 left: parent.left
67 right: parent.right
68 }
69 readOnly: true
70 font.pixelSize: FontUtils.sizeToPixels("x-large")
71 font.bold: true
72 horizontalAlignment: Text.AlignRight
73 height: layout.currentLayout === "landscape" ?
74 units.gu(5) : units.gu(7)
75 primaryItem: Label {
76 id: memoryIndicator
77 width: units.gu(3)
78 height: parent.height
79 text: "M"
80 fontSize: "large"
81 font.bold: true
82 }
83 }
84
85 Layouts {
86 id: layout
87 anchors {
88 left: parent.left
89 right: parent.right
90 }
91 height: page.height - numericInput.height - mainView.header.height
92
93 layouts: [
94 ConditionalLayout {
95 name: "landscape"
96 when: mainView.width > mainView.height
97 Item {
98 anchors.fill: parent
99 Functions {
100 operations: calculator
101 anchors.fill: parent
102 anchors.rightMargin: parent.width / 2 + units.gu(0.25)
103 spacing: units.gu(0.4)
104 }
105
106 ItemLayout {
107 item: "buttons"
108 anchors.fill: parent
109
110 anchors.leftMargin: parent.width / 2 + units.gu(0.25)
111 }
112 }
113 }
114
115 ]
116 DefaultLayout {
117 anchors.fill: parent
118 anchors.margins: units.gu(0.5)
119 operations: calculator
120 spacing: (layout.currentLayout === "landscape") ? units.gu(0.4) : units.gu(2)
121 }
122 }
123 }
124 }
125 }
126}
0127
=== added file 'examples/calculator/calculator.qmlproject'
--- examples/calculator/calculator.qmlproject 1970-01-01 00:00:00 +0000
+++ examples/calculator/calculator.qmlproject 2013-07-03 06:43:28 +0000
@@ -0,0 +1,31 @@
1/* File generated by Qt Creator (with Ubuntu Plugin), version 2.7.1 */
2
3import QmlProject 1.1
4
5Project {
6 mainFile: "calculator.qml"
7
8 /* Include .qml, .js, and image files from current directory and subdirectories */
9 QmlFiles {
10 directory: "."
11 }
12 JavaScriptFiles {
13 directory: "."
14 }
15 ImageFiles {
16 directory: "."
17 }
18 Files {
19 filter: "*.desktop"
20 }
21 Files {
22 directory: "html"
23 filter: "*"
24 }
25 Files {
26 directory: "debian"
27 filter: "*"
28 }
29 /* List of plugin directories passed to QML runtime */
30 importPaths: [ "." ,"/usr/bin","/usr/lib/*/qt5/qml" ]
31}
032
=== added directory 'examples/calculator/components'
=== added file 'examples/calculator/components/DefaultLayout.qml'
--- examples/calculator/components/DefaultLayout.qml 1970-01-01 00:00:00 +0000
+++ examples/calculator/components/DefaultLayout.qml 2013-07-03 06:43:28 +0000
@@ -0,0 +1,100 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Zsombor Egri <zsombor.egri@canonical.com>
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 0.1
21import Ubuntu.Layouts 0.1
22
23Item {
24 id: buttonGrid
25 Layouts.item: "buttons"
26
27 property real spacing: units.gu(0.5)
28 property real buttonHeight: (buttonGrid.height - 5 * buttonGrid.spacing) / 6
29 property real buttonWidth: (buttonGrid.width - 3 * buttonGrid.spacing) / 4
30
31 property var operations
32
33 property var __model: [
34 {"label": "mc", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight},
35 {"label": "m+", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight},
36 {"label": "m-", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight},
37 {"label": "mr", "color": "darkgray", "width" : buttonWidth, "height": buttonHeight},
38
39 {"label": "c", "color": "brown", "width" : buttonWidth, "height": buttonHeight},
40 {"label": "+/-", "color": "brown", "width" : buttonWidth, "height": buttonHeight},
41 {"label": "/", "color": "brown", "width" : buttonWidth, "height": buttonHeight},
42 {"label": "*", "color": "brown", "width" : buttonWidth, "height": buttonHeight},
43
44 {"label": "7", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
45 {"label": "8", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
46 {"label": "9", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
47 {"label": "-", "color": "brown", "width" : buttonWidth, "height": buttonHeight},
48
49 {"label": "4", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
50 {"label": "5", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
51 {"label": "6", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
52 {"label": "+", "color": "brown", "width" : buttonWidth, "height": buttonHeight},
53
54 {"label": "1", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
55 {"label": "2", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
56 {"label": "3", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
57 {"label": "=", "color": "orange", "width" : buttonWidth, "height": buttonHeight * 2 + spacing},
58 ]
59 property var __lastRow: [
60 {"label": "0", "color": "#5f5f5f", "width" : 2 * buttonWidth + spacing, "height": buttonHeight},
61 {"label": ".", "color": "#5f5f5f", "width" : buttonWidth, "height": buttonHeight},
62 ]
63 Grid {
64 id: grid
65 spacing: buttonGrid.spacing
66 anchors.fill: parent
67
68 // memory
69 Repeater {
70 model: __model
71 delegate: Button {
72 text: modelData.label
73 color: modelData.color
74 width: modelData.width
75 height: modelData.height
76 onClicked: operations.execute(modelData.label)
77 }
78 }
79 }
80 Row {
81 anchors{
82 top: grid.bottom
83 topMargin: -buttonHeight
84 }
85
86 spacing: buttonGrid.spacing
87
88 // memory
89 Repeater {
90 model: __lastRow
91 delegate: Button {
92 text: modelData.label
93 color: modelData.color
94 width: modelData.width
95 height: modelData.height
96 onClicked: operations.execute(modelData.label)
97 }
98 }
99 }
100}
0101
=== added file 'examples/calculator/components/Functions.qml'
--- examples/calculator/components/Functions.qml 1970-01-01 00:00:00 +0000
+++ examples/calculator/components/Functions.qml 2013-07-03 06:43:28 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Zsombor Egri <zsombor.egri@canonical.com>
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 0.1
21import Ubuntu.Layouts 0.1
22
23Grid {
24 id: buttonGrid
25 columns: 4
26 rows: 7
27 spacing: units.gu(1)
28
29 property var operations
30
31 Repeater {
32 model: [
33 "%", "1/x", "x!", "x^2",
34 "x^3", "x^y", "2^x", "sqrt",
35 "ln", "e^x", "sin()", "cos()",
36 "tan()", "cot()", "sec()", "csc()",
37 ]
38 delegate: Button {
39 text: modelData
40 width: (buttonGrid.width - 3 * buttonGrid.spacing) / 4
41 height: (buttonGrid.height - 3 * buttonGrid.spacing) / 4
42 onClicked: operations.execute(modelData)
43 }
44 }
45
46}
047
=== added file 'examples/calculator/components/calculator.js'
--- examples/calculator/components/calculator.js 1970-01-01 00:00:00 +0000
+++ examples/calculator/components/calculator.js 2013-07-03 06:43:28 +0000
@@ -0,0 +1,219 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Zsombor Egri <zsombor.egri@canonical.com>
17 */
18
19.pragma library
20
21function Calculator(textInput, memoryIndicator) {
22 var operationStage = 0; // 0-lvalue, 1-rvalue
23 var lvalue = 0.0;
24 var rvalue = 0.0;
25 var lastOperation = -1;
26 var memory = 0.0;
27 var clearInputNext = true;
28
29 textInput.text = lvalue;
30 memoryIndicator.visible = false;
31
32 function setValue(value) {
33 if (operationStage === 0) {
34 lvalue = parseFloat(value);
35 return lvalue;
36 } else if (operationStage === 1) {
37 rvalue = parseFloat(value);
38 return rvalue;
39 }
40 }
41 function value() {
42 return (operationStage === 0) ? lvalue : rvalue;
43 }
44
45 function clear() {
46 operationStage = 1;
47 lvalue = rvalue = 0;
48 lastOperation = -1;
49 textInput.text = 0.0;
50 }
51 function memClear() {
52 memory = 0;
53 memoryIndicator.visible = false;
54 }
55 function memRecall() {
56 if (memory <= 0)
57 return;
58 textInput.text = setValue(memory);
59 }
60 function memAdd() {
61 memory += value();
62 textInput.text = setValue(memory);
63 memoryIndicator.visible = true;
64 }
65 function memDec() {
66 memory -= value();
67 textInput.text = setValue(memory);
68 memoryIndicator.visible = true;
69 }
70
71 // arythmetic functions
72 function add() {
73 lvalue += rvalue;
74 }
75 function dec() {
76 lvalue -= rvalue;
77 }
78 function mul() {
79 lvalue *= rvalue;
80 }
81 function div() {
82 lvalue /= rvalue;
83 }
84
85 function sign() {
86 textInput.text = setValue(-value());
87 }
88
89 function invert() {
90 textInput.text = setValue(1/value());
91 }
92 function percent() {
93 textInput.text = setValue(value() / 100);
94 }
95 function sqr() {
96 textInput.text = setValue(Math.pow(value(), 2));
97 }
98 function cube() {
99 textInput.text = setValue(Math.pow(value(), 3));
100 }
101 function power() {
102 lvalue = Math.pow(lvalue, rvalue);
103 }
104 function powerOf2() {
105 textInput.text = setValue(Math.pow(2, value()));
106 }
107 function factorial() {
108 var rval = 1;
109 for (var i = 2; i <= value(); i++) {
110 rval *= i;
111 }
112 textInput.text = setValue(rval);
113 }
114 function sqrt() {
115 textInput.text = setValue(Math.sqrt(value()));
116 }
117 function ln() {
118 textInput.text = setValue(Math.log(value()));
119 }
120 function exp()
121 {
122 textInput.text = setValue(Math.exp(value()));
123 }
124 function sin() {
125 textInput.text = setValue(Math.sin(value()));
126 }
127 function cos() {
128 textInput.text = setValue(Math.cos(value()));
129 }
130 function tan() {
131 textInput.text = setValue(Math.tan(value()));
132 }
133 function cot() {
134 textInput.text = setValue(1/Math.tan(value()));
135 }
136 function sec() {
137 textInput.text = setValue(1/Math.cos(value()));
138 }
139 function csc() {
140 textInput.text = setValue(1/Math.sin(value()));
141 }
142
143 var operations = [
144 {code: "+", operationFunc: add},
145 {code: "-", operationFunc: dec},
146 {code: "*", operationFunc: mul},
147 {code: "/", operationFunc: div},
148
149 {code: "+/-", controlFunc: sign},
150 {code: "c", controlFunc: clear},
151
152 {code: "mc", controlFunc: memClear},
153 {code: "mr", controlFunc: memRecall},
154 {code: "m+", controlFunc: memAdd},
155 {code: "m-", controlFunc: memDec},
156
157 {code: "%", controlFunc: percent},
158 {code: "1/x", controlFunc: invert},
159 {code: "x!", controlFunc: factorial},
160 {code: "x^2", controlFunc: sqr},
161 {code: "x^3", controlFunc: cube},
162 {code: "x^y", operationFunc: power},
163 {code: "2^x", controlFunc: powerOf2},
164 {code: "sqrt", controlFunc: sqrt},
165 {code: "ln", controlFunc: ln},
166 {code: "e^x", controlFunc: exp},
167 {code: "sin()", controlFunc: sin},
168 {code: "cos()", controlFunc: cos},
169 {code: "tan()", controlFunc: tan},
170 {code: "cot()", controlFunc: cot},
171 {code: "sec()", controlFunc: sec},
172 {code: "csc()", controlFunc: csc},
173
174 ];
175
176 this.execute = function (operation) {
177 if (operation === "=") {
178 if (lastOperation > -1) {
179 operations[lastOperation].operationFunc();
180 textInput.text = lvalue;
181 }
182 operationStage = 0;
183 clearInputNext = true;
184 } else {
185 for (var i = 0; i < operations.length; i++) {
186 if (operations[i].code === operation) {
187 if (operations[i].operationFunc) {
188 clearInputNext = true;
189 if (operations[i].singleOp) {
190 operations[i].operationFunc();
191 return;
192 }
193
194 lastOperation = i;
195 if (operationStage === 0) {
196 operationStage = 1;
197 } else if (operationStage === 1) {
198 // evaluate and continue receiving rvalue
199 operations[i].operationFunc(lvalue, rvalue);
200 textInput.text = lvalue;
201 }
202 } else if (operations[i].controlFunc) {
203 operations[i].controlFunc();
204 clearInputNext = true;
205 }
206
207 return;
208 }
209 }
210
211 // if no opeartion was performed, add operation to input
212 if (clearInputNext) {
213 clearInputNext = false;
214 textInput.text = "";
215 }
216 textInput.text = setValue(textInput.text + operation);
217 }
218 }
219}
0220
=== modified file 'examples/examples.pro'
--- examples/examples.pro 2013-06-26 22:55:34 +0000
+++ examples/examples.pro 2013-07-03 06:43:28 +0000
@@ -4,7 +4,8 @@
4 ubuntu-ui-toolkit-gallery\4 ubuntu-ui-toolkit-gallery\
5 jokes \5 jokes \
6 locale \6 locale \
7 unit-converter7 unit-converter \
8 calculator
89
910
10#examples = jokes unit-converter11#examples = jokes unit-converter

Subscribers

People subscribed via source and target branches

to status/vote changes: