-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add custom widget for speed button in the status bar #7427
Conversation
src/gui/statusspeedbutton.h
Outdated
public: | ||
StatusSpeedButton(QWidget *parent = nullptr); | ||
|
||
void setCurrentSpeed(quint64 currentSpeed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe joining these 3 into a single call would be better, because each of them calls QWidget::updateGeometry()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the current use POV it's better. But not from the abstract design POV. Although you can track appropriate value changes (ie. have cached value in your class and compare it with new one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although you can track appropriate value changes (ie. have cached value in your class and compare it with new one).
Incidentally, this will prevent unnecessary calculations for those values which are updated rarely (e.g. speed limits).
@LordNyriox: there is no need in that, I believe, because status bar will not provide updates in that case. |
@LordNyriox: thanks! Corrected. |
src/base/utils/misc.cpp
Outdated
QString numberPart; | ||
if (unit == SizeUnit::Byte) { | ||
numberPart = QString(QLatin1String("%1")).arg(bytesValue, fieldWidth, 10, fill); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coding style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coding style
src/gui/statusspeedbutton.cpp
Outdated
|
||
#include <QApplication> | ||
#include <QStylePainter> | ||
#include <QStyleOptionButton> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One up.
src/gui/statusspeedbutton.h
Outdated
* @brief Status bar button with speed text | ||
* | ||
*/ | ||
class StatusSpeedButton final: public QPushButton |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New rule: spaces around the colon.
FYI, StatusBar instance isn't created if it isn't showed and it is deleted when it becomes unused (unvisible from user POV). |
src/gui/statusbar.cpp
Outdated
@@ -69,23 +70,13 @@ StatusBar::StatusBar(QWidget *parent) | |||
.arg(tr("No direct connections. This may indicate network configuration problems."))); | |||
connect(m_connecStatusLblIcon, &QAbstractButton::clicked, this, &StatusBar::connectionButtonClicked); | |||
|
|||
m_dlSpeedLbl = new QPushButton(this); | |||
m_dlSpeedLbl = new StatusSpeedButton(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_dlSpeedLbl -> m_dlSpeedButton
src/gui/statusbar.cpp
Outdated
|
||
m_upSpeedLbl = new QPushButton(this); | ||
m_upSpeedLbl = new StatusSpeedButton(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_upSpeedLbl -> m_upSpeedButton
src/gui/statusspeedbutton.cpp
Outdated
#include "base/unicodestrings.h" | ||
#include "base/utils/misc.h" | ||
|
||
StatusSpeedButton::StatusSpeedButton(QWidget* parent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QWidget *parent
src/gui/statusspeedbutton.cpp
Outdated
} | ||
|
||
void StatusSpeedButton::updateSection(QStaticText §ion, quint64 bytes, bool isSpeed, | ||
int minMantissaDigits, const QString& templateText) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please realign all pointers and references.
src/gui/statusspeedbutton.h
Outdated
using base = QPushButton; | ||
|
||
public: | ||
StatusSpeedButton(QWidget *parent = nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explicit
void setSpeedLimit(int speedLimit); | ||
void setTotalPayload(quint64 totalPayload); | ||
|
||
protected: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protected is meaningless in final class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not final now.
src/gui/statusspeedbutton.h
Outdated
public: | ||
StatusSpeedButton(QWidget *parent = nullptr); | ||
|
||
void setCurrentSpeed(quint64 currentSpeed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the current use POV it's better. But not from the abstract design POV. Although you can track appropriate value changes (ie. have cached value in your class and compare it with new one).
src/gui/statusspeedbutton.h
Outdated
public: | ||
StatusSpeedButton(QWidget *parent = nullptr); | ||
|
||
void setCurrentSpeed(quint64 currentSpeed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although you can track appropriate value changes (ie. have cached value in your class and compare it with new one).
Incidentally, this will prevent unnecessary calculations for those values which are updated rarely (e.g. speed limits).
Review comments addressed. Thanks! |
src/gui/statusspeedbutton.cpp
Outdated
#include <QTextOption> | ||
|
||
#include "base/unicodestrings.h" | ||
#include "base/utils/misc.h" | ||
|
||
StatusSpeedButton::Section::Section(const QString& templateText, int minDigits, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const QString &templateText
src/gui/statusspeedbutton.cpp
Outdated
} | ||
} | ||
|
||
QStaticText StatusSpeedButton::emptyText() | ||
QChar StatusSpeedButton::widestDecimalDigit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add const
even used internally.
src/gui/statusspeedbutton.cpp
Outdated
res.setTextFormat(Qt::PlainText); | ||
res.setTextOption({Qt::AlignRight}); | ||
return res; | ||
const QString digits = QLocale().toString(1234567890); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why QLocale here, does it do anything special?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need localised digits as would be produced by QString::arg()
, but here I don't need the template string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand it now.
Not related to this PR, just my opinion, do you really expect to see a localized number string in the button? I mean I prefer plain number, commas or anything else for separator is redundant IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm weak in locale-related things. Just wanted to avoid any assumptions that might fail.
qreal maxWidth = 0.; | ||
QChar digit; | ||
QFontMetricsF fm {font(), this}; | ||
for (int i = 0; i < digits.size(); ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor thing, you can use range based for loop here.
Asking a naive question here: in git master code, what about recording the largest width of the speed limit button and set it every time when it updates, well... assuming the width size don't explode. |
I actually do exactly that for speed label, just allocate that space a bit in advance. But to get a stable position of the label (each of them), you also have to right-alight it. From there we are only a step away from the approach of this PR. Namely: should we try to predict the possible widest label or not. Perhaps we simply measure width of the unit strings (once on initialisation), select the widest and just allocate space for "1023.99 "? But that labels will look quite strangely spaced most of the time. |
Oh, thanks! Need to use left-alignment for them.
Agree with you. But can't help myself, want smooth UI so much :)
Here is a screen record, please: https://streamable.com/jhsqz
What QStyle do you use, please? I don't see anything like that. |
Let me experiment a little...
OK, thanks!
Fusion I guess. |
Wrong metric was used. Should be correct now. |
Do I correctly understand from your comments, that this PR contains too much of code and is too complicated for the task? |
Since a proportional font is used usually for GUI texts, the width of speed status labels can fluctuate significantly due to speed changes and digit variability. Because of that the download speed button jitters in the status bar from left to right, creating unpleasant visual experience. Here we replace it with a custom widget, that attempts to allocate constatn-sized placeholders for its text labels, thus eliminating the jitter.
When no limit is set there is a plenty of free space for both download and upload speeds. Simplest solution is to increase width for the labels and made it fixed (not dependent on content). |
@Chocobo1, @sledgehammer999, are we interested in this feature? (given the fact that the author has been inactive for a long time) |
IIRC I did still see some resizing quirks, although much less often. And I think the implementation is maybe a little bit too complex. |
As I said before the implementation is too complex for this job. |
Since a proportional font is used usually for GUI texts, the width
of speed status labels can fluctuate significantly due to speed changes
and digit variability. Because of that the download speed button jitters
in the status bar from left to right, creating unpleasant visual
experience.
Here we replace it with a custom widget, that attempts to allocate
constant-sized placeholders for its text labels, thus eliminating the
jitter.
Example of the problem: https://streamable.com/jhsqz