summaryrefslogtreecommitdiffstats
path: root/sigmodr/corewidgets/FractionWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sigmodr/corewidgets/FractionWidget.cpp')
-rw-r--r--sigmodr/corewidgets/FractionWidget.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/sigmodr/corewidgets/FractionWidget.cpp b/sigmodr/corewidgets/FractionWidget.cpp
new file mode 100644
index 00000000..36a9a9ea
--- /dev/null
+++ b/sigmodr/corewidgets/FractionWidget.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2008-2009 Ben Boeckel <MathStuf@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Header include
+#include "FractionWidget.h"
+#include "FractionWidget_p.h"
+
+// KDE includes
+#include <KIntNumInput>
+#include <KLineEdit>
+
+// Qt includes
+#include <QtCore/QFile>
+#include <QtGui/QVBoxLayout>
+#include <QtUiTools/QUiLoader>
+
+// C includes
+#include <climits>
+
+using namespace Sigcore;
+using namespace Sigmodr::CoreWidgets;
+
+FractionWidget::Private::Private(QObject* parent, const Fraction& value) :
+ QObject(parent),
+ m_value(value),
+ m_behavior(Any)
+{
+}
+
+QWidget* FractionWidget::Private::makeWidgets(FractionWidget* widget)
+{
+ QFile file(":/gui/fraction.ui");
+ file.open(QFile::ReadOnly);
+ QWidget *formWidget = QUiLoader().load(&file, widget);
+ file.close();
+ ui_numerator = formWidget->findChild<KIntNumInput*>("varNumerator");
+ ui_denominator = formWidget->findChild<KIntNumInput*>("varDenominator");
+ ui_value = formWidget->findChild<KLineEdit*>("varValue");
+ connect(ui_numerator, SIGNAL(valueChanged(int)), this, SLOT(numeratorChanged(int)));
+ connect(ui_denominator, SIGNAL(valueChanged(int)), this, SLOT(denominatorChanged(int)));
+ connect(this, SIGNAL(valueChanged(Sigcore::Fraction)), widget, SIGNAL(valueChanged(Sigcore::Fraction)));
+ connect(this, SIGNAL(valueChanged(Sigcore::Fraction)), this, SLOT(updateValue()));
+ connect(this, SIGNAL(valueChanged(Sigcore::Fraction)), this, SLOT(resetRanges()));
+ connect(widget, SIGNAL(behaviorChanged(Behavior)), this, SLOT(resetRanges()));
+ updateValue();
+ return formWidget;
+}
+
+void FractionWidget::Private::numeratorChanged(const int numerator)
+{
+ m_value.setNumerator(numerator);
+ emit(valueChanged(m_value));
+}
+
+void FractionWidget::Private::denominatorChanged(const int denominator)
+{
+ m_value.setDenominator(denominator);
+ emit(valueChanged(m_value));
+}
+
+void FractionWidget::Private::updateValue()
+{
+ ui_value->setText(QString::number(double(m_value), 'g', 7));
+}
+
+void FractionWidget::Private::resetRanges()
+{
+ ui_numerator->setValue(m_value.numerator());
+ ui_denominator->setValue(m_value.denominator());
+ int numMin = 0;
+ int numMax = INT_MAX;
+ int denomMin = 1;
+ int denomMax = INT_MAX;
+ switch (m_behavior)
+ {
+ case NonZero:
+ numMin = 1;
+ case Proper:
+ numMax = m_value.denominator();
+ break;
+ case Improper:
+ denomMax = m_value.numerator();
+ case AnyButZero:
+ numMin = 1;
+ default:
+ break;
+ }
+ ui_numerator->setRange(numMin, numMax);
+ ui_denominator->setRange(denomMin, denomMax);
+}
+
+FractionWidget::FractionWidget(QWidget* parent, const Fraction& value) :
+ QWidget(parent),
+ d(new Private(this, value))
+{
+ QVBoxLayout* layout = new QVBoxLayout;
+ layout->addWidget(d->makeWidgets(this));
+ setLayout(layout);
+}
+
+FractionWidget::Behavior FractionWidget::behavior() const
+{
+ return d->m_behavior;
+}
+
+Fraction FractionWidget::value() const
+{
+ return d->m_value;
+}
+
+void FractionWidget::setBehavior(const Behavior behavior)
+{
+ d->m_behavior = behavior;
+ emit(behaviorChanged(d->m_behavior));
+}
+
+void FractionWidget::setValue(const Fraction& value)
+{
+ if (d->m_value == value)
+ return;
+ d->m_value = value;
+ emit(valueChanged(d->m_value));
+}