diff --git a/src/widgets/axiscontrol.h b/src/widgets/axiscontrol.h --- a/src/widgets/axiscontrol.h +++ b/src/widgets/axiscontrol.h @@ -1,7 +1,8 @@ -/* Atelier KDE Printer Host for 3D Printing - Copyright (C) <2016> - Author: Lays Rodrigues - lays.rodrigues@kde.org - Chris Rizzitello - rizzitello@kde.org +/* AtCore Test Client + Copyright (C) <2016 - 2018> + + Authors: + Chris Rizzitello 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 @@ -17,75 +18,63 @@ along with this program. If not, see . */ #pragma once - -#include -#include -#include +#include +#include +#include +#include #include "atcorewidgets_export.h" -class ATCOREWIDGETS_EXPORT PieButton : public QObject, public QGraphicsEllipseItem -{ - Q_OBJECT -public: - PieButton(QLatin1Char &axis, int value, int size, int angle); - void setPalette(QPalette palette); -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *); - void hoverEnterEvent(QGraphicsSceneHoverEvent *); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *); -signals: - void clicked(QLatin1Char axis, int value); -private: - QLatin1Char _axis; - int _value; - QPalette _palette; -}; - -class ATCOREWIDGETS_EXPORT RectButton : public QObject, public QGraphicsRectItem -{ - Q_OBJECT - -public: - RectButton(QLatin1Char &axis, int value, int size); - void setPalette(QPalette palette); -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *); - void hoverEnterEvent(QGraphicsSceneHoverEvent *); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *); -signals: - void clicked(QLatin1Char axis, int value); -private: - QLatin1Char _axis; - int _value; - QPalette _palette; -}; - /** * @brief AxisControl is a Widget to generate axis relative movements. * * Usage: * Create a instance of AxisControl and connect the clicked signal, it will give you the axis and value that was clicked. */ -class ATCOREWIDGETS_EXPORT AxisControl : public QGraphicsView +class ATCOREWIDGETS_EXPORT AxisControl : public QWidget { Q_OBJECT public: - explicit AxisControl(const QList &movementValues = {1, 10, 25}, QWidget *parent = nullptr); - -private: - void setLabels(QGraphicsItem *item, QLatin1Char &axis, int value); - -protected: - void resizeEvent(QResizeEvent *); + /** + * @brief Create a new AxisControl + * @param parent + */ + AxisControl(QWidget *parent = nullptr); + ~AxisControl() = default; signals: /** * @brief User has clicked to move an axis. * @param axis: Axis to move * @param value: Amount to move */ - void clicked(QLatin1Char axis, int value); + void clicked(const QLatin1Char axis, double value); + /** + * @brief User has changed the units. + * @param selection: Selection of Metric (0) or Imperial(1) + */ + void unitsChanged(int selection); + +private: + /** + * @brief Create A push button connected to the emit event + * @param axis: Single letter of the axis (X,Y,Z,E) + * @param multiplier: Used to set the move direction set to 1 or -1 + * @param iconSize: size to set the icon + * @param themeIcon: icon to use "fromTheme" + * @param fallbackText: Fallback text if theme fails + * @return The Created PushButton + */ + QPushButton *makeButton(const QLatin1Char axis, int multiplier, const QSize &iconSize, const QString &themeIcon, const QString &fallbackText); + + /** + * @brief makeSimpleAxis + * @param axis: Axis + * @param iconSize: Size of the icon + * @return Simple Axis Widget + */ + QWidget *makeSimpleAxis(const QLatin1Char axis, const QSize &iconSize); + QDoubleSpinBox *sbValue = nullptr; }; diff --git a/src/widgets/axiscontrol.cpp b/src/widgets/axiscontrol.cpp --- a/src/widgets/axiscontrol.cpp +++ b/src/widgets/axiscontrol.cpp @@ -1,7 +1,8 @@ -/* Atelier KDE Printer Host for 3D Printing - Copyright (C) <2016> - Author: Lays Rodrigues - lays.rodrigues@kde.org - Chris Rizzitello - rizzitello@kde.org +/* AtCore Test Client + Copyright (C) <2016 - 2018> + + Authors: + Chris Rizzitello 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 @@ -17,201 +18,106 @@ along with this program. If not, see . */ #include "axiscontrol.h" -#include - -PieButton::PieButton(QLatin1Char &axis, int value, int size, int angle) : _axis(axis), _value(value) +#include +#include +#include +#include + +AxisControl::AxisControl(QWidget *parent) : + QWidget(parent) + , sbValue(new QDoubleSpinBox) { - const int delta = 16; // Qt Docs: angle is 16th of a degree. - setBrush(_palette.button()); - setStartAngle(angle * delta); - setSpanAngle(90 * delta); - setRect(QRect(QPoint(size * -1, size * -1), QPoint(size, size))); - setZValue(size * -1); - setAcceptHoverEvents(true); - setToolTip(tr("Move the hotend to the %1 by %2 units").arg(axis).arg(value)); -} + auto mainLayout = new QVBoxLayout; + auto newLabel = new QLabel(tr("Move Axis")); + sbValue->setSuffix(QStringLiteral(" mm")); + sbValue->setDecimals(3); + sbValue->setMaximum(100.0); + sbValue->setValue(1); + + auto comboUnits = new QComboBox(); + comboUnits->addItems(QStringList {QStringLiteral("Metric"), QStringLiteral("Imperial")}); + + connect(comboUnits, QOverload::of(&QComboBox::currentIndexChanged), this, [this](int selection) { + if (selection == 0) { + sbValue->setSuffix(QStringLiteral(" mm")); + } else { + sbValue->setSuffix(QStringLiteral(" in")); + } + emit unitsChanged(selection); + }); -void PieButton::setPalette(QPalette palette) -{ - _palette = palette; -} + auto layout = new QHBoxLayout(); + layout->addWidget(newLabel); + layout->addWidget(sbValue); + layout->addWidget(comboUnits); -void PieButton::mousePressEvent(QGraphicsSceneMouseEvent *) -{ - emit clicked(_axis, _value); -} + auto newWidget = new QWidget(); + newWidget->setLayout(layout); + newWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + mainLayout->addWidget(newWidget); -void PieButton::hoverEnterEvent(QGraphicsSceneHoverEvent *) -{ - setBrush(_palette.highlight()); -} + QSize iconSize = QSize(fontMetrics().height(), fontMetrics().height()); + auto glayout = new QGridLayout(); + newLabel = new QLabel(QStringLiteral("X/Y")); + newLabel->setAlignment(Qt::AlignCenter); + glayout->addWidget(newLabel, 2, 1); -void PieButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *) -{ - setBrush(_palette.button()); -} + //Y-Axis + glayout->addWidget(makeButton(QLatin1Char('Y'), 1, iconSize, QStringLiteral("arrow-up"), QStringLiteral("↑")), 1, 1); + glayout->addWidget(makeButton(QLatin1Char('Y'), -1, iconSize, QStringLiteral("arrow-down"), QStringLiteral("↓")), 3, 1); -RectButton::RectButton(QLatin1Char &axis, int value, int size) : _axis(axis), _value(value) -{ - setBrush(_palette.button()); - setRect(QRect(QPoint(0, 0), QPoint(size, size))); - setAcceptHoverEvents(true); - setZValue(size * -1); - if (axis != QLatin1Char('E')) { - setToolTip(tr("Move the hotend to the %1 by %2 units").arg(axis).arg(value)); - } else { - setToolTip(tr("Extrude %1 Units").arg(value)); - } -} + //X-Axis + glayout->addWidget(makeButton(QLatin1Char('X'), -1, iconSize, QStringLiteral("arrow-left"), QStringLiteral("←")), 2, 0); + glayout->addWidget(makeButton(QLatin1Char('X'), 1, iconSize, QStringLiteral("arrow-right"), QStringLiteral("→")), 2, 3); -void RectButton::setPalette(QPalette palette) -{ - _palette = palette; -} + auto bottomLayout = new QHBoxLayout(); + bottomLayout->addItem(glayout); -void RectButton::mousePressEvent(QGraphicsSceneMouseEvent *) -{ - emit clicked(_axis, _value); -} + newWidget = makeSimpleAxis(QLatin1Char('Z'), iconSize); + bottomLayout->addWidget(newWidget); -void RectButton::hoverEnterEvent(QGraphicsSceneHoverEvent *) -{ - setBrush(_palette.highlight()); -} + newWidget = makeSimpleAxis(QLatin1Char('E'), iconSize); + bottomLayout->addWidget(newWidget); -void RectButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *) -{ - setBrush(_palette.button()); + mainLayout->addItem(bottomLayout); + setLayout(mainLayout); } -/* About the Magic Numbers - I don't have experience programming with QGraphicsScene, - Tomaz is helping me, but until we have a better solution, all the values - that are dividing or multiplying the items is based only in tests and errors. - Those values was chosen because it fit better on the alignment of the items - in the scene. If you have a better solution, please share with us. - Lays Rodrigues - Jan/2017 -*/ -AxisControl::AxisControl(const QList &movementValues, QWidget *parent) : - QGraphicsView(parent) -{ - setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - - setScene(new QGraphicsScene()); - - const int listSize = movementValues.size(); - int maxValue = *std::max_element(movementValues.begin(), movementValues.end()); - QList lessList = movementValues; - std::sort(lessList.begin(), lessList.end(), std::less()); - QList greaterList = movementValues; - std::sort(greaterList.begin(), greaterList.end(), std::greater()); - - auto createPie = [ this, maxValue ](QLatin1Char & axis, int value, int size, int angle) { - auto pie = new PieButton(axis, value, size, angle); - pie->setPalette(this->palette()); - connect(pie, &PieButton::clicked, this, &AxisControl::clicked); - if (abs(value) == maxValue) { - setLabels(pie, axis, value); - } - scene()->addItem(pie); - }; - - auto createRect = [ this, maxValue ](QLatin1Char & axis, int value, int size, int xPos, int yPos) { - auto z = new RectButton(axis, value, size); - z->setPalette(this->palette()); - z->setPos(xPos, yPos); - connect(z, &RectButton::clicked, this, &AxisControl::clicked); - if (abs(value) == maxValue) { - setLabels(z, axis, value); - } - scene()->addItem(z); - }; - - int currPieSize = 25; - auto xchar = QLatin1Char('X'); - auto ychar = QLatin1Char('Y'); - auto zchar = QLatin1Char('Z'); - auto echar = QLatin1Char('E'); - for (const int &value : lessList) { - createPie(xchar, value, currPieSize, -45); // Left - createPie(xchar, value * -1, currPieSize, 135); // Right - createPie(ychar, value, currPieSize, 45); // Top - createPie(ychar, value * -1, currPieSize, 225); // Bottom - currPieSize += 25; - } - - int currSize = 25; - int xPos = sceneRect().width() - 50; - int yPos = -(listSize * 25); //Align with the origin - - // Z+ - for (const int &value : greaterList) { - createRect(zchar, value, currSize, xPos, yPos); - yPos += currSize; - } - - // Z- - for (const int &value : lessList) { - createRect(zchar, -value, currSize, xPos, yPos); - yPos += currSize; - } - currSize = 25; - xPos = sceneRect().width() - 50; - yPos = -(listSize * 25); //Align with the origin - - // E- - for (const int &value : greaterList) { - createRect(echar, -value, currSize, xPos, yPos); - yPos += currSize; +QPushButton *AxisControl::makeButton(const QLatin1Char axis, int multiplier, const QSize &iconSize, const QString &themeIcon, const QString &fallbackText) +{ + auto button = new QPushButton(QIcon::fromTheme(themeIcon), QString()); + button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + if (button->icon().isNull()) { + button->setText(fallbackText); + } else { + button->setIconSize(iconSize); } - // E+ - for (const int &value : lessList) { - createRect(echar, value, currSize, xPos, yPos); - yPos += currSize; - } - setSceneRect(scene()->itemsBoundingRect()); + connect(button, &QPushButton::clicked, this, [this, axis, multiplier] { + emit clicked(axis, sbValue->value() *multiplier); + }); + return button; } -void AxisControl::resizeEvent(QResizeEvent *) +QWidget *AxisControl::makeSimpleAxis(const QLatin1Char axis, const QSize &iconSize) { - fitInView(sceneRect(), Qt::KeepAspectRatio); -} + int multiplier = 1; + if (axis == QLatin1Char('E')) { + multiplier = -1; + } -void AxisControl::setLabels(QGraphicsItem *item, QLatin1Char &axis, int value) -{ - auto *lb = new QGraphicsSimpleTextItem(); - lb->setBrush(palette().buttonText()); + auto vLayout = new QVBoxLayout; - if (this->logicalDpiX() <= 96) { - lb->setText((value < 0) ? QStringLiteral(" -") + axis : QStringLiteral(" ") + axis); - } else { - lb->setText((value < 0) ? QStringLiteral("-") + axis : QStringLiteral(" ") + axis); - } + vLayout->addWidget(makeButton(axis, multiplier, iconSize, QStringLiteral("arrow-up"), QStringLiteral("↑"))); - if (axis.toLatin1() == 'X') { - lb->setY(item->y() - lb->boundingRect().width()); - if (value < 0) { - lb->setX(item->x() - item->boundingRect().width() / 1.2 - lb->boundingRect().width() / 2); - } else { - lb->setX(item->x() + item->boundingRect().width() / 1.2 - lb->boundingRect().width() / 2); - } - } else if (axis.toLatin1() == 'Y') { - lb->setX(item->x() - lb->boundingRect().width() / 2); - if (value < 0) { - lb->setY(item->y() + item->boundingRect().height() / 1.5); - } else { - lb->setY(item->y() - item->boundingRect().height()); - } - } else { + auto label = new QLabel(QString(axis)); + label->setAlignment(Qt::AlignCenter); + vLayout->addWidget(label); - lb->setX(item->x() + lb->boundingRect().width() / fontMetrics().width(lb->text())); + multiplier *= -1; + vLayout->addWidget(makeButton(axis, multiplier, iconSize, QStringLiteral("arrow-down"), QStringLiteral("↓"))); -#ifndef Q_OS_WIN - lb->setY(item->y() - lb->boundingRect().height() / fontMetrics().xHeight()); -#else - lb->setY(item->y() - lb->boundingRect().height() / fontMetrics().height()); -#endif - } - scene()->addItem(lb); + auto widget = new QWidget(); + widget->setLayout(vLayout); + return widget; } diff --git a/src/widgets/movementwidget.h b/src/widgets/movementwidget.h --- a/src/widgets/movementwidget.h +++ b/src/widgets/movementwidget.h @@ -87,6 +87,13 @@ */ void relativeMove(const QLatin1Char &axis, const double value); + /** + * @brief A Change of units was requested from the AxisControl + * This should connect to a function that calls AtCore::setUnits + * @param units: 0=Metric 1=Imperial + */ + void unitsChanged(int units); + private: QComboBox *comboMoveAxis = nullptr; QDoubleSpinBox *sbMoveAxis = nullptr; diff --git a/src/widgets/movementwidget.cpp b/src/widgets/movementwidget.cpp --- a/src/widgets/movementwidget.cpp +++ b/src/widgets/movementwidget.cpp @@ -93,6 +93,7 @@ auto axisControl = new AxisControl; mainLayout->addWidget(axisControl); connect(axisControl, &AxisControl::clicked, this, &MovementWidget::relativeMove); + connect(axisControl, &AxisControl::unitsChanged, this, &MovementWidget::unitsChanged); setLayout(mainLayout); } diff --git a/testclient/mainwindow.cpp b/testclient/mainwindow.cpp --- a/testclient/mainwindow.cpp +++ b/testclient/mainwindow.cpp @@ -307,6 +307,11 @@ core->setAbsolutePosition(); }); + connect(movementWidget, &MovementWidget::unitsChanged, this, [this](int units) { + auto selection = static_cast(units); + core->setUnits(selection); + }); + moveDock = new QDockWidget(tr("Movement"), this); moveDock->setWidget(movementWidget);