Home · All Classes · Main Classes · Deprecated |
This demonstrates a simple calculator widget that can work in both portrait and landscape mode.
It uses CSS and SVG to style the calculator, and separate portrait and landscape policies to dynamically change the layouting of the buttons.
The calculator is not fully functional - completing the task is left as an exercise to the reader.
Header file for calculator widget:
/*************************************************************************** ** ** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (directui@nokia.com) ** ** This file is part of libmeegotouch. ** ** If you have questions regarding the use of this file, please contact ** Nokia at directui@nokia.com. ** ** This library is free software; you can redistribute it and/or ** modify it 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. ** ****************************************************************************/ #ifndef CALCULATORWIDGET_H #define CALCULATORWIDGET_H #include <MWidgetController> #include <QList> class MButton; class MLabel; class MGridLayoutPolicy; class CalculatorWidget : public MWidget { public: CalculatorWidget(); void setValue(qreal value); qreal value() const; void setText(const QString &text); QString text() const; private: MLabel *mLabel; MLabel *mCalculationLine; qreal mValue; }; #endif
The calculator widget:
/*************************************************************************** ** ** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (directui@nokia.com) ** ** This file is part of libmeegotouch. ** ** If you have questions regarding the use of this file, please contact ** Nokia at directui@nokia.com. ** ** This library is free software; you can redistribute it and/or ** modify it 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. ** ****************************************************************************/ #include "calculatorwidget.h" #include <MLabel> #include <MButton> #include <MLayout> #include <MGridLayoutPolicy> #include <MSceneManager> #include "calculatorbutton.h" CalculatorWidget::CalculatorWidget() { mValue = 0; //Prevent the layout from changing in right-to-left. //The calculation line will still be reversed however. setLayoutDirection(Qt::LeftToRight); /* Create a MLayout attached to this widget */ MLayout *layout = new MLayout(this); MGridLayoutPolicy *landscapePolicy = new MGridLayoutPolicy(layout); MGridLayoutPolicy *portraitPolicy = new MGridLayoutPolicy(layout); layout->setPortraitPolicy(portraitPolicy); layout->setLandscapePolicy(landscapePolicy); landscapePolicy->setObjectName("calculatorLandscape"); portraitPolicy->setObjectName("calculatorPortrait"); mCalculationLine = new MLabel; mCalculationLine->setObjectName("calculationLine"); mCalculationLine->setAlignment(Qt::AlignRight); QList<CalculatorButton *> buttons; CalculatorButton *button; for (int i = 0; i < 10; i++) { button = new CalculatorButton(CalculatorButton::Button((int)CalculatorButton::Num0 + i), this); if (i == 0) { landscapePolicy->addItem(button, 3, 4); portraitPolicy->addItem(button, 6, 0); } else { landscapePolicy->addItem(button, 2 - (i - 1) / 3, 4 + (i - 1) % 3); portraitPolicy->addItem(button, 5 - (i - 1) / 3, (i - 1) % 3); } } CalculatorButton *buttonC = new CalculatorButton(CalculatorButton::Clear, this); CalculatorButton *buttonBackspace = new CalculatorButton(CalculatorButton::Backspace, this); CalculatorButton *buttonSign = new CalculatorButton(CalculatorButton::Sign, this); CalculatorButton *buttonDecimal = new CalculatorButton(CalculatorButton::Decimal, this); CalculatorButton *buttonReciprocal = new CalculatorButton(CalculatorButton::Reciprocal, this); CalculatorButton *buttonPower = new CalculatorButton(CalculatorButton::Power, this); CalculatorButton *buttonSqrt = new CalculatorButton(CalculatorButton::Sqrt, this); CalculatorButton *buttonPercentage = new CalculatorButton(CalculatorButton::Percentage, this); CalculatorButton *buttonDivide = new CalculatorButton(CalculatorButton::Divide, this); CalculatorButton *buttonMultiply = new CalculatorButton(CalculatorButton::Multiply, this); CalculatorButton *buttonSubtract = new CalculatorButton(CalculatorButton::Subtract, this); CalculatorButton *buttonAdd = new CalculatorButton(CalculatorButton::Add, this); CalculatorButton *buttonEquals = new CalculatorButton(CalculatorButton::Equals, this); buttonEquals->setObjectName("calculatorButtonEquals"); landscapePolicy->addItem(mCalculationLine, 0, 0, 1, 4); landscapePolicy->addItem(buttonC, 1, 0); landscapePolicy->addItem(buttonBackspace, 1, 1); landscapePolicy->addItem(buttonSign, 1, 2); landscapePolicy->addItem(buttonDecimal, 1, 3); landscapePolicy->addItem(buttonReciprocal, 2, 0); landscapePolicy->addItem(buttonPower, 2, 1); landscapePolicy->addItem(buttonSqrt, 2, 2); landscapePolicy->addItem(buttonPercentage, 2, 3); landscapePolicy->addItem(buttonDivide, 3, 0); landscapePolicy->addItem(buttonMultiply, 3, 1); landscapePolicy->addItem(buttonSubtract, 3, 2); landscapePolicy->addItem(buttonAdd, 3, 3); landscapePolicy->addItem(buttonEquals, 3, 5, 1, 2); portraitPolicy->addItem(mCalculationLine, 0, 0, 1, 4); portraitPolicy->addItem(buttonC, 1, 0); portraitPolicy->addItem(buttonBackspace, 1, 1); portraitPolicy->addItem(buttonReciprocal, 1, 2); portraitPolicy->addItem(buttonDivide, 1, 3); portraitPolicy->addItem(buttonPower, 2, 0); portraitPolicy->addItem(buttonSqrt, 2, 1); portraitPolicy->addItem(buttonPercentage, 2, 2); portraitPolicy->addItem(buttonMultiply, 2, 3); portraitPolicy->addItem(buttonSubtract, 3, 3); portraitPolicy->addItem(buttonAdd, 4, 3); portraitPolicy->addItem(buttonEquals, 5, 3, 2, 1); portraitPolicy->addItem(buttonDecimal, 6, 1); portraitPolicy->addItem(buttonSign, 6, 2); setValue(mValue); } void CalculatorWidget::setValue(qreal value) { mValue = value; mCalculationLine->setText(QString::number(mValue)); } qreal CalculatorWidget::value() const { return mValue; } void CalculatorWidget::setText(const QString &text) { mValue = text.toDouble(); mCalculationLine->setText(text); } QString CalculatorWidget::text() const { return mCalculationLine->text(); }
The calculator widget is added to an application page:
/*************************************************************************** ** ** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (directui@nokia.com) ** ** This file is part of libmeegotouch. ** ** If you have questions regarding the use of this file, please contact ** Nokia at directui@nokia.com. ** ** This library is free software; you can redistribute it and/or ** modify it 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. ** ****************************************************************************/ /* * This demonstrates a simple calculator widget that can work in both portrait and landscape mode. */ #include <MApplication> #include <MApplicationPage> #include <MApplicationWindow> #include <MTheme> #include "calculatorwidget.h" int main(int argc, char **argv) { MApplication app(argc, argv); MTheme::loadCSS("calculator.css"); //Load the example svg file in the same directory MTheme::addPixmapDirectory(".", M::NonRecursive); MApplicationWindow window; MApplicationPage page; CalculatorWidget *calculatorWidget = new CalculatorWidget; page.setCentralWidget(calculatorWidget); page.appear(&window); window.show(); return app.exec(); }
The logic for the calculator buttons is in calculatorbutton.cpp:
/*************************************************************************** ** ** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (directui@nokia.com) ** ** This file is part of libmeegotouch. ** ** If you have questions regarding the use of this file, please contact ** Nokia at directui@nokia.com. ** ** This library is free software; you can redistribute it and/or ** modify it 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. ** ****************************************************************************/ #include "calculatorbutton.h" #include <math.h> //for sqrt #include <QString> #include "calculatorwidget.h" CalculatorButton::CalculatorButton(Button _button, CalculatorWidget *_calculatorWidget) : MButton(), button(_button), calculatorWidget(_calculatorWidget) { setObjectName("calculatorButton"); connect(this, SIGNAL(clicked(bool)), SLOT(execute())); retranslate(); } void CalculatorButton::retranslate() { if (button >= Num0 && button <= Num9) { setText(QString::number(button)); return; } switch (button) { case Clear: setText("C"); return; case Backspace: setText("Del"); return; case Sign: setText(QChar(0x00B1)); return; case Decimal: setText("."); return; case Reciprocal: setText("1/x"); return; case Power: setText("x^y"); return; case Sqrt: setText(QChar(0x221a)); return; case Percentage: setText("%"); return; case Divide: setText(QChar(0x00F7)); return; case Multiply: setText(QChar(0x00D7)); return; case Subtract: setText("-"); return; case Add: setText("+"); return; case Equals: setText("="); return; default: return; } } void CalculatorButton::execute() { if (button >= Num0 && button <= Num9) { if (calculatorWidget->text() == "0") calculatorWidget->setValue(button); else calculatorWidget->setText(calculatorWidget->text() + QString::number(button)); return; } switch (button) { case Clear: calculatorWidget->setValue(0); return; case Backspace: { QString text = calculatorWidget->text(); text.chop(1); calculatorWidget->setText(text); return; } case Sign: // TODO improve calculatorWidget->setValue(-calculatorWidget->value()); return; case Decimal: //TODO check we don't already have a . calculatorWidget->setText(calculatorWidget->text() + '.'); return; case Reciprocal: //TODO error check calculatorWidget->setValue(1 / calculatorWidget->value()); return; case Power: //TODO implement return; case Sqrt: calculatorWidget->setValue(sqrt(calculatorWidget->value())); return; case Percentage: // TODO improve calculatorWidget->setValue(calculatorWidget->value() / 100); return; case Divide: // TODO implement return; case Multiply: // TODO implement return; case Subtract: // TODO implement return; case Add: // TODO implement return; case Equals: // TODO implement return; default: return; } }
Header file for calculator button:
/*************************************************************************** ** ** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (directui@nokia.com) ** ** This file is part of libmeegotouch. ** ** If you have questions regarding the use of this file, please contact ** Nokia at directui@nokia.com. ** ** This library is free software; you can redistribute it and/or ** modify it 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. ** ****************************************************************************/ #ifndef CALCULATORBUTTON_H #define CALCULATORBUTTON_H #include <MButton> class CalculatorWidget; class CalculatorButton : public MButton { Q_OBJECT public: enum Button { Num0 = 0, Num9 = 9, Clear, Backspace, Sign, Decimal, Reciprocal, Power, Sqrt, Percentage, Divide, Multiply, Subtract, Add, Equals }; CalculatorButton(Button _button, CalculatorWidget *_calculatorWidget); void retranslate(); public slots: void execute(); private: const Button button; CalculatorWidget *const calculatorWidget; }; #endif
Styled with the following calculator.css file:
#calculationLine { font: "Nokia Sans Wide" 30px; background-color: #444444; preferred-size: 200 50; } DuiAbstractLayoutPolicyStyle#calculatorLandscape { margin-left: 12.0; margin-right: 12.0; margin-top: 12.0; margin-bottom: 12.0; vertical-spacing: 4.0; horizontal-spacing: 4.0; } DuiAbstractLayoutPolicyStyle#calculatorPortrait { margin-left: 12.0; margin-right: 24.0; margin-top: 12.0; margin-bottom: 12.0; vertical-spacing: 12.0; horizontal-spacing: 12.0; } #calculatorButton { normal-background-image: calc-button 0 0 0 0; pressed-background-image: calc-button-pressed 0 0 0 0; normal-text-color: #FFFFFF; font: "Nokia Sans Wide" 21px; preferred-size: 200 50; } #calculatorButtonEquals { normal-background-image: equals-button 0 0 0 0; pressed-background-image: equals-button-pressed 0 0 0 0; normal-text-color: #000000; font: "Nokia Sans Wide" 30px; }
And compiled with the following calculator.pro file:
include( ../common.pri )
TEMPLATE = app
# Input
SOURCES += calculator.cpp calculatorbutton.cpp calculatorwidget.cpp
HEADERS += *.h
Copyright © 2010 Nokia Corporation | MeeGo Touch |