DialWindow: Scaling font in both dimensions (#4469)

Currently the font in DialWindow is only scaled to make the text fit
into the label vertically. This commit scales the font in both
dimensions and prevents cutting off the content.

The font is rescaled
* If the DialWindow itself is resized
* If the text set and is longer than the previous one
* Every 10 text-changes
This commit is contained in:
Joachim Kohlhammer
2024-05-07 01:40:16 +02:00
committed by GitHub
parent f97770fa94
commit 63a14d0edf
5 changed files with 273 additions and 25 deletions

View File

@@ -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!

View File

@@ -26,6 +26,8 @@
#include <QLineEdit>
#include <QFormLayout>
#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;

194
src/Train/ScalingLabel.cpp Normal file
View File

@@ -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 <QDebug>
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<int>(sizeWidth, sizeHeight);
f.setPointSize(std::max<int>(std::min<int>(calcSize, maxSize), minFontPointSize));
QLabel::setFont(f);
return true;
}

68
src/Train/ScalingLabel.h Normal file
View File

@@ -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 <QLabel>
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

View File

@@ -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* {