Mercurial > minori
comparison src/gui/widgets/text.cc @ 370:ea3a74ed2ef9
*: hm, last commit wasn't quite finished?
author | Paper <paper@tflc.us> |
---|---|
date | Fri, 25 Jul 2025 10:22:04 -0400 |
parents | f81bed4e04ac |
children |
comparison
equal
deleted
inserted
replaced
369:47c9f8502269 | 370:ea3a74ed2ef9 |
---|---|
3 #include "core/strings.h" | 3 #include "core/strings.h" |
4 | 4 |
5 #include <QDebug> | 5 #include <QDebug> |
6 #include <QFrame> | 6 #include <QFrame> |
7 #include <QLabel> | 7 #include <QLabel> |
8 #include <QPainter> | |
9 #include <QScrollArea> | |
8 #include <QTextBlock> | 10 #include <QTextBlock> |
9 #include <QVBoxLayout> | 11 #include <QVBoxLayout> |
10 #include <QScrollArea> | |
11 #include <QDebug> | |
12 #include <QPainter> | |
13 | 12 |
14 namespace TextWidgets { | 13 namespace TextWidgets { |
15 | 14 |
16 /* Generic header meant to be used in conjunction with Section<T> */ | 15 /* Generic header meant to be used in conjunction with Section<T> */ |
17 | 16 |
18 Header::Header(QWidget* parent) | 17 Header::Header(QWidget *parent) : QWidget(parent), title_(new QLabel), separator_(new QFrame) |
19 : QWidget(parent) | 18 { |
20 , title_(new QLabel) | 19 QVBoxLayout *layout = new QVBoxLayout(this); |
21 , separator_(new QFrame) { | |
22 QVBoxLayout* layout = new QVBoxLayout(this); | |
23 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); | 20 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); |
24 | 21 |
25 title_->setTextFormat(Qt::PlainText); | 22 title_->setTextFormat(Qt::PlainText); |
26 | 23 |
27 { | 24 { |
38 layout->addWidget(separator_.data()); | 35 layout->addWidget(separator_.data()); |
39 layout->setSpacing(0); | 36 layout->setSpacing(0); |
40 layout->setContentsMargins(0, 0, 0, 0); | 37 layout->setContentsMargins(0, 0, 0, 0); |
41 } | 38 } |
42 | 39 |
43 void Header::SetText(const std::string& text) { | 40 void Header::SetText(const std::string &text) |
41 { | |
44 title_->setText(Strings::ToQString(text)); | 42 title_->setText(Strings::ToQString(text)); |
45 updateGeometry(); | 43 updateGeometry(); |
46 } | 44 } |
47 | 45 |
48 Label::Label(QWidget *parent) : QLabel(parent) {} | 46 Label::Label(QWidget *parent) : QLabel(parent) |
49 Label::Label(const QString &string, QWidget *parent) : QLabel(string, parent) {} | 47 { |
50 | 48 } |
51 void Label::SetElidingMode(bool elide) { | 49 Label::Label(const QString &string, QWidget *parent) : QLabel(string, parent) |
50 { | |
51 } | |
52 | |
53 void Label::SetElidingMode(bool elide) | |
54 { | |
52 elide_ = elide; | 55 elide_ = elide; |
53 update(); | 56 update(); |
54 } | 57 } |
55 | 58 |
56 void Label::paintEvent(QPaintEvent *event) { | 59 void Label::paintEvent(QPaintEvent *event) |
60 { | |
57 if (elide_) { | 61 if (elide_) { |
58 /* bruh */ | 62 /* bruh */ |
59 if (wordWrap()) { | 63 if (wordWrap()) { |
60 QFrame::paintEvent(event); | 64 QFrame::paintEvent(event); |
61 | 65 |
62 const QString content = text(); | 66 const QString content = text(); |
63 | 67 |
64 QPainter painter(this); | 68 QPainter painter(this); |
65 QFontMetrics fontMetrics = painter.fontMetrics(); | 69 QFontMetrics fontMetrics = painter.fontMetrics(); |
66 | 70 |
67 bool didElide = false; | 71 bool didElide = false; |
68 int lineSpacing = fontMetrics.lineSpacing(); | 72 int lineSpacing = fontMetrics.lineSpacing(); |
69 int y = 0; | 73 int y = 0; |
70 | 74 |
71 QTextLayout textLayout(content, painter.font()); | 75 QTextLayout textLayout(content, painter.font()); |
72 textLayout.beginLayout(); | 76 textLayout.beginLayout(); |
73 for (;;) { | 77 for (;;) { |
74 QTextLine line = textLayout.createLine(); | 78 QTextLine line = textLayout.createLine(); |
75 | 79 |
76 if (!line.isValid()) | 80 if (!line.isValid()) |
77 break; | 81 break; |
78 | 82 |
79 line.setLineWidth(width()); | 83 line.setLineWidth(width()); |
80 int nextLineY = y + lineSpacing; | 84 int nextLineY = y + lineSpacing; |
81 | 85 |
82 if (height() >= nextLineY + lineSpacing) { | 86 if (height() >= nextLineY + lineSpacing) { |
83 line.draw(&painter, QPoint(0, y)); | 87 line.draw(&painter, QPoint(0, y)); |
84 y = nextLineY; | 88 y = nextLineY; |
85 } else { | 89 } else { |
86 QString lastLine = content.mid(line.textStart()); | 90 QString lastLine = content.mid(line.textStart()); |
87 QString elidedLastLine = fontMetrics.elidedText(lastLine, Qt::ElideRight, width()); | 91 QString elidedLastLine = fontMetrics.elidedText(lastLine, Qt::ElideRight, width()); |
88 painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLastLine); | 92 painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLastLine); |
89 line = textLayout.createLine(); | 93 line = textLayout.createLine(); |
109 } | 113 } |
110 | 114 |
111 /* ---------------------------------------------------------------------------------- */ | 115 /* ---------------------------------------------------------------------------------- */ |
112 /* "Paragraph" widgets, as in widgets meant to hold a bunch of text. */ | 116 /* "Paragraph" widgets, as in widgets meant to hold a bunch of text. */ |
113 | 117 |
114 Paragraph::Paragraph(QWidget *parent) : QWidget(parent), label_(new QLabel) { | 118 Paragraph::Paragraph(QWidget *parent) : QWidget(parent), label_(new QLabel) |
119 { | |
115 QVBoxLayout *layout = new QVBoxLayout(this); | 120 QVBoxLayout *layout = new QVBoxLayout(this); |
116 layout->setSpacing(0); | 121 layout->setSpacing(0); |
117 layout->setContentsMargins(0, 0, 0, 0); | 122 layout->setContentsMargins(0, 0, 0, 0); |
118 | 123 |
119 label_->setTextInteractionFlags(Qt::TextBrowserInteraction); | 124 label_->setTextInteractionFlags(Qt::TextBrowserInteraction); |
123 SetSelectable(true); | 128 SetSelectable(true); |
124 | 129 |
125 layout->addWidget(label_.data()); | 130 layout->addWidget(label_.data()); |
126 } | 131 } |
127 | 132 |
128 void Paragraph::SetText(const std::string& text) { | 133 void Paragraph::SetText(const std::string &text) |
134 { | |
129 label_->setText(Strings::ToQString(text)); | 135 label_->setText(Strings::ToQString(text)); |
130 } | 136 } |
131 | 137 |
132 void Paragraph::SetSelectable(bool enable) { | 138 void Paragraph::SetSelectable(bool enable) |
139 { | |
133 label_->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents, !enable); | 140 label_->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents, !enable); |
134 label_->setCursor(enable ? Qt::IBeamCursor : Qt::ArrowCursor); | 141 label_->setCursor(enable ? Qt::IBeamCursor : Qt::ArrowCursor); |
135 } | 142 } |
136 | 143 |
137 void Paragraph::SetWordWrap(bool enable) { | 144 void Paragraph::SetWordWrap(bool enable) |
145 { | |
138 label_->setWordWrap(enable); | 146 label_->setWordWrap(enable); |
139 } | 147 } |
140 | 148 |
141 /* LabelledParagraph implementation */ | 149 /* LabelledParagraph implementation */ |
142 | 150 |
143 LabelledParagraph::LabelledParagraph(QWidget* parent) | 151 LabelledParagraph::LabelledParagraph(QWidget *parent) |
144 : QWidget(parent) | 152 : QWidget(parent), contents_(new QWidget), contents_layout_(new QGridLayout) |
145 , contents_(new QWidget) | 153 { |
146 , contents_layout_(new QGridLayout) { | 154 QHBoxLayout *ly = new QHBoxLayout(this); |
147 QHBoxLayout* ly = new QHBoxLayout(this); | |
148 | 155 |
149 contents_layout_->setVerticalSpacing(1); | 156 contents_layout_->setVerticalSpacing(1); |
150 contents_layout_->setHorizontalSpacing(20); | 157 contents_layout_->setHorizontalSpacing(20); |
151 contents_layout_->setContentsMargins(0, 0, 0, 0); | 158 contents_layout_->setContentsMargins(0, 0, 0, 0); |
152 contents_layout_->setColumnStretch(1, 0); | 159 contents_layout_->setColumnStretch(1, 0); |
155 | 162 |
156 ly->addWidget(contents_.data()); | 163 ly->addWidget(contents_.data()); |
157 ly->setContentsMargins(0, 0, 0, 0); | 164 ly->setContentsMargins(0, 0, 0, 0); |
158 } | 165 } |
159 | 166 |
160 LabelledParagraph::~LabelledParagraph() { | 167 LabelledParagraph::~LabelledParagraph() |
168 { | |
161 data_.clear(); | 169 data_.clear(); |
162 } | 170 } |
163 | 171 |
164 void LabelledParagraph::Clear(void) { | 172 void LabelledParagraph::Clear(void) |
165 for (auto& [label, data] : data_) { | 173 { |
174 for (auto &[label, data] : data_) { | |
166 contents_layout_->removeWidget(label.data()); | 175 contents_layout_->removeWidget(label.data()); |
167 contents_layout_->removeWidget(data.data()); | 176 contents_layout_->removeWidget(data.data()); |
168 } | 177 } |
169 | 178 |
170 data_.clear(); | 179 data_.clear(); |
171 } | 180 } |
172 | 181 |
173 void LabelledParagraph::SetData(const std::vector<std::pair<std::string, std::string>>& data) { | 182 void LabelledParagraph::SetData(const std::vector<std::pair<std::string, std::string>> &data) |
183 { | |
174 Clear(); | 184 Clear(); |
175 | 185 |
176 data_.reserve(data.size()); | 186 data_.reserve(data.size()); |
177 for (std::size_t i = 0; i < data.size(); i++) { | 187 for (std::size_t i = 0; i < data.size(); i++) { |
178 QSharedPointer<Label> first(new Label); | 188 QSharedPointer<Label> first(new Label); |
183 first->setText(Strings::ToQString(data[i].first)); | 193 first->setText(Strings::ToQString(data[i].first)); |
184 second->setText(Strings::ToQString(data[i].second)); | 194 second->setText(Strings::ToQString(data[i].second)); |
185 | 195 |
186 data_.push_back({first, second}); | 196 data_.push_back({first, second}); |
187 | 197 |
188 contents_layout_->addWidget(first.data(), i, 0); | 198 contents_layout_->addWidget(first.data(), i, 0); |
189 contents_layout_->addWidget(second.data(), i, 1); | 199 contents_layout_->addWidget(second.data(), i, 1); |
190 } | 200 } |
191 } | 201 } |
192 | 202 |
193 void LabelledParagraph::SetStyle(int style) { | 203 void LabelledParagraph::SetStyle(int style) |
204 { | |
194 const QString style_sheet = (style & LabelledParagraph::BoldedLabels) ? "font-weight: bold;" : ""; | 205 const QString style_sheet = (style & LabelledParagraph::BoldedLabels) ? "font-weight: bold;" : ""; |
195 for (auto& [label, data] : data_) | 206 for (auto &[label, data] : data_) |
196 label->setStyleSheet(style_sheet); | 207 label->setStyleSheet(style_sheet); |
197 | 208 |
198 if (style & LabelledParagraph::ElidedData) { | 209 if (style & LabelledParagraph::ElidedData) { |
199 for (auto& [label, data] : data_) { | 210 for (auto &[label, data] : data_) { |
200 data->setWordWrap(false); | 211 data->setWordWrap(false); |
201 data->SetElidingMode(true); | 212 data->SetElidingMode(true); |
202 } | 213 } |
203 } | 214 } |
204 } | 215 } |