diff src/gui/widgets/text.cc @ 365:f81bed4e04ac

*: megacommit that probably breaks things
author Paper <paper@paper.us.eu.org>
date Wed, 02 Oct 2024 23:06:43 -0400
parents 6b0768158dcd
children
line wrap: on
line diff
--- a/src/gui/widgets/text.cc	Tue Jul 16 21:15:59 2024 -0400
+++ b/src/gui/widgets/text.cc	Wed Oct 02 23:06:43 2024 -0400
@@ -9,6 +9,7 @@
 #include <QVBoxLayout>
 #include <QScrollArea>
 #include <QDebug>
+#include <QPainter>
 
 namespace TextWidgets {
 
@@ -16,8 +17,8 @@
 
 Header::Header(QWidget* parent)
 	: QWidget(parent)
-	, title_(new QLabel(this))
-	, separator_(new QFrame(this)) {
+	, title_(new QLabel)
+	, separator_(new QFrame) {
 	QVBoxLayout* layout = new QVBoxLayout(this);
 	setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
 
@@ -44,6 +45,69 @@
 	updateGeometry();
 }
 
+Label::Label(QWidget *parent) : QLabel(parent) {}
+Label::Label(const QString &string, QWidget *parent) : QLabel(string, parent) {}
+
+void Label::SetElidingMode(bool elide) {
+	elide_ = elide;
+	update();
+}
+
+void Label::paintEvent(QPaintEvent *event) {
+	if (elide_) {
+		/* bruh */
+		if (wordWrap()) {
+			QFrame::paintEvent(event);
+
+			const QString content = text();
+
+		    QPainter painter(this);
+		    QFontMetrics fontMetrics = painter.fontMetrics();
+
+		    bool didElide = false;
+		    int lineSpacing = fontMetrics.lineSpacing();
+		    int y = 0;
+
+		    QTextLayout textLayout(content, painter.font());
+		    textLayout.beginLayout();
+		    for (;;) {
+		        QTextLine line = textLayout.createLine();
+
+		        if (!line.isValid())
+		            break;
+
+		        line.setLineWidth(width());
+		        int nextLineY = y + lineSpacing;
+
+		        if (height() >= nextLineY + lineSpacing) {
+		            line.draw(&painter, QPoint(0, y));
+		            y = nextLineY;
+				} else {
+					QString lastLine = content.mid(line.textStart());
+					QString elidedLastLine = fontMetrics.elidedText(lastLine, Qt::ElideRight, width());
+					painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLastLine);
+					line = textLayout.createLine();
+					didElide = line.isValid();
+					break;
+				}
+			}
+			textLayout.endLayout();
+		} else {
+			QString backup_text = QLabel::text();
+
+			QFontMetrics metric(fontMetrics());
+			QString elided_text = metric.elidedText(backup_text, Qt::ElideRight, width());
+
+			QLabel::setText(elided_text);
+			QLabel::paintEvent(event);
+			QLabel::setText(backup_text);
+		}
+	} else {
+		/* QLabel can handle everything... */
+		QLabel::paintEvent(event);
+	}
+}
+
 /* ---------------------------------------------------------------------------------- */
 /* "Paragraph" widgets, as in widgets meant to hold a bunch of text. */
 
@@ -111,8 +175,8 @@
 
 	data_.reserve(data.size());
 	for (std::size_t i = 0; i < data.size(); i++) {
-		QSharedPointer<QLabel> first(new QLabel);
-		QSharedPointer<QLabel> second(new QLabel);
+		QSharedPointer<Label> first(new Label);
+		QSharedPointer<Label> second(new Label);
 
 		first->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
 
@@ -121,7 +185,7 @@
 
 		data_.push_back({first, second});
 
-		contents_layout_->addWidget(first.data(), i, 0);
+		contents_layout_->addWidget(first.data(),  i, 0);
 		contents_layout_->addWidget(second.data(), i, 1);
 	}
 }
@@ -131,7 +195,12 @@
 	for (auto& [label, data] : data_)
 		label->setStyleSheet(style_sheet);
 
-	// TODO ElidedData
+	if (style & LabelledParagraph::ElidedData) {
+		for (auto& [label, data] : data_) {
+			data->setWordWrap(false);
+			data->SetElidingMode(true);
+		}
+	}
 }
 
 } // namespace TextWidgets