fix: elide user notes (#6318)

This commit is contained in:
pajlada
2025-07-12 13:20:05 +02:00
committed by GitHub
parent fba845f978
commit 49aa83244c
5 changed files with 130 additions and 38 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
## Unversioned ## Unversioned
- Minor: Added user notes to the user info dialog (when clicking a username). (#6122) - Minor: Added user notes to the user info dialog (when clicking a username). (#6122, #6318)
- Minor: Added cached emotes fallback when fetching from a provider fails. (#6125, #6229) - Minor: Added cached emotes fallback when fetching from a provider fails. (#6125, #6229)
- Minor: Add an option for the reduced opacity of message history. (#6121) - Minor: Add an option for the reduced opacity of message history. (#6121)
- Minor: Make paused chat indicator more visible, and fix its zoom behavior. (#6123) - Minor: Make paused chat indicator more visible, and fix its zoom behavior. (#6123)
+97 -25
View File
@@ -33,6 +33,11 @@ void Label::setText(const QString &text)
if (this->text_ != text) if (this->text_ != text)
{ {
this->text_ = text; this->text_ = text;
if (this->shouldElide_)
{
this->updateElidedText(this->getFontMetrics(),
this->getInnerWidth());
}
this->updateSize(); this->updateSize();
this->update(); this->update();
} }
@@ -54,14 +59,9 @@ void Label::setCentered(bool centered)
this->updateSize(); this->updateSize();
} }
bool Label::getHasOffset() const void Label::setHasPadding(bool hasPadding)
{ {
return this->hasOffset_; this->hasPadding_ = hasPadding;
}
void Label::setHasOffset(bool hasOffset)
{
this->hasOffset_ = hasOffset;
this->updateSize(); this->updateSize();
} }
@@ -76,42 +76,59 @@ void Label::setWordWrap(bool wrap)
this->update(); this->update();
} }
void Label::setShouldElide(bool shouldElide)
{
this->shouldElide_ = shouldElide;
this->updateSize();
this->update();
}
void Label::setFontStyle(FontStyle style) void Label::setFontStyle(FontStyle style)
{ {
this->fontStyle_ = style; this->fontStyle_ = style;
this->updateSize(); this->updateSize();
} }
void Label::scaleChangedEvent(float scale) void Label::scaleChangedEvent(float /*scale*/)
{ {
this->updateSize(); this->updateSize();
} }
QSize Label::sizeHint() const QSize Label::sizeHint() const
{ {
return this->preferedSize_; return this->sizeHint_;
} }
QSize Label::minimumSizeHint() const QSize Label::minimumSizeHint() const
{ {
return this->preferedSize_; return this->minimumSizeHint_;
} }
void Label::paintEvent(QPaintEvent *) void Label::paintEvent(QPaintEvent * /*event*/)
{ {
QPainter painter(this); QPainter painter(this);
auto metrics = getApp()->getFonts()->getFontMetrics(this->getFontStyle(), auto metrics = this->getFontMetrics();
this->scale());
painter.setFont( painter.setFont(
getApp()->getFonts()->getFont(this->getFontStyle(), this->scale())); getApp()->getFonts()->getFont(this->getFontStyle(), this->scale()));
int offset = this->getOffset(); int padding = this->getPadding();
// draw text // draw text
QRect textRect(offset, 0, this->width() - offset - offset, this->height()); QRect textRect(this->getPadding(), 0,
static_cast<int>(this->getInnerWidth()), this->height());
int width = static_cast<int>(metrics.horizontalAdvance(this->text_)); auto text = [this] {
if (this->shouldElide_)
{
return this->elidedText_;
}
return this->text_;
}();
int width = static_cast<int>(metrics.horizontalAdvance(text));
Qt::Alignment alignment = !this->centered_ || width > textRect.width() Qt::Alignment alignment = !this->centered_ || width > textRect.width()
? Qt::AlignLeft | Qt::AlignVCenter ? Qt::AlignLeft | Qt::AlignVCenter
: Qt::AlignCenter; : Qt::AlignCenter;
@@ -127,7 +144,7 @@ void Label::paintEvent(QPaintEvent *)
{ {
option.setWrapMode(QTextOption::NoWrap); option.setWrapMode(QTextOption::NoWrap);
} }
painter.drawText(textRect, this->text_, option); painter.drawText(textRect, text, option);
#if 0 #if 0
painter.setPen(QColor(255, 0, 0)); painter.setPen(QColor(255, 0, 0));
@@ -135,22 +152,77 @@ void Label::paintEvent(QPaintEvent *)
#endif #endif
} }
void Label::resizeEvent(QResizeEvent *event)
{
if (this->shouldElide_)
{
auto metrics = this->getFontMetrics();
if (this->updateElidedText(metrics, this->getInnerWidth()))
{
this->update();
}
}
BaseWidget::resizeEvent(event);
}
QFontMetricsF Label::getFontMetrics() const
{
return getApp()->getFonts()->getFontMetrics(this->fontStyle_,
this->scale());
}
qreal Label::getInnerWidth() const
{
return this->width() - (2 * this->getPadding());
}
void Label::updateSize() void Label::updateSize()
{ {
auto metrics = auto metrics = this->getFontMetrics();
getApp()->getFonts()->getFontMetrics(this->fontStyle_, this->scale());
auto width = if (this->shouldElide_)
metrics.horizontalAdvance(this->text_) + (2 * this->getOffset()); {
auto height = metrics.height(); auto height = metrics.height();
this->preferedSize_ = QSizeF(width, height).toSize(); this->updateElidedText(metrics, this->getInnerWidth());
this->sizeHint_ = QSizeF(-1, height).toSize();
this->minimumSizeHint_ = this->sizeHint_;
}
else
{
auto width =
metrics.horizontalAdvance(this->text_) + (2 * this->getPadding());
auto height = metrics.height();
this->sizeHint_ = QSizeF(width, height).toSize();
this->minimumSizeHint_ = this->sizeHint_;
}
this->updateGeometry(); this->updateGeometry();
} }
int Label::getOffset() int Label::getPadding() const
{ {
return this->hasOffset_ ? int(8 * this->scale()) : 0; if (this->hasPadding_)
{
return static_cast<int>(8 * this->scale());
}
return 0;
}
bool Label::updateElidedText(const QFontMetricsF &fontMetrics, qreal width)
{
assert(this->shouldElide_ == true);
auto elidedText = fontMetrics.elidedText(
this->text_, Qt::TextElideMode::ElideRight, width);
if (elidedText != this->elidedText_)
{
this->elidedText_ = elidedText;
return true;
}
return false;
} }
} // namespace chatterino } // namespace chatterino
+29 -5
View File
@@ -5,6 +5,8 @@
#include <pajlada/signals/signalholder.hpp> #include <pajlada/signals/signalholder.hpp>
class QFontMetricsF;
namespace chatterino { namespace chatterino {
class Label : public BaseWidget class Label : public BaseWidget
@@ -24,29 +26,51 @@ public:
bool getCentered() const; bool getCentered() const;
void setCentered(bool centered); void setCentered(bool centered);
bool getHasOffset() const; /// Enable or disable horizontal padding
void setHasOffset(bool hasOffset); void setHasPadding(bool hasPadding);
bool getWordWrap() const; bool getWordWrap() const;
void setWordWrap(bool wrap); void setWordWrap(bool wrap);
/// Sets whether the text should elide if there's not enough room to
/// render the current text.
void setShouldElide(bool shouldElide);
protected: protected:
void scaleChangedEvent(float scale_) override; void scaleChangedEvent(float scale_) override;
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
void resizeEvent(QResizeEvent *event) override;
QSize sizeHint() const override; QSize sizeHint() const override;
QSize minimumSizeHint() const override; QSize minimumSizeHint() const override;
private: private:
void updateSize(); void updateSize();
int getOffset();
/// Returns the horizontal padding, or 0 if hasPadding_ is false
int getPadding() const;
/// Returns the current font style's font metric based on the current scale.
QFontMetricsF getFontMetrics() const;
/// Returns the width of this content without padding
qreal getInnerWidth() const;
/// Calculate the new elided text based on text_
///
/// Return true if the elided text changed
bool updateElidedText(const QFontMetricsF &fontMetrics, qreal width);
QString text_; QString text_;
FontStyle fontStyle_; FontStyle fontStyle_;
QSize preferedSize_; QSize sizeHint_;
QSize minimumSizeHint_;
bool centered_ = false; bool centered_ = false;
bool hasOffset_ = true; bool hasPadding_ = true;
bool wordWrap_ = false; bool wordWrap_ = false;
bool shouldElide_ = false;
/// The text, but elided. Only set if shouldElide_ is true
QString elidedText_;
pajlada::Signals::SignalHolder connections_; pajlada::Signals::SignalHolder connections_;
}; };
+2 -6
View File
@@ -56,7 +56,6 @@ constexpr QStringView TEXT_UNAVAILABLE = u"(not available)";
constexpr QStringView TEXT_PRONOUNS = u"Pronouns: %1"; constexpr QStringView TEXT_PRONOUNS = u"Pronouns: %1";
constexpr QStringView TEXT_UNSPECIFIED = u"(unspecified)"; constexpr QStringView TEXT_UNSPECIFIED = u"(unspecified)";
constexpr QStringView TEXT_LOADING = u"(loading...)"; constexpr QStringView TEXT_LOADING = u"(loading...)";
constexpr qsizetype NOTES_PREVIEW_LENGTH = 80;
using namespace chatterino; using namespace chatterino;
@@ -490,6 +489,7 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, Split *split)
auto notesPreview = layout.emplace<Label>().assign(&ui_.notesPreview); auto notesPreview = layout.emplace<Label>().assign(&ui_.notesPreview);
notesPreview->setVisible(false); notesPreview->setVisible(false);
notesPreview->setShouldElide(true);
auto lineMod = layout.emplace<Line>(false); auto lineMod = layout.emplace<Line>(false);
@@ -1143,10 +1143,6 @@ void UserInfoPopup::updateNotes()
static QRegularExpression spaceRegex{"\\s+"}; static QRegularExpression spaceRegex{"\\s+"};
auto previewText = "Notes: " + userData->notes.replace(spaceRegex, " "); auto previewText = "Notes: " + userData->notes.replace(spaceRegex, " ");
if (previewText.length() > NOTES_PREVIEW_LENGTH)
{
previewText = previewText.left(NOTES_PREVIEW_LENGTH - 3) + "...";
}
this->ui_.notesPreview->setText(previewText); this->ui_.notesPreview->setText(previewText);
this->ui_.notesPreview->setVisible(true); this->ui_.notesPreview->setVisible(true);
@@ -1173,7 +1169,7 @@ UserInfoPopup::TimeoutWidget::TimeoutWidget()
title->addStretch(1); title->addStretch(1);
auto label = title.emplace<Label>(text); auto label = title.emplace<Label>(text);
label->setStyleSheet("color: #BBB"); label->setStyleSheet("color: #BBB");
label->setHasOffset(false); label->setHasPadding(false);
title->addStretch(1); title->addStretch(1);
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin(); auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
+1 -1
View File
@@ -290,7 +290,7 @@ void SplitHeader::initializeLayout()
w->setSizePolicy(QSizePolicy::MinimumExpanding, w->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::Preferred); QSizePolicy::Preferred);
w->setCentered(true); w->setCentered(true);
w->setHasOffset(false); w->setHasPadding(false);
}), }),
// space // space
makeWidget<BaseWidget>([](auto w) { makeWidget<BaseWidget>([](auto w) {