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