Mercurial > projects > qtd
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 } |