diff --git a/CMakeLists.txt b/CMakeLists.txt index 095d698..927fa40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,73 +1,71 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) project(atelier) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(KDECompilerSettings) include(KDEInstallDirs) include(KDECMakeSettings) include(ECMInstallIcons) if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif() set(CMAKE_CXX_STANDARD 11) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(QT_MIN_VERSION "5.9.0") set(KF5_DEP_VERSION "5.30.0") set(KDE_APPLICATIONS_VERSION_MAJOR "0") set(KDE_APPLICATIONS_VERSION_MINOR "70") set(KDE_APPLICATIONS_VERSION_MICRO "0") set(KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}") #Atelier Dependencies find_package(AtCore REQUIRED COMPONENTS AtCore AtCoreWidgets ) -find_package(Qwt6 REQUIRED) - find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS I18n XmlGui ConfigWidgets TextEditor ) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Core Widgets SerialPort Charts Quick Qml 3DCore 3DExtras 3DRender 3DInput Multimedia MultimediaWidgets ) if(BUILD_TESTING) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED) endif() # config.h configure_file (config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/src/config.h) include(ECMPoQmTools) include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}) add_subdirectory(src) add_subdirectory(deploy) if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ecm_install_po_files_as_qm(po) endif() feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/cmake/FindQwt6.cmake b/cmake/FindQwt6.cmake deleted file mode 100644 index 1ac5b75..0000000 --- a/cmake/FindQwt6.cmake +++ /dev/null @@ -1,114 +0,0 @@ -# Qt Widgets for Technical Applications -# available at http://www.http://qwt.sourceforge.net/ -# -# The module defines the following variables: -# QWT_FOUND - the system has Qwt -# QWT_INCLUDE_DIR - where to find qwt_plot.h -# QWT_INCLUDE_DIRS - qwt includes -# QWT_LIBRARY - where to find the Qwt library -# QWT_LIBRARIES - aditional libraries -# QWT_MAJOR_VERSION - major version -# QWT_MINOR_VERSION - minor version -# QWT_PATCH_VERSION - patch version -# QWT_VERSION_STRING - version (ex. 5.2.1) -# QWT_ROOT_DIR - root dir (ex. /usr/local) - -#============================================================================= -# Copyright 2010-2013, Julien Schueller -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# The views and conclusions contained in the software and documentation are those -# of the authors and should not be interpreted as representing official policies, -# either expressed or implied, of the FreeBSD Project. -#============================================================================= - -find_package( PkgConfig QUIET ) -pkg_search_module( PKG_QWT QUIET qwt>=6.0.0 Qt5Qwt6>=6.0.0 ) - -find_path ( QWT_INCLUDE_DIR - NAMES qwt_plot.h - HINTS ${PKG_QWT_INCLUDEDIR} ${QT_INCLUDE_DIR} - PATH_SUFFIXES qwt qwt-qt3 qwt-qt4 qwt-qt5 - ) - -set ( QWT_INCLUDE_DIRS ${QWT_INCLUDE_DIR} ) - -# version -set ( _VERSION_FILE ${QWT_INCLUDE_DIR}/qwt_global.h ) -if ( EXISTS ${_VERSION_FILE} ) - file ( STRINGS ${_VERSION_FILE} _VERSION_LINE REGEX "define[ ]+QWT_VERSION_STR" ) - if ( _VERSION_LINE ) - string ( REGEX REPLACE ".*define[ ]+QWT_VERSION_STR[ ]+\"(.*)\".*" "\\1" QWT_VERSION_STRING "${_VERSION_LINE}" ) - string ( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" QWT_MAJOR_VERSION "${QWT_VERSION_STRING}" ) - string ( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" QWT_MINOR_VERSION "${QWT_VERSION_STRING}" ) - string ( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" QWT_PATCH_VERSION "${QWT_VERSION_STRING}" ) - endif () -endif () - - -# check version -set ( _QWT_VERSION_MATCH TRUE ) -if ( Qwt_FIND_VERSION AND QWT_VERSION_STRING ) - if ( Qwt_FIND_VERSION_EXACT ) - if ( NOT Qwt_FIND_VERSION VERSION_EQUAL QWT_VERSION_STRING ) - set ( _QWT_VERSION_MATCH FALSE ) - endif () - else () - if ( QWT_VERSION_STRING VERSION_LESS Qwt_FIND_VERSION ) - set ( _QWT_VERSION_MATCH FALSE ) - endif () - endif () -endif () - - -find_library ( QWT_LIBRARY - NAMES qwt qwt-qt3 qwt-qt4 qwt-qt5 - ) - -set ( QWT_LIBRARIES ${QWT_LIBRARY} ) - - -# try to guess root dir from include dir -if ( QWT_INCLUDE_DIR ) - string ( REGEX REPLACE "(.*)/include.*" "\\1" QWT_ROOT_DIR ${QWT_INCLUDE_DIR} ) - # try to guess root dir from library dir -elseif ( QWT_LIBRARY ) - string ( REGEX REPLACE "(.*)/lib[/|32|64].*" "\\1" QWT_ROOT_DIR ${QWT_LIBRARY} ) -endif () - - -# handle the QUIETLY and REQUIRED arguments -include ( FindPackageHandleStandardArgs ) -find_package_handle_standard_args( Qwt6 DEFAULT_MSG QWT_LIBRARY QWT_INCLUDE_DIR _QWT_VERSION_MATCH ) - -mark_as_advanced ( - QWT_LIBRARY - QWT_LIBRARIES - QWT_INCLUDE_DIR - QWT_INCLUDE_DIRS - QWT_MAJOR_VERSION - QWT_MINOR_VERSION - QWT_PATCH_VERSION - QWT_VERSION_STRING - QWT_ROOT_DIR - ) diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index b4fa615..6d78b01 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -1,31 +1,30 @@ include_directories(../dialogs) -include_directories(${QWT_INCLUDE_DIR}) set(widgets_SRCS atcoreinstancewidget.cpp bedextruderwidget.cpp gcodeeditorwidget.cpp thermowidget.cpp + qcgaugewidget.cpp videomonitorwidget.cpp welcomewidget.cpp ) add_library(AtelierWidgets STATIC ${widgets_SRCS}) target_link_libraries(AtelierWidgets AtCore::AtCore KF5::I18n KF5::TextEditor Qt5::Charts Qt5::Core Qt5::Multimedia Qt5::MultimediaWidgets Qt5::Widgets - ${QWT_LIBRARY} ) if(WIN32) - target_compile_definitions(AtelierWidgets PRIVATE -DQWT_DLL) + target_compile_definitions(AtelierWidgets PRIVATE) endif() add_subdirectory(3dview) diff --git a/src/widgets/bedextruderwidget.cpp b/src/widgets/bedextruderwidget.cpp index 727cb7e..84a9ce6 100644 --- a/src/widgets/bedextruderwidget.cpp +++ b/src/widgets/bedextruderwidget.cpp @@ -1,130 +1,130 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2016> Author: Lays Rodrigues - lays.rodrigues@kde.org Tomaz Canabraza - tcanabrava@kde.org Chris Rizzitello - rizzitello@kde.org 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 . */ #include #include #include #include #include "bedextruderwidget.h" #include "thermowidget.h" BedExtruderWidget::BedExtruderWidget(QWidget *parent) : QWidget(parent) , m_bedThermo(new ThermoWidget(this, QString(i18n("Bed")))) , m_extruderThermo(new ThermoWidget(this, QString(i18n("HotEnd")))) , m_extrudersLayout(new QHBoxLayout) , m_extruderBox(new QWidget(this)) { - m_bedThermo->setScale(0, 150); - m_extruderThermo->setScale(0, 250); + m_bedThermo->setRange(0, 150); + m_extruderThermo->setRange(0, 250); m_extruderBox->setLayout(m_extrudersLayout); auto *label = new QLabel(i18n("Active Extruder:"), this); m_extrudersLayout->addWidget(label); auto *layout = new QHBoxLayout; layout->addWidget(m_extruderBox); layout->addWidget(m_bedThermo); layout->addWidget(m_extruderThermo); setLayout(layout); //Add Default Extruder setExtruderCount(1); connect(m_bedThermo, &ThermoWidget::targetTemperatureChanged, this, [this](int v) { emit bedTemperatureChanged(v, false); }); connect(m_extruderThermo, &ThermoWidget::targetTemperatureChanged, this, [this](int v) { emit extTemperatureChanged(v, currentExtruder(), false); }); } void BedExtruderWidget::setExtruderCount(int value) { value > 1 ? m_extruderBox->setVisible(true) : m_extruderBox->setVisible(false); if (value == m_extruderCount) { return; } if (m_extruderCount < value) { //loop for the new buttons for (int i = m_extruderCount; i < value; i++) { auto *rb = new QRadioButton(QString::number(i + 1), this); m_extrudersLayout->addWidget(rb); extruderMap.insert(i, rb); } } else { //remove buttons - need to test it! for (int i = m_extruderCount; i >= value; i--) { auto *rb = extruderMap.value(i); m_extrudersLayout->removeWidget(rb); extruderMap.remove(i); delete (rb); } } m_extruderCount = value; } void BedExtruderWidget::updateBedTemp(const float temp) { m_bedThermo->setCurrentTemperature(double(temp)); } void BedExtruderWidget::updateExtTemp(const float temp) { m_extruderThermo->setCurrentTemperature(double(temp)); } void BedExtruderWidget::updateBedTargetTemp(const int temp) { m_bedThermo->setTargetTemperature(temp); } void BedExtruderWidget::updateExtTargetTemp(const int temp) { m_extruderThermo->setTargetTemperature(temp); } int BedExtruderWidget::currentExtruder() { int currExt = 0; for (int i = 0; i < extruderMap.size(); i++) { if (extruderMap.value(i)->isChecked()) { currExt = i; break; } } return currExt; } void BedExtruderWidget::setBedMaxTemperature(int value) { - m_bedThermo->setScale(0, value); + m_bedThermo->setRange(0, value); } void BedExtruderWidget::setExtruderMaxTemperature(int value) { - m_extruderThermo->setScale(0, value); + m_extruderThermo->setRange(0, value); } void BedExtruderWidget::setBedThermoHidden(bool hidden) { m_bedThermo->setHidden(hidden); } diff --git a/src/widgets/qcgaugewidget.cpp b/src/widgets/qcgaugewidget.cpp new file mode 100644 index 0000000..62b8b85 --- /dev/null +++ b/src/widgets/qcgaugewidget.cpp @@ -0,0 +1,647 @@ +/*************************************************************************** +** ** +** QcGauge, for instrumentation, and real time data measurement ** +** visualization widget for Qt. ** +** Copyright (C) 2015 Hadj Tahar Berrima ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU Lesser 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 Lesser General Public License for more details. ** +** ** +** You should have received a copy of the GNU Lesser General Public ** +** License along with this program. ** +** If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Hadj Tahar Berrima ** +** Website: http://pytricity.com/ ** +** Contact: berrima_tahar@yahoo.com ** +** Date: 1 dec 2014 ** +** Version: 1.0 ** +**************************************************************************** +** Modified: Chris Rizzitello 2019 ** +** Website: http://atelier.kde.org ** +** Contact: rizzitello@kde.org ** +** Version: Atelier-Custom ** +****************************************************************************/ + +#include "qcgaugewidget.h" + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcGaugeWidget::QcGaugeWidget(QWidget *parent) : + QWidget(parent) +{ + setMinimumSize(250, 250); +} + +QcBackgroundItem *QcGaugeWidget::addBackground(float position) +{ + QcBackgroundItem *item = new QcBackgroundItem(this); + item->setPosition(position); + mItems.append(item); + return item; +} + +QcDegreesItem *QcGaugeWidget::addDegrees(float position) +{ + QcDegreesItem *item = new QcDegreesItem(this); + item->setPosition(position); + + mItems.append(item); + return item; +} + +QcValuesItem *QcGaugeWidget::addValues(float position) +{ + auto *item = new QcValuesItem(this); + item->setPosition(position); + mItems.append(item); + return item; +} + +QcArcItem *QcGaugeWidget::addArc(float position) +{ + QcArcItem *item = new QcArcItem(this); + item->setPosition(position); + mItems.append(item); + return item; +} + +QcNeedleItem *QcGaugeWidget::addNeedle(float position) +{ + auto *item = new QcNeedleItem(this); + item->setPosition(position); + mItems.append(item); + return item; +} + +QcLabelItem *QcGaugeWidget::addLabel(float position) +{ + QcLabelItem *item = new QcLabelItem(this); + item->setPosition(position); + mItems.append(item); + return item; +} + +void QcGaugeWidget::addItem(QcItem *item, float position) +{ + // takes parentship of the item + item->setParent(this); + item->setPosition(position); + mItems.append(item); +} + +int QcGaugeWidget::removeItem(QcItem *item) +{ + return mItems.removeAll(item); +} + +QList QcGaugeWidget::items() +{ + return mItems; +} + +void QcGaugeWidget::paintEvent(QPaintEvent */*paintEvt*/) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + for (QcItem *item : qAsConst(mItems)) { + item->draw(&painter); + } +} +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcItem::QcItem(QObject *parent) : + QObject(parent) +{ + + parentWidget = qobject_cast(parent); + mPosition = 50; +} + +int QcItem::type() +{ + return 50; +} + +void QcItem::update() +{ + parentWidget->update(); +} + +float QcItem::position() +{ + return mPosition; +} + +QRectF QcItem::rect() +{ + return mRect; +} + +void QcItem::setPosition(float position) +{ + if (position > 100) { + mPosition = 100; + } else if (position < 0) { + mPosition = 0; + } else { + mPosition = position; + } + update(); +} + +QRectF QcItem::adjustRect(float percentage) +{ + float r = getRadius(mRect); + float offset = r - (percentage * r) / 100.0; + QRectF tmpRect = mRect.adjusted(offset, offset, -offset, -offset); + return tmpRect; +} + +float QcItem::getRadius(const QRectF &tmpRect) +{ + float r = 0; + if (tmpRect.width() < tmpRect.height()) { + r = tmpRect.width() / 2.0; + } else { + r = tmpRect.height() / 2.0; + } + return r; +} + +QRectF QcItem::resetRect() +{ + mRect = parentWidget->rect(); + float r = getRadius(mRect); + mRect.setWidth(2.0 * r); + mRect.setHeight(2.0 * r); + mRect.moveCenter(parentWidget->rect().center()); + return mRect; +} + +QPointF QcItem::getPoint(float deg, const QRectF &tmpRect) +{ + float r = getRadius(tmpRect); + float xx = cos(qDegreesToRadians(deg)) * r; + float yy = sin(qDegreesToRadians(deg)) * r; + QPointF pt; + xx = tmpRect.center().x() - xx; + yy = tmpRect.center().y() - yy; + pt.setX(xx); + pt.setY(yy); + return pt; +} + +float QcItem::getAngle(const QPointF &pt, const QRectF &tmpRect) +{ + float xx = tmpRect.center().x() - pt.x(); + float yy = tmpRect.center().y() - pt.y(); + return qRadiansToDegrees(atan2(yy, xx)); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcScaleItem::QcScaleItem(QObject *parent) : + QcItem(parent) +{ + mMinDegree = -45; + mMaxDegree = 225; + mMinValue = 0; + mMaxValue = 100; +} + +void QcScaleItem::setValueRange(float minValue, float maxValue) +{ + if (!(minValue < maxValue)) { + mMaxValue = minValue; + mMinValue = maxValue; + } else { + mMinValue = minValue; + mMaxValue = maxValue; + } + +} + +void QcScaleItem::setDgereeRange(float minDegree, float maxDegree) +{ + if (!(minDegree < maxDegree)) { + mMinDegree = maxDegree; + mMaxDegree = minDegree; + } else { + mMinDegree = minDegree; + mMaxDegree = maxDegree; + } +} + +float QcScaleItem::getDegFromValue(float v) +{ + float a = (mMaxDegree - mMinDegree) / (mMaxValue - mMinValue); + float b = -a * mMinValue + mMinDegree; + return a * v + b; +} + +void QcScaleItem::setMinValue(float minValue) +{ + if (minValue > mMaxValue) { + return; + } + mMinValue = minValue; + update(); +} + +void QcScaleItem::setMaxValue(float maxValue) +{ + if (maxValue < mMinValue) { + return; + } + mMaxValue = maxValue; + update(); +} + +void QcScaleItem::setMinDegree(float minDegree) +{ + if (minDegree > mMaxDegree) { + return; + } + mMinDegree = minDegree; + update(); +} +void QcScaleItem::setMaxDegree(float maxDegree) +{ + if (maxDegree < mMinDegree) { + return; + } + mMaxDegree = maxDegree; + update(); +} + +float QcScaleItem::minValue() +{ + return mMinValue; +} + +float QcScaleItem::maxValue() +{ + return mMaxValue; +} + +float QcScaleItem::minDegree() +{ + return mMinDegree; +} + +float QcScaleItem::maxDegree() +{ + return mMaxDegree; +} +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcBackgroundItem::QcBackgroundItem(QObject *parent) : + QcItem(parent) +{ + setPosition(88); + mPen = Qt::NoPen; + setPosition(88); + + addColor(0.4, Qt::darkGray); + addColor(0.8, Qt::black); + +} + +void QcBackgroundItem::draw(QPainter *painter) +{ + QRectF tmpRect = resetRect(); + painter->setBrush(Qt::NoBrush); + QLinearGradient linearGrad(tmpRect.topLeft(), tmpRect.bottomRight()); + for (int i = 0; i < mColors.size(); i++) { + linearGrad.setColorAt(mColors[i].first, mColors[i].second); + } + painter->setPen(mPen); + painter->setBrush(linearGrad); + painter->drawEllipse(adjustRect(position())); +} + +void QcBackgroundItem::addColor(float position, const QColor &color) +{ + if (position < 0 || position > 1) { + return; + } + QPair pair; + pair.first = position; + pair.second = color; + mColors.append(pair); + update(); +} + +void QcBackgroundItem::clearrColors() +{ + mColors.clear(); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcLabelItem::QcLabelItem(QObject *parent) : + QcItem(parent) +{ + setPosition(50); + mAngle = 270; + mText = "%"; + mColor = Qt::black; +} + +void QcLabelItem::draw(QPainter *painter) +{ + resetRect(); + QRectF tmpRect = adjustRect(position()); + float r = getRadius(rect()); + painter->setFont(mFont); + painter->setPen(QPen(mColor)); + + QPointF txtCenter = getPoint(mAngle, tmpRect); + QFontMetrics fMetrics = painter->fontMetrics(); + QSize sz = fMetrics.size(Qt::TextSingleLine, mText); + QRectF txtRect(QPointF(0, 0), sz); + txtRect.moveCenter(txtCenter); + + painter->drawText(txtRect, Qt::TextSingleLine, mText); + +} + +void QcLabelItem::setAngle(float a) +{ + mAngle = a; + update(); +} + +float QcLabelItem::angle() +{ + return mAngle; +} + +void QcLabelItem::setFont(const QFont &font) +{ + mFont = font; +} + +void QcLabelItem::setText(const QString &text, bool repaint) +{ + mText = text; + if (repaint) { + update(); + } +} + +QString QcLabelItem::text() +{ + return mText; +} + +void QcLabelItem::setColor(const QColor &color) +{ + mColor = color; + update(); +} + +QColor QcLabelItem::color() +{ + return mColor; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcArcItem::QcArcItem(QObject *parent) : + QcScaleItem(parent) +{ + setPosition(80); + mColor = Qt::black; +} + +void QcArcItem::draw(QPainter *painter) +{ + resetRect(); + QRectF tmpRect = adjustRect(position()); + float r = getRadius(tmpRect); + + QPen pen; + pen.setColor(mColor); + pen.setWidthF(r / 40); + painter->setPen(pen); + painter->drawArc(tmpRect, -16 * (minDegree() + 180), -16 * (maxDegree() - minDegree())); +} + +void QcArcItem::setColor(const QColor &color) +{ + mColor = color; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcDegreesItem::QcDegreesItem(QObject *parent) : + QcScaleItem(parent) +{ + mStep = 10; + mColor = Qt::black; + mSubDegree = false; + setPosition(90); +} + +void QcDegreesItem::draw(QPainter *painter) +{ + resetRect(); + QRectF tmpRect = adjustRect(position()); + + painter->setPen(mColor); + float r = getRadius(tmpRect); + for (float val = minValue(); val <= maxValue(); val += mStep) { + float deg = getDegFromValue(val); + QPointF pt = getPoint(deg, tmpRect); + QPainterPath path; + path.moveTo(pt); + path.lineTo(tmpRect.center()); + pt = path.pointAtPercent(0.03); + QPointF newPt = path.pointAtPercent(0.13); + + QPen pen; + pen.setColor(mColor); + if (!mSubDegree) { + pen.setWidthF(r / 25.0); + } + + painter->setPen(pen); + painter->drawLine(pt, newPt); + + } +} + +void QcDegreesItem::setStep(float step) +{ + mStep = step; + update(); +} + +void QcDegreesItem::setColor(const QColor &color) +{ + mColor = color; + update(); +} + +void QcDegreesItem::setSubDegree(bool b) +{ + mSubDegree = b; + update(); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcNeedleItem::QcNeedleItem(QObject *parent) : + QcScaleItem(parent) + , mCurrentValue(0) + , mColor(Qt::black) + , mLabel(nullptr) +{ +} + +void QcNeedleItem::draw(QPainter *painter) +{ + resetRect(); + QRectF tmpRect = adjustRect(position()); + painter->save(); + painter->translate(tmpRect.center()); + float deg = getDegFromValue(mCurrentValue); + painter->rotate(deg + 90.0); + painter->setBrush(QBrush(mColor)); + painter->setPen(Qt::NoPen); + + QLinearGradient grad; + createDiamonNeedle(getRadius(tmpRect)); + painter->drawConvexPolygon(mNeedlePoly); + painter->restore(); +} + +void QcNeedleItem::setCurrentValue(float value) +{ + if (value < minValue()) { + mCurrentValue = minValue(); + } else if (value > maxValue()) { + mCurrentValue = maxValue(); + } else { + mCurrentValue = value; + } + + if (mLabel) { + mLabel->setText(QString::number(mCurrentValue), false); + } + update(); +} + +float QcNeedleItem::currentValue() +{ + return mCurrentValue; +} + +void QcNeedleItem::setColor(const QColor &color) +{ + mColor = color; + update(); +} + +QColor QcNeedleItem::color() +{ + return mColor; +} + +void QcNeedleItem::setLabel(QcLabelItem *label) +{ + mLabel = label; + update(); +} + +QcLabelItem *QcNeedleItem::label() +{ + return mLabel; +} + +void QcNeedleItem::createDiamonNeedle(float r) +{ + QVector tmpPoints; + tmpPoints.append(QPointF(0.0, 0.0)); + tmpPoints.append(QPointF(-r / 20.0, r / 20.0)); + tmpPoints.append(QPointF(0.0, r)); + tmpPoints.append(QPointF(r / 20.0, r / 20.0)); + mNeedlePoly = tmpPoints; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +QcValuesItem::QcValuesItem(QObject *parent) : + QcScaleItem(parent) + , mStep(10) + , mColor(Qt::black) +{ + setPosition(70); +} + +void QcValuesItem::draw(QPainter *painter) +{ + QRectF tmpRect = resetRect(); + float r = getRadius(adjustRect(99)); + painter->setFont(mFont); + painter->setPen(mColor); + for (float val = minValue(); val <= maxValue(); val += mStep) { + float deg = getDegFromValue(val); + QPointF pt = getPoint(deg, tmpRect); + QPainterPath path; + path.moveTo(pt); + path.lineTo(tmpRect.center()); + QString strVal = QString::number(val); + QFontMetrics fMetrics = painter->fontMetrics(); + QSize sz = fMetrics.size(Qt::TextSingleLine, strVal); + QRectF txtRect(QPointF(0, 0), sz); + QPointF textCenter = path.pointAtPercent(1.0 - position() / 100.0); + txtRect.moveCenter(textCenter); + + painter->drawText(txtRect, Qt::TextSingleLine, strVal); + } +} + +void QcValuesItem::setFont(const QFont &font) +{ + mFont = font; +} + +void QcValuesItem::setStep(float step) +{ + mStep = step; +} + +void QcValuesItem::setColor(const QColor &color) +{ + mColor = color; +} diff --git a/src/widgets/qcgaugewidget.h b/src/widgets/qcgaugewidget.h new file mode 100644 index 0000000..ea1dee6 --- /dev/null +++ b/src/widgets/qcgaugewidget.h @@ -0,0 +1,272 @@ +/*************************************************************************** +** ** +** QcGauge, for instrumentation, and real time data measurement ** +** visualization widget for Qt. ** +** Copyright (C) 2015 Hadj Tahar Berrima ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU Lesser 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 Lesser General Public License for more details. ** +** ** +** You should have received a copy of the GNU Lesser General Public ** +** License along with this program. ** +** If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Hadj Tahar Berrima ** +** Website: http://pytricity.com/ ** +** Contact: berrima_tahar@yahoo.com ** +** Date: 1 dec 2014 ** +** Version: 1.0 ** +**************************************************************************** +** Modified: Chris Rizzitello 2019 ** +** Website: http://atelier.kde.org ** +** Contact: rizzitello@kde.org ** +** Version: Atelier-Custom ** +****************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include + +#if defined(QCGAUGE_COMPILE_LIBRARY) +# define QCGAUGE_DECL Q_DECL_EXPORT +#elif defined(QCGAUGE_USE_LIBRARY) +# define QCGAUGE_DECL Q_DECL_IMPORT +#else +# define QCGAUGE_DECL +#endif + +class QcGaugeWidget; +class QcItem; +class QcBackgroundItem; +class QcDegreesItem; +class QcValuesItem; +class QcArcItem; +class QcNeedleItem; +class QcLabelItem; + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +class QCGAUGE_DECL QcGaugeWidget : public QWidget +{ + Q_OBJECT +public: + explicit QcGaugeWidget(QWidget *parent = nullptr); + ~QcGaugeWidget() override = default; + + QcBackgroundItem *addBackground(float position); + QcDegreesItem *addDegrees(float position); + QcValuesItem *addValues(float position); + QcArcItem *addArc(float position); + QcNeedleItem *addNeedle(float position); + QcLabelItem *addLabel(float position); + + void addItem(QcItem *item, float position); + int removeItem(QcItem *item); + QList items(); + +private: + QList mItems; + +protected: + void paintEvent(QPaintEvent *) override; + +}; + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcItem : public QObject +{ + Q_OBJECT +public: + explicit QcItem(QObject *parent = nullptr); + virtual void draw(QPainter *) = 0; + virtual int type(); + + void setPosition(float percentage); + float position(); + QRectF rect(); + enum Error {InvalidValueRange, InvalidDegreeRange, InvalidStep}; + +protected: + QRectF adjustRect(float percentage); + float getRadius(const QRectF &); + float getAngle(const QPointF &, const QRectF &tmpRect); + QPointF getPoint(float deg, const QRectF &tmpRect); + QRectF resetRect(); + void update(); + +private: + QRectF mRect; + QWidget *parentWidget; + float mPosition; +}; +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcScaleItem : public QcItem +{ + Q_OBJECT +public: + explicit QcScaleItem(QObject *parent = nullptr); + + void setValueRange(float minValue, float maxValue); + void setDgereeRange(float minDegree, float maxDegree); + void setMinValue(float minValue); + void setMaxValue(float maxValue); + void setMinDegree(float minDegree); + void setMaxDegree(float maxDegree); + float minValue(); + float maxValue(); + float minDegree(); + float maxDegree(); + +protected: + float getDegFromValue(float); + +private: + float mMinValue; + float mMaxValue; + float mMinDegree; + float mMaxDegree; + +}; +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcBackgroundItem : public QcItem +{ + Q_OBJECT +public: + explicit QcBackgroundItem(QObject *parent = nullptr); + void draw(QPainter *) override; + void addColor(float position, const QColor &color); + void clearrColors(); + +private: + QPen mPen; + QList > mColors; + QLinearGradient mLinearGrad; +}; + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcLabelItem : public QcItem +{ + Q_OBJECT +public: + explicit QcLabelItem(QObject *parent = nullptr); + void draw(QPainter *) override; + void setAngle(float); + float angle(); + void setFont(const QFont &font); + void setText(const QString &text, bool repaint = true); + QString text(); + void setColor(const QColor &color); + QColor color(); + +private: + float mAngle; + QString mText; + QColor mColor; + QFont mFont; +}; + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcArcItem : public QcScaleItem +{ + Q_OBJECT +public: + explicit QcArcItem(QObject *parent = nullptr); + void draw(QPainter *) override; + void setColor(const QColor &color); + +private: + QColor mColor; + +signals: + +public slots: + +}; +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcDegreesItem : public QcScaleItem +{ + Q_OBJECT +public: + explicit QcDegreesItem(QObject *parent = nullptr); + void draw(QPainter *painter) override; + void setStep(float step); + void setColor(const QColor &color); + void setSubDegree(bool); +private: + float mStep; + QColor mColor; + bool mSubDegree; +}; +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcNeedleItem : public QcScaleItem +{ + Q_OBJECT +public: + explicit QcNeedleItem(QObject *parent = nullptr); + void draw(QPainter *) override; + void setCurrentValue(float value); + float currentValue(); + void setColor(const QColor &color); + QColor color(); + + void setLabel(QcLabelItem *); + QcLabelItem *label(); + +private: + void createDiamonNeedle(float r); + QPolygonF mNeedlePoly; + float mCurrentValue; + QColor mColor; + QcLabelItem *mLabel; +}; +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// + +class QCGAUGE_DECL QcValuesItem : public QcScaleItem +{ + Q_OBJECT +public: + explicit QcValuesItem(QObject *parent = nullptr); + void draw(QPainter *) override; + void setFont(const QFont &font); + void setStep(float step); + void setColor(const QColor &color); +private: + float mStep{10}; + QFont mFont; + QColor mColor; +}; diff --git a/src/widgets/thermowidget.cpp b/src/widgets/thermowidget.cpp index 16255ed..3cfa1aa 100644 --- a/src/widgets/thermowidget.cpp +++ b/src/widgets/thermowidget.cpp @@ -1,306 +1,343 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2018> Author: Tomaz Canabrava - tcanabrava@kde.org Chris Rizzitello - rizzitello@kde.org Lays Rodrigues - lays.rodrigues@kde.org 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 . */ #include #include #include #include #include #include #include #include +#include #include "thermowidget.h" ThermoWidget::ThermoWidget(QWidget *parent, const QString &name) : - QwtDial(parent) - , m_targetTemperatureNeedle(new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, false, Qt::red, Qt::darkRed)) - , m_name(name) + QcGaugeWidget(parent) , m_tempChangedTimer(new QTimer(this)) , m_currentTemperature(0) , m_targetTemperature(0) { - setScaleArc(40, 320); - //make our current temperature needle here so we can set it to match text color. - m_currentTemperatureNeedle = new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, true, palette().text().color()); - setNeedle(m_currentTemperatureNeedle); - setReadOnly(false); setFocusPolicy(Qt::StrongFocus); + QcBackgroundItem *bkground = addBackground(100); + bkground->clearrColors(); + bkground->addColor(0.0, palette().light().color()); + + auto bk2 = addBackground(98); + bk2->clearrColors(); + bk2->addColor(0.0, palette().dark().color()); + + auto arc = addArc(70); + arc->setColor(palette().midlight().color()); + m_ticksItem = addDegrees(70); + m_ticksItem->setColor(Qt::red); + + m_subTicksItem = addDegrees(70); + m_subTicksItem->setSubDegree(true); + m_subTicksItem->setStep(5); + m_subTicksItem->setColor(palette().text().color()); + + m_nameLabel = addLabel(80); + m_nameLabel->setFont(font()); + m_nameLabel->setText(name); + m_nameLabel->setColor(palette().text().color()); + m_valueDisplay = addValues(85); + m_valueDisplay->setFont(font()); + m_valueDisplay->setColor(palette().text().color()); + + m_targetTemperatureNeedle = addNeedle(60); + m_targetTemperatureNeedle->setPosition(95); + m_targetTemperatureNeedle->setColor(Qt::red); + + QcLabelItem *lab = addLabel(60); + lab->setText(QString::number(m_currentTemperature)); + lab->setColor(palette().text().color()); + + m_currentTemperatureNeedle = addNeedle(60); + m_currentTemperatureNeedle->setPosition(65); + m_currentTemperatureNeedle->setColor(palette().text().color()); + m_currentTemperatureNeedle->setLabel(lab); + addBackground(7); m_cursorTimer = new QTimer(this); connect(m_cursorTimer, &QTimer::timeout, this, [this] { m_paintCursor = !m_paintCursor; update(); }); m_tempChangedTimer->setSingleShot(true); connect(m_tempChangedTimer, &QTimer::timeout, this, [this] { emit targetTemperatureChanged(m_targetTemperature); }); } +void ThermoWidget::setRange(int min, int max) +{ + m_maxValue = max; + m_minValue = min; + m_currentTemperatureNeedle->setValueRange(min, max); + m_targetTemperatureNeedle->setValueRange(min, max); + m_valueDisplay->setValueRange(min, max); + int range = max - min; + if (range <= 150) { + m_valueDisplay->setStep(10); + m_ticksItem->setStep(10); + } else if (range <= 300) { + m_valueDisplay->setStep(25); + m_ticksItem->setStep(25); + } else { + m_valueDisplay->setStep((max - min) / 10); + m_ticksItem->setStep((max - min) / 10); + } + m_ticksItem->setValueRange(min, max); +} + +void ThermoWidget::setName(const QString &name) +{ + m_nameLabel->setText(name); +} + +void ThermoWidget::setCurrentTemperature(double temperature) +{ + if (!isEqual(m_currentTemperature, temperature)) { + m_currentTemperature = temperature; + m_currentTemperatureNeedle->setCurrentValue(float(temperature)); + update(); + } +} + +void ThermoWidget::setTargetTemperature(int temperature) +{ + if (m_targetTemperature != temperature) { + m_targetTemperatureText = QString::number(temperature); + m_targetTemperature = temperature; + m_targetTemperatureNeedle->setCurrentValue(temperature); + resetTimer(); + update(); + } +} void ThermoWidget::keyPressEvent(QKeyEvent *event) { //set our target text length. - int slen = m_currentTemperatureTextFromEditor.length() - 1; + int slen = m_targetTemperatureText.length() - 1; // be sure our cursor position is valid. if (slen < 0) { - m_currentTemperatureTextFromEditor = '-'; + m_targetTemperatureText = QStringLiteral("0"); m_cursorPos = 0; } else if (slen > 2) { m_cursorPos = 2; } //parse the key events. if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) { - auto tmp = m_currentTemperatureTextFromEditor; + auto tmp = QString::number(m_targetTemperature); if (m_cursorPos == slen) { tmp.append(event->key()); } else { tmp.insert(m_cursorPos, event->key()); } - if (tmp.startsWith('0')) { - tmp.remove(0, 1); - } - - if (tmp.contains('-')) { - tmp.remove('-'); - //push the cursor back to negate advancement; - m_cursorPos--; - } - if (tmp.toInt() <= upperBound() && tmp.toInt() >= lowerBound()) { - m_currentTemperatureTextFromEditor = tmp; + if (tmp.toInt() <= m_maxValue && tmp.toInt() >= m_minValue) { + m_targetTemperatureText = tmp; if (m_cursorPos <= slen) { m_cursorPos++; } } - } else if (event->key() == Qt::Key_Delete && m_currentTemperatureTextFromEditor.count()) { - m_currentTemperatureTextFromEditor.remove(m_cursorPos, 1); + } else if (event->key() == Qt::Key_Delete && m_targetTemperatureText.count()) { + m_targetTemperatureText.remove(m_cursorPos, 1); if (m_cursorPos < slen) { m_cursorPos = slen; } m_cursorPos--; - } else if (event->key() == Qt::Key_Backspace && m_currentTemperatureTextFromEditor.count()) { + } else if (event->key() == Qt::Key_Backspace && m_targetTemperatureText.count()) { if (m_cursorPos <= slen) { m_cursorPos--; - m_currentTemperatureTextFromEditor.remove(m_cursorPos, 1); + m_targetTemperatureText.remove(m_cursorPos, 1); } } else if (event->key() == Qt::Key_Enter) { - m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); + m_targetTemperature = m_targetTemperatureText.toInt(); } else if (event->key() == Qt::Key_Escape) { - m_currentTemperatureTextFromEditor = '0'; + m_targetTemperatureText = QString::number(m_targetTemperature); } else if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Plus) { - if (!isEqual(m_targetTemperature, upperBound())) { - m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 1); + if (!isEqual(m_targetTemperature, m_maxValue)) { + m_targetTemperatureText = QString::number(m_targetTemperature + 1); } } else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Minus) { - if (!isEqual(m_targetTemperature, lowerBound())) { - m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 1); + if (!isEqual(m_targetTemperature, m_minValue)) { + m_targetTemperatureText = QString::number(m_targetTemperature - 1); } } else if (event->key() == Qt::Key_PageUp) { - if (m_targetTemperature + 10 > upperBound()) { - m_currentTemperatureTextFromEditor = QString::number(upperBound()); + if (m_targetTemperature + 10 > m_maxValue) { + m_targetTemperatureText = QString::number(m_maxValue); } else { - m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 10); + m_targetTemperatureText = QString::number(m_targetTemperature + 10); } } else if (event->key() == Qt::Key_PageDown) { - if (m_targetTemperature - 10 < lowerBound()) { - m_currentTemperatureTextFromEditor = QString::number(lowerBound()); + if (m_targetTemperature - 10 < m_minValue) { + m_targetTemperatureText = QString::number(m_minValue); } else { - m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 10); + m_targetTemperatureText = QString::number(m_targetTemperature - 10); } } else if (event->key() == Qt::Key_Right) { if (m_cursorPos < slen) { m_cursorPos++; } } else if (event->key() == Qt::Key_Left) { if (m_cursorPos > 0) { m_cursorPos--; } } else { - QwtDial::keyPressEvent(event); - return; + QcGaugeWidget::keyPressEvent(event); + } + + if (m_cursorPos < 0) { + m_cursorPos = 0; + } else if (m_cursorPos > 2) { + m_cursorPos = 2; + } + + if (m_targetTemperatureText.simplified().isEmpty()) { + m_targetTemperatureText = QStringLiteral("0"); } - if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { - m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); + if (m_targetTemperature != m_targetTemperatureText.toInt()) { + setTargetTemperature(m_targetTemperatureText.toInt()); resetTimer(); update(); - event->accept(); } + event->accept(); } void ThermoWidget::wheelEvent(QWheelEvent *event) { if (event->angleDelta().y() > 0) { - if (m_targetTemperature + 10 > upperBound()) { - m_currentTemperatureTextFromEditor = QString::number(upperBound()); + if (m_targetTemperature + 10 > m_maxValue) { + m_targetTemperatureText = QString::number(m_maxValue); } else { - m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 10); + m_targetTemperatureText = QString::number(m_targetTemperature + 10); } } else if (event->angleDelta().y() < 0) { - if (m_targetTemperature - 10 < lowerBound()) { - m_currentTemperatureTextFromEditor = QString::number(lowerBound()); + if (m_targetTemperature - 10 < m_minValue) { + m_targetTemperatureText = QString::number(m_minValue); } else { - m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 10); + m_targetTemperatureText = QString::number(m_targetTemperature - 10); } } - if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { - m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); + if (m_targetTemperature != m_targetTemperatureText.toInt()) { + setTargetTemperature(m_targetTemperatureText.toInt()); resetTimer(); update(); } event->accept(); } void ThermoWidget::focusOutEvent(QFocusEvent *event) { - if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { - m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); + if (m_targetTemperature != m_targetTemperatureText.toInt()) { + setTargetTemperature(m_targetTemperatureText.toInt()); resetTimer(); event->accept(); } m_cursorTimer->stop(); m_paintCursor = false; update(); } void ThermoWidget::focusInEvent(QFocusEvent *event) { m_cursorTimer->start(1000); event->accept(); } +void ThermoWidget::resetTimer() +{ + m_tempChangedTimer->start(500); +} + void ThermoWidget::paintEvent(QPaintEvent *event) { - QwtDial::paintEvent(event); - const QString currentText = QString::number(m_currentTemperature); - - QFontMetrics fm(font()); - const int targetWidth = fm.width(m_currentTemperatureTextFromEditor); - const int currentWidth = fm.width(currentText); - const int nameWidth = fm.width(m_name); - const int wWidth = fm.width('W'); - const int cursorWidth = fm.width('0'); + QcGaugeWidget::paintEvent(event); + + int radiusAsInt = 0; + if (rect().width() < rect().height()) { + radiusAsInt = int(rect().width() / 2.0); + } else { + radiusAsInt = int(rect().height() / 2.0); + } + + QFont font(QApplication::font().family(), radiusAsInt / 10, QFont::Normal); + QFontMetrics fm(font); + const int targetWidth = fm.horizontalAdvance(m_targetTemperatureText); + const int wWidth = fm.horizontalAdvance('W'); + const int cursorWidth = fm.horizontalAdvance('0'); const int height = fm.height(); const int halfWidth = geometry().width() / 2; const int xposTarget = int(halfWidth - (targetWidth / 2)); - const int xposCurrent = int(halfWidth - (currentWidth / 2)); - const int xposName = halfWidth - (nameWidth / 2); const int xposCursor = xposTarget + (cursorWidth * m_cursorPos); int ypos = geometry().height() / 2 + height * 2; + const double relativePercent = m_maxValue - m_minValue; + const double targetTemperaturePercent = (m_targetTemperature - m_minValue) / relativePercent; + const double targetTemperatureAngle = (225 - -45) * targetTemperaturePercent + -45; + const int coolZone = int (- (targetTemperatureAngle - -45)); + const int qtBeginAngle = -135; + int PieYPos = geometry().height() / 2 - radiusAsInt; + int PieXPos = geometry().width() / 2 - radiusAsInt; + QPainter p(this); - QColor color = palette().color(QPalette::Text); + p.setFont(font); //draw a box to put our target into as a user hint. - p.fillRect(QRect(int(halfWidth - wWidth), int(ypos - (height * 0.66)), int(wWidth * 2), int(height * 0.9)), palette().color(QPalette::AlternateBase)); + p.fillRect(QRect(int(halfWidth - wWidth), int(ypos - (height * 1.2)), int(wWidth * 2), int(height * 0.8)), palette().color(QPalette::AlternateBase)); if (m_paintCursor) { p.setPen(palette().color(QPalette::Text)); - p.drawText(xposCursor, ypos, QChar('_')); + p.drawText(xposCursor, int(ypos - (height * 0.60)), QChar('_')); } p.setPen(Qt::red); - p.drawText(xposTarget, ypos, m_currentTemperatureTextFromEditor); - ypos += height + 2; - - p.setPen(color); - p.drawText(xposCurrent, ypos, QString::number(m_currentTemperature)); - - p.setPen(color); - if (size().height() <= height * 6.5 && innerRect().width() <= nameWidth * 4) { - p.drawText(xposName, 0 + height, m_name); - } else if (size().height() >= height * 8) { - p.drawText(xposName, ypos + height + 2, m_name); - } else { - p.drawText(xposName, geometry().height() / 2 - 12, m_name); - } -} - -void ThermoWidget::drawNeedle(QPainter *painter, const QPointF ¢er, double radius, double dir, QPalette::ColorGroup colorGroup) const -{ - Q_UNUSED(dir); - //save a copy of radius as int to avoid casting it several times. - int radiusAsInt = int(radius); - const double relativePercent = upperBound() - lowerBound(); - const double currentTemperaturePercent = (m_currentTemperature - lowerBound()) / relativePercent; - const double targetTemperaturePercent = (m_targetTemperature - lowerBound()) / relativePercent; - const double currentTemperatureAngle = (maxScaleArc() - minScaleArc()) * currentTemperaturePercent + minScaleArc(); - const double targetTemperatureAngle = (maxScaleArc() - minScaleArc()) * targetTemperaturePercent + minScaleArc(); - // Qt coordinates and Qwt coordinates differ. - // the "begin" of our coordinates in Qt: -130 - // the "span" of our coordinates in Qt: -180 - // Negative values means clockwise in Qt dialect. - const int qtBeginAngle = -130; - const int coolZone = int (- (targetTemperatureAngle - minScaleArc())); - int yPos = geometry().height() / 2 - radiusAsInt; - int xPos = geometry().width() / 2 - radiusAsInt; - - QRadialGradient grad(center, radius); - grad.setColorAt(0.75, QColor(0, 0, 0, 0)); - grad.setColorAt(0.85, QColor(255, 0, 0, 196)); - grad.setColorAt(0.95, QColor(255, 110, 60, 196)); - - painter->setBrush(grad); - painter->drawPie(xPos, yPos, radiusAsInt * 2, radiusAsInt * 2, qtBeginAngle * 16, coolZone * 16); - - m_targetTemperatureNeedle->draw(painter, center, radius * 1.3, 360 - targetTemperatureAngle - origin(), colorGroup); - m_currentTemperatureNeedle->draw(painter, center, radius, 360 - currentTemperatureAngle - origin(), colorGroup); -} - -void ThermoWidget::setCurrentTemperature(double temperature) -{ - if (!isEqual(m_currentTemperature, temperature)) { - m_currentTemperature = temperature; - update(); - } -} + p.drawText(xposTarget, int(ypos - (height * 0.60)), m_targetTemperatureText); -void ThermoWidget::setTargetTemperature(int temperature) -{ - if (m_targetTemperature != temperature) { - m_currentTemperatureTextFromEditor = QString::number(temperature); - m_targetTemperature = temperature; - resetTimer(); - update(); - } -} + QRadialGradient grad(rect().center(), radiusAsInt); + grad.setColorAt(0.35, QColor(0, 0, 0, 0)); + grad.setColorAt(0.45, QColor(255, 110, 60, 96)); + grad.setColorAt(0.55, QColor(255, 0, 0, 96)); + grad.setColorAt(0.70, QColor(0, 0, 0, 0)); + p.setPen(Qt::transparent); + p.setBrush(grad); + p.drawPie(PieXPos, PieYPos, radiusAsInt * 2, radiusAsInt * 2, qtBeginAngle * 16, coolZone * 16); -void ThermoWidget::resetTimer() -{ - m_tempChangedTimer->start(500); } bool ThermoWidget::isEqual(double a, double b) { //qFuzzyCompare always returns false if a || b ==0 if (qFuzzyIsNull(a) || qFuzzyIsNull(b)) { if (a < 0.0 || b < 0.0) { //One number is 0 and the other negative //to prevent a issue if a or b == -1 and the other 0 //we will subtract one from each value a -= 1; b -= 1; } else { a += 1; b += 1; } } return qFuzzyCompare(a, b); } diff --git a/src/widgets/thermowidget.h b/src/widgets/thermowidget.h index e0786ea..1d74ccb 100644 --- a/src/widgets/thermowidget.h +++ b/src/widgets/thermowidget.h @@ -1,67 +1,66 @@ /* Atelier KDE Printer Host for 3D Printing - Copyright (C) <2018> + Copyright (C) <2019> Author: Tomaz Canabrava - tcanabrava@kde.org Chris Rizzitello - rizzitello@kde.org Lays Rodrigues - lays.rodrigues@kde.org 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 . */ #pragma once - -#include -#include +#include "qcgaugewidget.h" class QKeyEvent; class QPaintEvent; class QFocusEvent; class QWheelEvent; -class ThermoWidget : public QwtDial +class ThermoWidget : public QcGaugeWidget { Q_OBJECT - public: ThermoWidget(QWidget *parent, const QString &name); - ~ThermoWidget() = default; - - void drawNeedle(QPainter *painter, const QPointF ¢er, - double radius, double dir, QPalette::ColorGroup colorGroup) const override; - + ~ThermoWidget() override = default; void setCurrentTemperature(double temperature); void setTargetTemperature(int temperature); + void setRange(int min, int max); + void setName(const QString &name); signals: void targetTemperatureChanged(double targetTemperature); - protected: + void keyPressEvent(QKeyEvent *event) override; + void wheelEvent(QWheelEvent *event) override; void focusInEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; void paintEvent(QPaintEvent *event) override; - void wheelEvent(QWheelEvent *event) override; private: - bool isEqual(double a = 0, double b = 0); - QwtDialSimpleNeedle *m_currentTemperatureNeedle; - QwtDialSimpleNeedle *m_targetTemperatureNeedle; - QString m_currentTemperatureTextFromEditor = QString("-"); - QString m_name; + QcNeedleItem *m_currentTemperatureNeedle = nullptr; + QcNeedleItem *m_targetTemperatureNeedle = nullptr; + QcDegreesItem *m_ticksItem = nullptr; + QcDegreesItem *m_subTicksItem = nullptr; + QcLabelItem *m_nameLabel = nullptr; + QcValuesItem *m_valueDisplay = nullptr; QTimer *m_cursorTimer = nullptr; QTimer *m_tempChangedTimer = nullptr; + QString m_targetTemperatureText = QStringLiteral("0"); bool m_paintCursor = false; int m_cursorPos = 0; double m_currentTemperature; int m_targetTemperature; + int m_maxValue = 100; + int m_minValue = 0; void resetTimer(); + bool isEqual(double a = 0, double b = 0); };