Mercurial > projects > qtd
annotate examples/widgets/calculator/calculator.d @ 282:256ab6cb8e85
Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
author | eldar |
---|---|
date | Fri, 16 Oct 2009 02:43:59 +0000 |
parents | 8aaa84d48451 |
children | 7a3c43424dca |
rev | line source |
---|---|
1 | 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 | |
210 | 44 import button; |
1 | 45 import qt.gui.QDialog; |
46 import qt.gui.QGridLayout; | |
47 import qt.gui.QLineEdit; | |
48 import qt.gui.QFont; | |
49 | |
215 | 50 import std.math; |
51 import std.conv; | |
52 import std.string; | |
1 | 53 |
54 class Calculator : public QDialog | |
55 { | |
56 | |
57 public: | |
58 | |
59 this(QWidget parent = null) | |
60 { | |
61 super(parent); | |
62 | |
63 sumInMemory = 0.0; | |
64 sumSoFar = 0.0; | |
65 factorSoFar = 0.0; | |
66 waitingForOperand = true; | |
67 | |
68 display = new QLineEdit("0"); | |
69 display.setReadOnly(true); | |
70 display.setAlignment(Qt.AlignRight); | |
71 display.setMaxLength(15); | |
72 | |
210 | 73 auto font = new QFont(display.font()); |
1 | 74 font.setPointSize(font.pointSize() + 8); |
75 display.setFont(font); | |
76 | |
77 for (int i = 0; i < NumDigitButtons; ++i) { | |
215 | 78 digitButtons[i] = createButton(format("%d", i), &digitClicked); |
1 | 79 } |
80 | |
81 Button pointButton = createButton(tr("."), &pointClicked); | |
82 Button changeSignButton = createButton(tr("+/-"), &changeSignClicked); | |
83 | |
84 Button backspaceButton = createButton(tr("Backspace"), &backspaceClicked); | |
85 Button clearButton = createButton(tr("Clear"), &clear); | |
86 Button clearAllButton = createButton(tr("Clear All"), &clearAll); | |
87 | |
88 Button clearMemoryButton = createButton(tr("MC"), &clearMemory); | |
89 Button readMemoryButton = createButton(tr("MR"), &readMemory); | |
90 Button setMemoryButton = createButton(tr("MS"), &setMemory); | |
91 Button addToMemoryButton = createButton(tr("M+"), &addToMemory); | |
92 | |
93 Button divisionButton = createButton(tr("/"), &multiplicativeOperatorClicked); | |
94 Button timesButton = createButton(tr("*"), &multiplicativeOperatorClicked); | |
95 Button minusButton = createButton(tr("-"), &additiveOperatorClicked); | |
96 Button plusButton = createButton(tr("+"), &additiveOperatorClicked); | |
97 | |
98 Button squareRootButton = createButton(tr("Sqrt"), &unaryOperatorClicked); | |
99 Button powerButton = createButton(tr("x^2"), &unaryOperatorClicked); | |
100 Button reciprocalButton = createButton(tr("1/x"), &unaryOperatorClicked); | |
101 Button equalButton = createButton(tr("="), &equalClicked); | |
102 | |
103 QGridLayout mainLayout = new QGridLayout(); | |
104 | |
105 mainLayout.setSizeConstraint(QLayout.SetFixedSize); | |
106 | |
107 mainLayout.addWidget(display, 0, 0, 1, 6); | |
108 mainLayout.addWidget(backspaceButton, 1, 0, 1, 2); | |
109 mainLayout.addWidget(clearButton, 1, 2, 1, 2); | |
110 mainLayout.addWidget(clearAllButton, 1, 4, 1, 2); | |
111 | |
112 mainLayout.addWidget(clearMemoryButton, 2, 0); | |
113 mainLayout.addWidget(readMemoryButton, 3, 0); | |
114 mainLayout.addWidget(setMemoryButton, 4, 0); | |
115 mainLayout.addWidget(addToMemoryButton, 5, 0); | |
116 | |
117 for (int i = 1; i < NumDigitButtons; ++i) { | |
118 int row = ((9 - i) / 3) + 2; | |
119 int column = ((i - 1) % 3) + 1; | |
120 mainLayout.addWidget(digitButtons[i], row, column); | |
121 } | |
122 | |
123 mainLayout.addWidget(digitButtons[0], 5, 1); | |
124 mainLayout.addWidget(pointButton, 5, 2); | |
125 mainLayout.addWidget(changeSignButton, 5, 3); | |
126 | |
127 mainLayout.addWidget(divisionButton, 2, 4); | |
128 mainLayout.addWidget(timesButton, 3, 4); | |
129 mainLayout.addWidget(minusButton, 4, 4); | |
130 mainLayout.addWidget(plusButton, 5, 4); | |
131 | |
132 mainLayout.addWidget(squareRootButton, 2, 5); | |
133 mainLayout.addWidget(powerButton, 3, 5); | |
134 mainLayout.addWidget(reciprocalButton, 4, 5); | |
135 mainLayout.addWidget(equalButton, 5, 5); | |
136 setLayout(mainLayout); | |
137 | |
138 setWindowTitle(tr("Calculator")); | |
139 } | |
140 | |
141 //private slots: | |
142 void digitClicked() | |
143 { | |
144 Button clickedButton = cast(Button) signalSender(); | |
215 | 145 int digitValue = to!int(clickedButton.text); |
1 | 146 if (display.text() == "0" && digitValue == 0.0) |
147 return; | |
148 | |
149 if (waitingForOperand) { | |
150 display.clear(); | |
151 waitingForOperand = false; | |
152 } | |
215 | 153 display.setText(display.text() ~ format("%g", digitValue)); |
1 | 154 } |
155 | |
156 void unaryOperatorClicked() | |
157 { | |
158 Button clickedButton = cast(Button) signalSender(); | |
210 | 159 string clickedOperator = clickedButton.text(); |
215 | 160 double operand = to!float(display.text); |
1 | 161 double result = 0.0; |
162 | |
163 if (clickedOperator == tr("Sqrt")) { | |
164 if (operand < 0.0) { | |
165 abortOperation(); | |
166 return; | |
167 } | |
168 result = sqrt(operand); | |
169 } else if (clickedOperator == tr("x^2")) { | |
170 result = pow(operand, 2.0); | |
171 } else if (clickedOperator == tr("1/x")) { | |
172 if (operand == 0.0) { | |
173 abortOperation(); | |
174 return; | |
175 } | |
176 result = 1.0 / operand; | |
177 } | |
215 | 178 display.setText(format("%g", result)); |
1 | 179 waitingForOperand = true; |
180 } | |
181 | |
182 void additiveOperatorClicked() | |
183 { | |
184 Button clickedButton = cast(Button) signalSender(); | |
210 | 185 string clickedOperator = clickedButton.text(); |
215 | 186 double operand = to!float(display.text); |
1 | 187 |
188 if (pendingMultiplicativeOperator.length) { | |
189 if (!calculate(operand, pendingMultiplicativeOperator)) { | |
190 abortOperation(); | |
191 return; | |
192 } | |
215 | 193 display.setText(format("%g", factorSoFar)); |
1 | 194 operand = factorSoFar; |
195 factorSoFar = 0.0; | |
196 pendingMultiplicativeOperator = null; | |
197 } | |
198 | |
199 if (pendingAdditiveOperator.length) { | |
200 if (!calculate(operand, pendingAdditiveOperator)) { | |
201 abortOperation(); | |
202 return; | |
203 } | |
215 | 204 display.setText(format("%g", sumSoFar)); |
1 | 205 } else { |
206 sumSoFar = operand; | |
207 } | |
208 | |
209 pendingAdditiveOperator = clickedOperator; | |
210 waitingForOperand = true; | |
211 } | |
212 | |
213 void multiplicativeOperatorClicked() | |
214 { | |
215 Button clickedButton = cast(Button) signalSender(); | |
210 | 216 string clickedOperator = clickedButton.text(); |
215 | 217 double operand = to!float(display.text); |
1 | 218 |
219 if (pendingMultiplicativeOperator.length) { | |
220 if (!calculate(operand, pendingMultiplicativeOperator)) { | |
221 abortOperation(); | |
222 return; | |
223 } | |
215 | 224 display.setText(format("%g", factorSoFar)); |
1 | 225 } else { |
226 factorSoFar = operand; | |
227 } | |
228 | |
229 pendingMultiplicativeOperator = clickedOperator; | |
230 waitingForOperand = true; | |
231 } | |
232 | |
233 void equalClicked() | |
234 { | |
215 | 235 double operand = to!float(display.text); |
1 | 236 |
237 if (pendingMultiplicativeOperator.length) { | |
238 if (!calculate(operand, pendingMultiplicativeOperator)) { | |
239 abortOperation(); | |
240 return; | |
241 } | |
242 operand = factorSoFar; | |
243 factorSoFar = 0.0; | |
244 pendingMultiplicativeOperator = null; | |
245 } | |
246 if (pendingAdditiveOperator.length) { | |
247 if (!calculate(operand, pendingAdditiveOperator)) { | |
248 abortOperation(); | |
249 return; | |
250 } | |
251 pendingAdditiveOperator = null; | |
252 } else { | |
253 sumSoFar = operand; | |
254 } | |
255 | |
215 | 256 display.setText(format("%g", sumSoFar)); |
1 | 257 sumSoFar = 0.0; |
258 waitingForOperand = true; | |
259 } | |
260 | |
261 void pointClicked() | |
262 { | |
210 | 263 string text = display.text; |
1 | 264 |
265 if (waitingForOperand) | |
266 display.setText("0"); | |
267 | |
215 | 268 if (indexOf(text, '.') >= text.length) |
1 | 269 display.setText(text ~ tr(".")); |
270 | |
271 waitingForOperand = false; | |
272 } | |
273 | |
274 void changeSignClicked() | |
275 { | |
210 | 276 string text = display.text(); |
215 | 277 double value = to!float(text); |
1 | 278 |
279 if (value > 0.0) { | |
280 text = "-" ~ text; | |
281 } else if (value < 0.0) { | |
282 text = text[1..$]; | |
283 } | |
284 display.setText(text); | |
285 } | |
286 | |
287 void backspaceClicked() | |
288 { | |
289 if (waitingForOperand) | |
290 return; | |
291 | |
210 | 292 string text = display.text(); |
1 | 293 text = text[0..$-1]; |
294 if (text.length == 0) { | |
295 text = "0"; | |
296 waitingForOperand = true; | |
297 } | |
298 display.setText(text); | |
299 } | |
300 | |
301 | |
302 void clear() | |
303 { | |
304 if (waitingForOperand) | |
305 return; | |
306 | |
307 display.setText("0"); | |
308 waitingForOperand = true; | |
309 } | |
310 | |
311 void clearAll() | |
312 { | |
313 sumSoFar = 0.0; | |
314 factorSoFar = 0.0; | |
315 pendingAdditiveOperator = null; | |
316 pendingMultiplicativeOperator = null; | |
317 display.setText("0"); | |
318 waitingForOperand = true; | |
319 } | |
320 | |
321 void clearMemory() | |
322 { | |
323 sumInMemory = 0.0; | |
324 } | |
325 | |
326 void readMemory() | |
327 { | |
215 | 328 display.setText(format("%g", sumInMemory)); |
1 | 329 waitingForOperand = true; |
330 } | |
331 | |
332 void setMemory() | |
333 { | |
334 equalClicked(); | |
215 | 335 sumInMemory = to!float(display.text); |
1 | 336 } |
337 | |
338 void addToMemory() | |
339 { | |
340 equalClicked(); | |
215 | 341 sumInMemory += to!float(display.text); |
1 | 342 } |
343 | |
344 private: | |
345 | |
210 | 346 Button createButton(string text, void delegate() member) |
1 | 347 { |
348 Button button = new Button(text); | |
282
256ab6cb8e85
Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
eldar
parents:
215
diff
changeset
|
349 connect!("clicked")(button, member); |
1 | 350 return button; |
351 } | |
352 | |
353 void abortOperation() | |
354 { | |
355 clearAll(); | |
356 display.setText(tr("####")); | |
357 } | |
358 | |
210 | 359 bool calculate(double rightOperand, string pendingOperator) |
1 | 360 { |
361 if (pendingOperator == tr("+")) { | |
362 sumSoFar += rightOperand; | |
363 } else if (pendingOperator == tr("-")) { | |
364 sumSoFar -= rightOperand; | |
365 } else if (pendingOperator == tr("*")) { | |
366 factorSoFar *= rightOperand; | |
367 } else if (pendingOperator == tr("/")) { | |
368 if (rightOperand == 0.0) | |
369 return false; | |
370 factorSoFar /= rightOperand; | |
371 } | |
372 return true; | |
373 } | |
374 | |
375 double sumInMemory; | |
376 double sumSoFar; | |
377 double factorSoFar; | |
210 | 378 string pendingAdditiveOperator; |
379 string pendingMultiplicativeOperator; | |
1 | 380 bool waitingForOperand; |
381 | |
382 QLineEdit display; | |
383 | |
384 enum { NumDigitButtons = 10 }; | |
385 Button[NumDigitButtons] digitButtons; | |
386 } |