comparison examples/widgets/calculator/calculator.d @ 1:e78566595089

initial import
author mandel
date Mon, 11 May 2009 16:01:50 +0000
parents
children 3ea0efe4d31e
comparison
equal deleted inserted replaced
0:36fb74dc547d 1:e78566595089
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Qt Software Information (qt-info@nokia.com)
5 **
6 ** This file is part of the example classes of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial Usage
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Nokia.
14 **
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at qt-sales@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 module calculator;
43
44 import qt.gui.QDialog;
45 import qt.gui.QGridLayout;
46 import qt.gui.QLineEdit;
47 import qt.gui.QFont;
48
49 import tango.math.Math : pow, sqrt;
50 import Float = tango.text.convert.Float;
51 import Integer = tango.text.convert.Integer;
52 import tango.core.Array;
53
54 import button;
55
56
57 class Calculator : public QDialog
58 {
59
60 public:
61
62 this(QWidget parent = null)
63 {
64 super(parent);
65
66 sumInMemory = 0.0;
67 sumSoFar = 0.0;
68 factorSoFar = 0.0;
69 waitingForOperand = true;
70
71 display = new QLineEdit("0");
72 display.setReadOnly(true);
73 display.setAlignment(Qt.AlignRight);
74 display.setMaxLength(15);
75
76 QFont font = display.font();
77 font.setPointSize(font.pointSize() + 8);
78 display.setFont(font);
79
80 for (int i = 0; i < NumDigitButtons; ++i) {
81 digitButtons[i] = createButton(Integer.toString(i), &digitClicked);
82 }
83
84 Button pointButton = createButton(tr("."), &pointClicked);
85 Button changeSignButton = createButton(tr("+/-"), &changeSignClicked);
86
87 Button backspaceButton = createButton(tr("Backspace"), &backspaceClicked);
88 Button clearButton = createButton(tr("Clear"), &clear);
89 Button clearAllButton = createButton(tr("Clear All"), &clearAll);
90
91 Button clearMemoryButton = createButton(tr("MC"), &clearMemory);
92 Button readMemoryButton = createButton(tr("MR"), &readMemory);
93 Button setMemoryButton = createButton(tr("MS"), &setMemory);
94 Button addToMemoryButton = createButton(tr("M+"), &addToMemory);
95
96 Button divisionButton = createButton(tr("/"), &multiplicativeOperatorClicked);
97 Button timesButton = createButton(tr("*"), &multiplicativeOperatorClicked);
98 Button minusButton = createButton(tr("-"), &additiveOperatorClicked);
99 Button plusButton = createButton(tr("+"), &additiveOperatorClicked);
100
101 Button squareRootButton = createButton(tr("Sqrt"), &unaryOperatorClicked);
102 Button powerButton = createButton(tr("x^2"), &unaryOperatorClicked);
103 Button reciprocalButton = createButton(tr("1/x"), &unaryOperatorClicked);
104 Button equalButton = createButton(tr("="), &equalClicked);
105
106 QGridLayout mainLayout = new QGridLayout();
107
108 mainLayout.setSizeConstraint(QLayout.SetFixedSize);
109
110 mainLayout.addWidget(display, 0, 0, 1, 6);
111 mainLayout.addWidget(backspaceButton, 1, 0, 1, 2);
112 mainLayout.addWidget(clearButton, 1, 2, 1, 2);
113 mainLayout.addWidget(clearAllButton, 1, 4, 1, 2);
114
115 mainLayout.addWidget(clearMemoryButton, 2, 0);
116 mainLayout.addWidget(readMemoryButton, 3, 0);
117 mainLayout.addWidget(setMemoryButton, 4, 0);
118 mainLayout.addWidget(addToMemoryButton, 5, 0);
119
120 for (int i = 1; i < NumDigitButtons; ++i) {
121 int row = ((9 - i) / 3) + 2;
122 int column = ((i - 1) % 3) + 1;
123 mainLayout.addWidget(digitButtons[i], row, column);
124 }
125
126 mainLayout.addWidget(digitButtons[0], 5, 1);
127 mainLayout.addWidget(pointButton, 5, 2);
128 mainLayout.addWidget(changeSignButton, 5, 3);
129
130 mainLayout.addWidget(divisionButton, 2, 4);
131 mainLayout.addWidget(timesButton, 3, 4);
132 mainLayout.addWidget(minusButton, 4, 4);
133 mainLayout.addWidget(plusButton, 5, 4);
134
135 mainLayout.addWidget(squareRootButton, 2, 5);
136 mainLayout.addWidget(powerButton, 3, 5);
137 mainLayout.addWidget(reciprocalButton, 4, 5);
138 mainLayout.addWidget(equalButton, 5, 5);
139 setLayout(mainLayout);
140
141 setWindowTitle(tr("Calculator"));
142 }
143
144 //private slots:
145 void digitClicked()
146 {
147 Button clickedButton = cast(Button) signalSender();
148 int digitValue = Integer.toInt(clickedButton.text);
149 if (display.text() == "0" && digitValue == 0.0)
150 return;
151
152 if (waitingForOperand) {
153 display.clear();
154 waitingForOperand = false;
155 }
156 display.setText(display.text() ~ Integer.toString(digitValue));
157 }
158
159 void unaryOperatorClicked()
160 {
161 Button clickedButton = cast(Button) signalSender();
162 char[] clickedOperator = clickedButton.text();
163 double operand = Float.toFloat(display.text);
164 double result = 0.0;
165
166 if (clickedOperator == tr("Sqrt")) {
167 if (operand < 0.0) {
168 abortOperation();
169 return;
170 }
171 result = sqrt(operand);
172 } else if (clickedOperator == tr("x^2")) {
173 result = pow(operand, 2.0);
174 } else if (clickedOperator == tr("1/x")) {
175 if (operand == 0.0) {
176 abortOperation();
177 return;
178 }
179 result = 1.0 / operand;
180 }
181 display.setText(Float.toString(result, 4));
182 waitingForOperand = true;
183 }
184
185 void additiveOperatorClicked()
186 {
187 Button clickedButton = cast(Button) signalSender();
188 char[] clickedOperator = clickedButton.text();
189 double operand = Float.toFloat(display.text);
190
191 if (pendingMultiplicativeOperator.length) {
192 if (!calculate(operand, pendingMultiplicativeOperator)) {
193 abortOperation();
194 return;
195 }
196 display.setText(Float.toString(factorSoFar, 4));
197 operand = factorSoFar;
198 factorSoFar = 0.0;
199 pendingMultiplicativeOperator = null;
200 }
201
202 if (pendingAdditiveOperator.length) {
203 if (!calculate(operand, pendingAdditiveOperator)) {
204 abortOperation();
205 return;
206 }
207 display.setText(Float.toString(sumSoFar, 4));
208 } else {
209 sumSoFar = operand;
210 }
211
212 pendingAdditiveOperator = clickedOperator;
213 waitingForOperand = true;
214 }
215
216 void multiplicativeOperatorClicked()
217 {
218 Button clickedButton = cast(Button) signalSender();
219 char[] clickedOperator = clickedButton.text();
220 double operand = Float.toFloat(display.text);
221
222 if (pendingMultiplicativeOperator.length) {
223 if (!calculate(operand, pendingMultiplicativeOperator)) {
224 abortOperation();
225 return;
226 }
227 display.setText(Float.toString(factorSoFar, 4));
228 } else {
229 factorSoFar = operand;
230 }
231
232 pendingMultiplicativeOperator = clickedOperator;
233 waitingForOperand = true;
234 }
235
236 void equalClicked()
237 {
238 double operand = Float.toFloat(display.text);
239
240 if (pendingMultiplicativeOperator.length) {
241 if (!calculate(operand, pendingMultiplicativeOperator)) {
242 abortOperation();
243 return;
244 }
245 operand = factorSoFar;
246 factorSoFar = 0.0;
247 pendingMultiplicativeOperator = null;
248 }
249 if (pendingAdditiveOperator.length) {
250 if (!calculate(operand, pendingAdditiveOperator)) {
251 abortOperation();
252 return;
253 }
254 pendingAdditiveOperator = null;
255 } else {
256 sumSoFar = operand;
257 }
258
259 display.setText(Float.toString(sumSoFar, 4));
260 sumSoFar = 0.0;
261 waitingForOperand = true;
262 }
263
264 void pointClicked()
265 {
266 char[] text = display.text;
267
268 if (waitingForOperand)
269 display.setText("0");
270
271 if (find(text, '.') >= text.length)
272 display.setText(text ~ tr("."));
273
274 waitingForOperand = false;
275 }
276
277 void changeSignClicked()
278 {
279 char[] text = display.text();
280 double value = Float.toFloat(text);
281
282 if (value > 0.0) {
283 text = "-" ~ text;
284 } else if (value < 0.0) {
285 text = text[1..$];
286 }
287 display.setText(text);
288 }
289
290 void backspaceClicked()
291 {
292 if (waitingForOperand)
293 return;
294
295 char[] text = display.text();
296 text = text[0..$-1];
297 if (text.length == 0) {
298 text = "0";
299 waitingForOperand = true;
300 }
301 display.setText(text);
302 }
303
304
305 void clear()
306 {
307 if (waitingForOperand)
308 return;
309
310 display.setText("0");
311 waitingForOperand = true;
312 }
313
314 void clearAll()
315 {
316 sumSoFar = 0.0;
317 factorSoFar = 0.0;
318 pendingAdditiveOperator = null;
319 pendingMultiplicativeOperator = null;
320 display.setText("0");
321 waitingForOperand = true;
322 }
323
324 void clearMemory()
325 {
326 sumInMemory = 0.0;
327 }
328
329 void readMemory()
330 {
331 display.setText(Float.toString(sumInMemory, 4));
332 waitingForOperand = true;
333 }
334
335 void setMemory()
336 {
337 equalClicked();
338 sumInMemory = Float.toFloat(display.text);
339 }
340
341 void addToMemory()
342 {
343 equalClicked();
344 sumInMemory += Float.toFloat(display.text);
345 }
346
347 private:
348
349 Button createButton(char[] text, void delegate() member)
350 {
351 Button button = new Button(text);
352 button.clicked.connect(member);
353 return button;
354 }
355
356 void abortOperation()
357 {
358 clearAll();
359 display.setText(tr("####"));
360 }
361
362 bool calculate(double rightOperand, char[] pendingOperator)
363 {
364 if (pendingOperator == tr("+")) {
365 sumSoFar += rightOperand;
366 } else if (pendingOperator == tr("-")) {
367 sumSoFar -= rightOperand;
368 } else if (pendingOperator == tr("*")) {
369 factorSoFar *= rightOperand;
370 } else if (pendingOperator == tr("/")) {
371 if (rightOperand == 0.0)
372 return false;
373 factorSoFar /= rightOperand;
374 }
375 return true;
376 }
377
378 double sumInMemory;
379 double sumSoFar;
380 double factorSoFar;
381 char[] pendingAdditiveOperator;
382 char[] pendingMultiplicativeOperator;
383 bool waitingForOperand;
384
385 QLineEdit display;
386
387 enum { NumDigitButtons = 10 };
388 Button[NumDigitButtons] digitButtons;
389 }