fix: elide user notes (#6318)
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user