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 } |
