diff --git a/src/Train/DialWindow.cpp b/src/Train/DialWindow.cpp index 066978d60..cff3d5ae7 100644 --- a/src/Train/DialWindow.cpp +++ b/src/Train/DialWindow.cpp @@ -80,7 +80,10 @@ DialWindow::DialWindow(Context *context) : QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(0); layout->setContentsMargins(3,3,3,3); - valueLabel = new QLabel(this); + valueLabel = new ScalingLabel(this); + QFont vlFont = valueLabel->font(); + vlFont.setWeight(QFont::Bold); + valueLabel->setFont(vlFont); valueLabel->setAlignment(Qt::AlignCenter | Qt::AlignVCenter); layout->addWidget(valueLabel); setChartLayout(layout); @@ -99,9 +102,6 @@ DialWindow::DialWindow(Context *context) : // setup colors seriesChanged(); - // setup fontsize etc - resizeEvent(NULL); - // set to zero resetValues(); } @@ -546,21 +546,6 @@ DialWindow::telemetryUpdate(const RealtimeData &rtData) } } -void DialWindow::resizeEvent(QResizeEvent * ) -{ - QFont font; - - // set point size within reasonable limits for low dpi screens - int size = (geometry().height() - 24) * 72 / logicalDpiY(); - if (size <= 0) size = 4; - if (size >= 64) size = 64; - - font.setPointSize(size); - - font.setWeight(QFont::Bold); - valueLabel->setFont(font); -} - void DialWindow::seriesChanged() { // we got some! diff --git a/src/Train/DialWindow.h b/src/Train/DialWindow.h index a21caa5f1..e49a3d0fd 100644 --- a/src/Train/DialWindow.h +++ b/src/Train/DialWindow.h @@ -26,6 +26,8 @@ #include #include +#include "ScalingLabel.h" + #include "Context.h" #include "Zones.h" // for data series types #include "RideFile.h" // for data series types @@ -74,9 +76,6 @@ class DialWindow : public GcChartWindow int style() const { return _style; } int avgSecs() const { return average; } - // change font as window resizes - void resizeEvent(QResizeEvent *); - public slots: // trap signals @@ -148,7 +147,7 @@ class DialWindow : public GcChartWindow QLineEdit *averageEdit; // display - QLabel *valueLabel; + ScalingLabel *valueLabel; QColor foreground, background; diff --git a/src/Train/ScalingLabel.cpp b/src/Train/ScalingLabel.cpp new file mode 100644 index 000000000..654f61165 --- /dev/null +++ b/src/Train/ScalingLabel.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2022 Joachim Kohlhammer (joachim.kohlhammer@gmx.de) + * + * 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 2 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, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ScalingLabel.h" + +#include + + +ScalingLabel::ScalingLabel +(QWidget *parent, Qt::WindowFlags f) +: ScalingLabel(4, 64, parent, f) +{ +} + + + +ScalingLabel::ScalingLabel +(int minFontPointSize, int maxFontPointSize, QWidget *parent, Qt::WindowFlags f) +: QLabel(parent, f), minFontPointSize(minFontPointSize), maxFontPointSize(maxFontPointSize) +{ + QFont fnt = font(); + fnt.setPointSize(minFontPointSize); + QLabel::setFont(fnt); +} + + +ScalingLabel::~ScalingLabel +() +{ +} + + +void +ScalingLabel::resizeEvent +(QResizeEvent *evt) +{ + Q_UNUSED(evt); + scaleFont(text(), ScalingLabelReason::ResizeEvent); +} + + +void +ScalingLabel::setText +(const QString &text) +{ + ++counter; + if (text.length() > QLabel::text().length()) { + scaleFont(text, ScalingLabelReason::TextLengthChanged); + } else if (counter > 10) { + scaleFont(text, ScalingLabelReason::CounterExceeded); + } + QLabel::setText(text); +} + + +void +ScalingLabel::setFont +(const QFont &font) +{ + if (! scaleFont(text(), font, ScalingLabelReason::FontChanged)) { + QLabel::setFont(font); + } +} + + +int +ScalingLabel::getMinFontPointSize +() const +{ + return minFontPointSize; +} + + +void +ScalingLabel::setMinFontPointSize +(int size) +{ + minFontPointSize = size; +} + + +int +ScalingLabel::getMaxFontPointSize +() const +{ + return maxFontPointSize; +} + + +void +ScalingLabel::setMaxFontPointSize +(int size) +{ + maxFontPointSize = size; +} + + +bool +ScalingLabel::isLinear +() const +{ + return linear; +} + + +void +ScalingLabel::setLinear +(bool linear) +{ + this->linear = linear; +} + + +bool +ScalingLabel::scaleFont +(const QString &text, ScalingLabelReason reason) +{ + return scaleFont(text, font(), reason); +} + + +bool +ScalingLabel::scaleFont +(const QString &text, const QFont &font, ScalingLabelReason reason) +{ + counter = 0; + if (linear) { + return scaleFontLinear(text, font, reason); + } else { + return scaleFontExact(text, font, reason); + } +} + + +bool +ScalingLabel::scaleFontExact +(const QString &text, const QFont &font, ScalingLabelReason reason) +{ + int size = maxFontPointSize + 1; + if (reason == ScalingLabelReason::CounterExceeded) { + size = font.pointSize() + 1; + } + QFont f(font); + QRect br; + do { + f.setPointSize(--size); + QFontMetrics fm = QFontMetrics(f, this); + br = fm.boundingRect(text); + } while (size >= minFontPointSize && (br.width() > width() || br.height() > height())); + QLabel::setFont(f); + return true; +} + + +bool +ScalingLabel::scaleFontLinear +(const QString &text, const QFont &font, ScalingLabelReason reason) +{ + if (text.length() == 0 || width() <= 0 || height() <= 0) { + return false; + } + int maxSize = maxFontPointSize; + if (reason == ScalingLabelReason::CounterExceeded) { + maxSize = font.pointSize(); + } + QFont f(font); + f.setPointSize(minFontPointSize); + QFontMetrics fmS = QFontMetrics(f, this); + f.setPointSize(maxSize); + QFontMetrics fmL = QFontMetrics(f, this); + QRect brS = fmS.boundingRect(text); + QRect brL = fmL.boundingRect(text); + int sizeWidth = (maxSize - minFontPointSize) / float(brL.width() - brS.width()) * width(); + int sizeHeight = (maxSize - minFontPointSize) / float(brL.height() - brS.height()) * height(); + int calcSize = std::min(sizeWidth, sizeHeight); + f.setPointSize(std::max(std::min(calcSize, maxSize), minFontPointSize)); + QLabel::setFont(f); + return true; +} diff --git a/src/Train/ScalingLabel.h b/src/Train/ScalingLabel.h new file mode 100644 index 000000000..6b6dcaa16 --- /dev/null +++ b/src/Train/ScalingLabel.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Joachim Kohlhammer (joachim.kohlhammer@gmx.de) + * + * 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 2 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, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _GC_ScalingLabel_h +#define _GC_ScalingLabel_h 1 + +#include + +enum class ScalingLabelReason : uint8_t { + TextLengthChanged, + FontChanged, + ResizeEvent, + CounterExceeded +}; + +class ScalingLabel : public QLabel +{ + Q_OBJECT + Q_PROPERTY(int minFontPointSize READ getMinFontPointSize WRITE setMinFontPointSize USER false) + Q_PROPERTY(int maxFontPointSize READ getMaxFontPointSize WRITE setMaxFontPointSize USER false) + Q_PROPERTY(bool linear READ isLinear WRITE setLinear USER false) + + public: + ScalingLabel(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); + ScalingLabel(int minFontPointSize, int maxFontPointSize, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); + virtual ~ScalingLabel(); + + virtual void resizeEvent(QResizeEvent *evt); + virtual void setFont(const QFont &font); + + int getMinFontPointSize() const; + int getMaxFontPointSize() const; + bool isLinear() const; + + public slots: + void setText(const QString &text); + void setMinFontPointSize(int size); + void setMaxFontPointSize(int size); + void setLinear(bool linear); + + private: + bool scaleFont(const QString &text, const QFont &font, ScalingLabelReason reason); + bool scaleFont(const QString &text, ScalingLabelReason reason); + bool scaleFontExact(const QString &text, const QFont &font, ScalingLabelReason reason); + bool scaleFontLinear(const QString &text, const QFont &font, ScalingLabelReason reason); + + int minFontPointSize; + int maxFontPointSize; + bool linear = true; + int counter = 0; +}; + +#endif diff --git a/src/src.pro b/src/src.pro index c38b52f40..0f57df479 100644 --- a/src/src.pro +++ b/src/src.pro @@ -699,7 +699,8 @@ HEADERS += Train/AddDeviceWizard.h Train/CalibrationData.h Train/ComputrainerCon HEADERS += Train/TrainBottom.h Train/TrainDB.h Train/TrainSidebar.h \ Train/VideoLayoutParser.h Train/VideoSyncFile.h Train/WorkoutPlotWindow.h Train/WebPageWindow.h \ Train/WorkoutWidget.h Train/WorkoutWidgetItems.h Train/WorkoutWindow.h Train/WorkoutWizard.h Train/ZwoParser.h \ - Train/LiveMapWebPageWindow.h + Train/LiveMapWebPageWindow.h \ + Train/ScalingLabel.h ###============= @@ -803,7 +804,8 @@ SOURCES += Train/AddDeviceWizard.cpp Train/CalibrationData.cpp Train/Computraine SOURCES += Train/TrainBottom.cpp Train/TrainDB.cpp Train/TrainSidebar.cpp \ Train/VideoLayoutParser.cpp Train/VideoSyncFile.cpp Train/WorkoutPlotWindow.cpp Train/WebPageWindow.cpp \ Train/WorkoutWidget.cpp Train/WorkoutWidgetItems.cpp Train/WorkoutWindow.cpp Train/WorkoutWizard.cpp Train/ZwoParser.cpp \ - Train/LiveMapWebPageWindow.cpp + Train/LiveMapWebPageWindow.cpp \ + Train/ScalingLabel.cpp ## Crash Handling win32-msvc* {