Browse Source

frontend: Improve VolumeName size calculations

Warchamp7 3 tuần trước cách đây
mục cha
commit
9236e4fba2

+ 62 - 17
frontend/components/VolumeName.cpp

@@ -26,6 +26,20 @@
 
 #include "moc_VolumeName.cpp"
 
+namespace {
+QString getPlainText(const QString &text)
+{
+	if (Qt::mightBeRichText(text)) {
+		QTextDocument doc;
+		doc.setHtml(text);
+
+		return doc.toPlainText();
+	}
+
+	return text;
+}
+} // namespace
+
 VolumeName::VolumeName(obs_source_t *source, QWidget *parent)
 	: QAbstractButton(parent),
 	  indicatorWidth(style()->pixelMetric(QStyle::PM_MenuButtonIndicator, nullptr, this))
@@ -39,6 +53,7 @@ VolumeName::VolumeName(obs_source_t *source, QWidget *parent)
 	setLayout(layout);
 
 	label = new QLabel(this);
+	label->setIndent(0);
 	layout->addWidget(label);
 
 	layout->setContentsMargins(0, 0, indicatorWidth, 0);
@@ -57,13 +72,15 @@ void VolumeName::setAlignment(Qt::Alignment alignment_)
 	}
 }
 
-QSize VolumeName::sizeHint() const
+QSize VolumeName::minimumSizeHint() const
 {
 	QStyleOptionButton opt;
 	opt.initFrom(this);
 
-	const QFontMetrics metrics(font());
-	QSize textSize = metrics.size(Qt::TextSingleLine, text());
+	QString plainText = getPlainText(fullText);
+
+	QFontMetrics metrics(label->font());
+	QSize textSize = metrics.size(Qt::TextSingleLine, plainText);
 
 	int width = textSize.width();
 	int height = textSize.height();
@@ -72,13 +89,32 @@ QSize VolumeName::sizeHint() const
 		height = std::max(height, indicatorWidth);
 	}
 
-	const int spacing = style()->pixelMetric(QStyle::PM_ButtonMargin, &opt, this) / 2;
-	width += indicatorWidth + spacing;
-
 	QSize contentsSize = style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(width, height), this);
+
+	contentsSize.rwidth() += indicatorWidth;
+
 	return contentsSize;
 }
 
+QSize VolumeName::sizeHint() const
+{
+	QString plainText = getPlainText(fullText);
+
+	QFontMetrics metrics(label->font());
+
+	int textWidth = metrics.horizontalAdvance(plainText);
+	int textHeight = metrics.height();
+
+	int width = textWidth + indicatorWidth;
+
+	// Account for label margins if needed
+	QMargins margins = label->contentsMargins();
+	width += margins.left() + margins.right();
+	int height = textHeight + margins.top() + margins.bottom();
+
+	return QSize(width, height);
+}
+
 void VolumeName::obsSourceRenamed(void *data, calldata_t *params)
 {
 	VolumeName *widget = static_cast<VolumeName *>(data);
@@ -139,27 +175,36 @@ void VolumeName::onRenamed(QString name)
 void VolumeName::setText(const QString &text)
 {
 	QAbstractButton::setText(text);
+	updateGeometry();
 	updateLabelText(text);
 }
 
 void VolumeName::updateLabelText(const QString &name)
 {
-	QString plainText = name;
-	// Handle source names that use rich text.
-	if (name.contains("<") && name.contains(">")) {
-		QTextDocument doc;
-		doc.setHtml(name);
+	QString plainText = getPlainText(name);
+
+	QFontMetrics metrics(label->font());
 
-		plainText = doc.toPlainText();
+	int availableWidth = label->contentsRect().width();
+	if (availableWidth <= 0) {
+		label->clear();
+		fullText = name;
+		return;
 	}
 
-	QFontMetrics metrics(label->font());
-	QString elidedText = metrics.elidedText(plainText, Qt::ElideMiddle, width() - indicatorWidth * 2);
+	int textWidth = metrics.horizontalAdvance(plainText);
+
+	bool isRichText = (plainText != name);
+	bool needsElide = textWidth > availableWidth;
 
-	bool useElidedText = metrics.boundingRect(plainText).width() > width() - indicatorWidth;
+	if (needsElide && !isRichText) {
+		QString elided = metrics.elidedText(plainText, Qt::ElideMiddle, availableWidth);
+		label->setText(elided);
+	} else {
+		label->setText(name);
+	}
 
-	bool isRichText = name != plainText;
-	label->setText(useElidedText && !isRichText ? elidedText : name);
+	fullText = name;
 }
 
 void VolumeName::onRemoved()

+ 2 - 0
frontend/components/VolumeName.hpp

@@ -29,6 +29,7 @@ class VolumeName : public QAbstractButton {
 
 	QPointer<QLabel> label{};
 	int indicatorWidth;
+	QString fullText{};
 
 public:
 	VolumeName(obs_source_t *source, QWidget *parent = nullptr);
@@ -37,6 +38,7 @@ public:
 	void setAlignment(Qt::Alignment alignment);
 	Qt::Alignment alignment() const { return textAlignment; }
 
+	QSize minimumSizeHint() const override;
 	QSize sizeHint() const override;
 
 	void updateLabelText(const QString &name);

+ 8 - 4
frontend/data/themes/Yami.obt

@@ -1733,7 +1733,7 @@ VolumeMeter {
 
 VolumeName {
     background: transparent;
-    padding: var(--padding_base);
+    padding: var(--padding_base) 0;
     border: 1px solid transparent;
 }
 
@@ -1771,12 +1771,16 @@ VolumeControl #volLabel {
     border-radius: var(--border_radius);
 }
 
+#hVolumeWidgets VolumeName {
+    padding-right: var(--padding_large);
+}
+
 #hVolumeWidgets VolumeName QLabel {
-    margin: 0px var(--spacing_base) var(--spacing_base);
+    margin: 0 var(--padding_large);
 }
 
 #hVolumeWidgets #volLabel {
-    margin: var(--spacing_base);
+    margin: 0 var(--spacing_base);
     border-radius: var(--border_radius);
 }
 
@@ -1794,7 +1798,7 @@ VolumeControl #volLabel {
 }
 
 #hVolumeWidgets VolumeControl QPushButton {
-    margin-left: var(--padding_xlarge);
+    margin-left: var(--padding_large);
 }
 
 #hVolumeWidgets VolumeControl #volMeterFrame {