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

initial import
author mandel
date Mon, 11 May 2009 16:01:50 +0000
parents
children 3ea0efe4d31e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/widgets/calculator/calculator.d	Mon May 11 16:01:50 2009 +0000
@@ -0,0 +1,389 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+module calculator;
+
+import qt.gui.QDialog;
+import qt.gui.QGridLayout;
+import qt.gui.QLineEdit;
+import qt.gui.QFont;
+
+import tango.math.Math : pow, sqrt;
+import Float = tango.text.convert.Float;
+import Integer = tango.text.convert.Integer;
+import tango.core.Array;
+
+import button;
+
+
+class Calculator : public QDialog
+{
+        
+public:
+        
+        this(QWidget parent = null)
+        {
+                super(parent);
+
+                sumInMemory = 0.0;
+                sumSoFar = 0.0;
+                factorSoFar = 0.0;
+                waitingForOperand = true;
+
+                display = new QLineEdit("0");
+                display.setReadOnly(true);
+                display.setAlignment(Qt.AlignRight);
+                display.setMaxLength(15);
+
+                QFont font = display.font();
+                font.setPointSize(font.pointSize() + 8);
+                display.setFont(font);
+
+                for (int i = 0; i < NumDigitButtons; ++i) {
+                        digitButtons[i] = createButton(Integer.toString(i), &digitClicked);
+                }
+
+                Button pointButton = createButton(tr("."), &pointClicked);
+                Button changeSignButton = createButton(tr("+/-"), &changeSignClicked);
+
+                Button backspaceButton = createButton(tr("Backspace"), &backspaceClicked);
+                Button clearButton = createButton(tr("Clear"), &clear);
+                Button clearAllButton = createButton(tr("Clear All"), &clearAll);
+
+                Button clearMemoryButton = createButton(tr("MC"), &clearMemory);
+                Button readMemoryButton = createButton(tr("MR"), &readMemory);
+                Button setMemoryButton = createButton(tr("MS"), &setMemory);
+                Button addToMemoryButton = createButton(tr("M+"), &addToMemory);
+
+                Button divisionButton = createButton(tr("/"), &multiplicativeOperatorClicked);
+                Button timesButton = createButton(tr("*"), &multiplicativeOperatorClicked);
+                Button minusButton = createButton(tr("-"), &additiveOperatorClicked);
+                Button plusButton = createButton(tr("+"), &additiveOperatorClicked);
+
+                Button squareRootButton = createButton(tr("Sqrt"), &unaryOperatorClicked);
+                Button powerButton = createButton(tr("x^2"), &unaryOperatorClicked);
+                Button reciprocalButton = createButton(tr("1/x"), &unaryOperatorClicked);
+                Button equalButton = createButton(tr("="), &equalClicked);
+
+                QGridLayout mainLayout = new QGridLayout();
+
+                mainLayout.setSizeConstraint(QLayout.SetFixedSize);
+
+                mainLayout.addWidget(display, 0, 0, 1, 6);
+                mainLayout.addWidget(backspaceButton, 1, 0, 1, 2);
+                mainLayout.addWidget(clearButton, 1, 2, 1, 2);
+                mainLayout.addWidget(clearAllButton, 1, 4, 1, 2);
+
+                mainLayout.addWidget(clearMemoryButton, 2, 0);
+                mainLayout.addWidget(readMemoryButton, 3, 0);
+                mainLayout.addWidget(setMemoryButton, 4, 0);
+                mainLayout.addWidget(addToMemoryButton, 5, 0);
+
+                for (int i = 1; i < NumDigitButtons; ++i) {
+                        int row = ((9 - i) / 3) + 2;
+                        int column = ((i - 1) % 3) + 1;
+                        mainLayout.addWidget(digitButtons[i], row, column);
+                }
+
+                mainLayout.addWidget(digitButtons[0], 5, 1);
+                mainLayout.addWidget(pointButton, 5, 2);
+                mainLayout.addWidget(changeSignButton, 5, 3);
+
+                mainLayout.addWidget(divisionButton, 2, 4);
+                mainLayout.addWidget(timesButton, 3, 4);
+                mainLayout.addWidget(minusButton, 4, 4);
+                mainLayout.addWidget(plusButton, 5, 4);
+
+                mainLayout.addWidget(squareRootButton, 2, 5);
+                mainLayout.addWidget(powerButton, 3, 5);
+                mainLayout.addWidget(reciprocalButton, 4, 5);
+                mainLayout.addWidget(equalButton, 5, 5);
+                setLayout(mainLayout);
+
+                setWindowTitle(tr("Calculator"));
+        }
+
+//private slots:
+        void digitClicked()
+        {
+                Button clickedButton = cast(Button) signalSender();
+                int digitValue = Integer.toInt(clickedButton.text);
+                if (display.text() == "0" && digitValue == 0.0)
+                        return;
+
+                if (waitingForOperand) {
+                        display.clear();
+                        waitingForOperand = false;
+                }
+                display.setText(display.text() ~ Integer.toString(digitValue));
+        }
+
+        void unaryOperatorClicked()
+        {
+                Button clickedButton = cast(Button) signalSender();
+                char[] clickedOperator = clickedButton.text();
+                double operand = Float.toFloat(display.text);
+                double result = 0.0;
+
+                if (clickedOperator == tr("Sqrt")) {
+                        if (operand < 0.0) {
+                                abortOperation();
+                                return;
+                        }
+                        result = sqrt(operand);
+                } else if (clickedOperator == tr("x^2")) {
+                        result = pow(operand, 2.0);
+                } else if (clickedOperator == tr("1/x")) {
+                        if (operand == 0.0) {
+                                abortOperation();
+                                return;
+                        }
+                        result = 1.0 / operand;
+                }
+                display.setText(Float.toString(result, 4));
+                waitingForOperand = true;
+        }
+
+        void additiveOperatorClicked()
+        {
+                Button clickedButton = cast(Button) signalSender();
+                char[] clickedOperator = clickedButton.text();
+                double operand = Float.toFloat(display.text);
+
+                if (pendingMultiplicativeOperator.length) {
+                        if (!calculate(operand, pendingMultiplicativeOperator)) {
+                                abortOperation();
+                                return;
+                        }
+                        display.setText(Float.toString(factorSoFar, 4));
+                        operand = factorSoFar;
+                        factorSoFar = 0.0;
+                        pendingMultiplicativeOperator = null;
+                }
+
+                if (pendingAdditiveOperator.length) {
+                        if (!calculate(operand, pendingAdditiveOperator)) {
+                                abortOperation();
+                                return;
+                        }
+                        display.setText(Float.toString(sumSoFar, 4));
+                } else {
+                        sumSoFar = operand;
+                }
+
+                pendingAdditiveOperator = clickedOperator;
+                waitingForOperand = true;
+        }
+
+        void multiplicativeOperatorClicked()
+        {
+                Button clickedButton = cast(Button) signalSender();
+                char[] clickedOperator = clickedButton.text();
+                double operand = Float.toFloat(display.text);
+
+                if (pendingMultiplicativeOperator.length) {
+                        if (!calculate(operand, pendingMultiplicativeOperator)) {
+                                abortOperation();
+                                return;
+                        }
+                        display.setText(Float.toString(factorSoFar, 4));
+                } else {
+                        factorSoFar = operand;
+                }
+
+                pendingMultiplicativeOperator = clickedOperator;
+                waitingForOperand = true;
+        }
+
+        void equalClicked()
+        {
+                double operand = Float.toFloat(display.text);
+
+                if (pendingMultiplicativeOperator.length) {
+                        if (!calculate(operand, pendingMultiplicativeOperator)) {
+                                abortOperation();
+                                return;
+                        }
+                        operand = factorSoFar;
+                        factorSoFar = 0.0;
+                        pendingMultiplicativeOperator = null;
+                }
+                if (pendingAdditiveOperator.length) {
+                        if (!calculate(operand, pendingAdditiveOperator)) {
+                                abortOperation();
+                                return;
+                        }
+                        pendingAdditiveOperator = null;
+                } else {
+                        sumSoFar = operand;
+                }
+
+                display.setText(Float.toString(sumSoFar, 4));
+                sumSoFar = 0.0;
+                waitingForOperand = true;
+        }
+
+        void pointClicked()
+        {
+                char[] text = display.text;
+
+                if (waitingForOperand)
+                        display.setText("0");
+
+                if (find(text, '.') >= text.length)
+                        display.setText(text ~ tr("."));
+                
+                waitingForOperand = false;
+        }
+
+        void changeSignClicked()
+        {
+                char[] text = display.text();
+                double value = Float.toFloat(text);
+
+                if (value > 0.0) {
+                        text = "-" ~ text;
+                } else if (value < 0.0) {
+                        text = text[1..$];
+                }
+                display.setText(text);
+        }
+
+        void backspaceClicked()
+        {
+                if (waitingForOperand)
+                        return;
+
+                char[] text = display.text();
+                text = text[0..$-1];
+                if (text.length == 0) {
+                        text = "0";
+                        waitingForOperand = true;
+                }
+                display.setText(text);
+        }
+
+
+        void clear()
+        {
+                if (waitingForOperand)
+                        return;
+
+                display.setText("0");
+                waitingForOperand = true;
+        }
+
+        void clearAll()
+        {
+                sumSoFar = 0.0;
+                factorSoFar = 0.0;
+                pendingAdditiveOperator = null;
+                pendingMultiplicativeOperator = null;
+                display.setText("0");
+                waitingForOperand = true;
+        }
+
+        void clearMemory()
+        {
+                sumInMemory = 0.0;
+        }
+
+        void readMemory()
+        {
+                display.setText(Float.toString(sumInMemory, 4));
+                waitingForOperand = true;
+        }
+
+        void setMemory()
+        {
+                equalClicked();
+                sumInMemory = Float.toFloat(display.text);
+        }
+
+        void addToMemory()
+        {
+                equalClicked();
+                sumInMemory += Float.toFloat(display.text);
+        }
+
+private:
+
+        Button createButton(char[] text, void delegate() member)
+        {
+                Button button = new Button(text);
+                button.clicked.connect(member);
+                return button;
+        }
+
+        void abortOperation()
+        {
+                clearAll();
+                display.setText(tr("####"));
+        }
+
+        bool calculate(double rightOperand, char[] pendingOperator)
+        {
+                if (pendingOperator == tr("+")) {
+                        sumSoFar += rightOperand;
+                } else if (pendingOperator == tr("-")) {
+                        sumSoFar -= rightOperand;
+                } else if (pendingOperator == tr("*")) {
+                        factorSoFar *= rightOperand;
+                } else if (pendingOperator == tr("/")) {
+                        if (rightOperand == 0.0)
+                                return false;
+                        factorSoFar /= rightOperand;
+                }
+                return true;
+        }
+
+        double sumInMemory;
+        double sumSoFar;
+        double factorSoFar;
+        char[] pendingAdditiveOperator;
+        char[] pendingMultiplicativeOperator;
+        bool waitingForOperand;
+
+        QLineEdit display;
+
+        enum { NumDigitButtons = 10 };
+        Button[NumDigitButtons] digitButtons;
+}