comparison src/gui/widgets/text.cc @ 348:6b0768158dcd

text: redesign almost every widget i.e. Paragraph is now a QLabel, etc etc, some things will probably break, idc
author Paper <paper@paper.us.eu.org>
date Tue, 25 Jun 2024 11:19:54 -0400
parents b82841e76e79
children f81bed4e04ac
comparison
equal deleted inserted replaced
347:a0aa8c8c4307 348:6b0768158dcd
1 #include "gui/widgets/text.h" 1 #include "gui/widgets/text.h"
2 #include "core/session.h" 2 #include "core/session.h"
3 #include "core/strings.h"
3 4
4 #include <QDebug> 5 #include <QDebug>
5 #include <QFrame> 6 #include <QFrame>
6 #include <QLabel> 7 #include <QLabel>
7 #include <QTextBlock> 8 #include <QTextBlock>
8 #include <QVBoxLayout> 9 #include <QVBoxLayout>
9 #include <QScrollArea> 10 #include <QScrollArea>
10 #include <QDebug> 11 #include <QDebug>
11 12
12 /* WARNING: GARBAGE CODE FOLLOWS
13 *
14 * This file is filled with spaghetti to make this
15 * stupid text render how I want it to.
16 *
17 * many cases of hacking with setSizePolicy() are seen
18 * all around this file. Edit it only if really
19 * necessary, please.
20 */
21
22 namespace TextWidgets { 13 namespace TextWidgets {
23 14
24 Header::Header(const QString& title, QWidget* parent) 15 /* Generic header meant to be used in conjunction with Section<T> */
16
17 Header::Header(QWidget* parent)
25 : QWidget(parent) 18 : QWidget(parent)
26 , static_text_title(title) { 19 , title_(new QLabel(this))
20 , separator_(new QFrame(this)) {
27 QVBoxLayout* layout = new QVBoxLayout(this); 21 QVBoxLayout* layout = new QVBoxLayout(this);
28 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); 22 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
29 23
30 static_text_title.setTextFormat(Qt::PlainText); 24 title_->setTextFormat(Qt::PlainText);
31 25
32 { 26 {
33 QFont font = static_text_title.font(); 27 QFont font = title_->font();
34 font.setWeight(QFont::Bold); 28 font.setWeight(QFont::Bold);
35 static_text_title.setFont(font); 29 title_->setFont(font);
36 } 30 }
37 31
38 static_text_line.setFrameShape(QFrame::HLine); 32 separator_->setFrameShape(QFrame::HLine);
39 static_text_line.setFrameShadow(QFrame::Sunken); 33 separator_->setFrameShadow(QFrame::Sunken);
40 static_text_line.setFixedHeight(2); 34 separator_->setFixedHeight(2);
41 35
42 layout->addWidget(&static_text_title); 36 layout->addWidget(title_.data());
43 layout->addWidget(&static_text_line); 37 layout->addWidget(separator_.data());
44 layout->setSpacing(0); 38 layout->setSpacing(0);
45 layout->setContentsMargins(0, 0, 0, 0); 39 layout->setContentsMargins(0, 0, 0, 0);
46 } 40 }
47 41
48 void Header::SetText(const QString& text) { 42 void Header::SetText(const std::string& text) {
49 static_text_title.setText(text); 43 title_->setText(Strings::ToQString(text));
50 updateGeometry(); 44 updateGeometry();
51 } 45 }
52 46
53 Paragraph::Paragraph(const QString& text, QWidget* parent) : QWidget(parent) { 47 /* ---------------------------------------------------------------------------------- */
54 /* meh */ 48 /* "Paragraph" widgets, as in widgets meant to hold a bunch of text. */
55 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
56 49
57 QVBoxLayout* layout = new QVBoxLayout(this); 50 Paragraph::Paragraph(QWidget *parent) : QWidget(parent), label_(new QLabel) {
51 QVBoxLayout *layout = new QVBoxLayout(this);
58 layout->setSpacing(0); 52 layout->setSpacing(0);
59 layout->setContentsMargins(0, 0, 0, 0); 53 layout->setContentsMargins(0, 0, 0, 0);
60 54
61 text_edit.setTextInteractionFlags(Qt::TextBrowserInteraction); 55 label_->setTextInteractionFlags(Qt::TextBrowserInteraction);
62 text_edit.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
63 text_edit.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
64 text_edit.setStyleSheet("background: transparent;");
65 text_edit.setFrameStyle(QFrame::NoFrame);
66 56
67 text_edit.document()->setDocumentMargin(0); 57 /* defaults */
58 SetWordWrap(true);
59 SetSelectable(true);
68 60
69 SetText(text); 61 layout->addWidget(label_.data());
70
71 layout->addWidget(&text_edit);
72 } 62 }
73 63
74 void Paragraph::SetText(const QString& text) { 64 void Paragraph::SetText(const std::string& text) {
75 text_edit.document()->setPlainText(text); 65 label_->setText(Strings::ToQString(text));
76
77 /* return the view to the start */
78 QTextCursor cursor = text_edit.textCursor();
79 cursor.setPosition(0);
80 text_edit.setTextCursor(cursor);
81 } 66 }
82 67
83 bool Paragraph::hasHeightForWidth() const { 68 void Paragraph::SetSelectable(bool enable) {
84 return true; 69 label_->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents, !enable);
70 label_->setCursor(enable ? Qt::IBeamCursor : Qt::ArrowCursor);
85 } 71 }
86 72
87 int Paragraph::heightForWidth(int w) const { 73 void Paragraph::SetWordWrap(bool enable) {
88 QTextDocument* doc = text_edit.document(); 74 label_->setWordWrap(enable);
89 doc->setTextWidth(w);
90
91 return doc->size().toSize().height();
92 } 75 }
93 76
94 QPlainTextEdit* Paragraph::GetLabel() { 77 /* LabelledParagraph implementation */
95 return &text_edit;
96 }
97 78
98 Line::Line(QWidget* parent) : QWidget(parent) { 79 LabelledParagraph::LabelledParagraph(QWidget* parent)
99 QVBoxLayout* layout = new QVBoxLayout(this);
100 layout->setSpacing(0);
101 layout->setContentsMargins(0, 0, 0, 0);
102
103 line_edit_.setReadOnly(true);
104 line_edit_.setFrame(false);
105 line_edit_.setStyleSheet("background: transparent;");
106
107 layout->addWidget(&line_edit_);
108 }
109
110 Line::Line(const QString& text, QWidget* parent) : Line(parent) {
111 SetText(text);
112 }
113
114 void Line::SetText(const QString& text) {
115 line_edit_.setText(text);
116 line_edit_.setCursorPosition(0);
117 }
118
119 Title::Title(const QString& title, QWidget* parent) : Line(title, parent) {
120 QFont fnt(line_edit_.font());
121 fnt.setPixelSize(16);
122 line_edit_.setFont(fnt);
123
124 line_edit_.setForegroundRole(QPalette::Highlight);
125 }
126
127 Section::Section(const QString& title, const QString& data, QWidget* parent)
128 : QWidget(parent) {
129 QVBoxLayout* layout = new QVBoxLayout(this);
130
131 header = new Header(title, this);
132
133 QWidget* content = new QWidget(this);
134 QHBoxLayout* content_layout = new QHBoxLayout(content);
135
136 paragraph = new Paragraph(data, this);
137 paragraph->GetLabel()->setTextInteractionFlags(Qt::NoTextInteraction);
138 paragraph->GetLabel()->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents);
139 paragraph->GetLabel()->setWordWrapMode(QTextOption::NoWrap);
140
141 content_layout->addWidget(paragraph);
142 content_layout->setSpacing(0);
143 content_layout->setContentsMargins(0, 0, 0, 0);
144 content->setContentsMargins(12, 0, 0, 0);
145
146 layout->addWidget(header);
147 layout->addWidget(paragraph);
148 layout->setSpacing(0);
149 layout->setContentsMargins(0, 0, 0, 0);
150 }
151
152 Header* Section::GetHeader() {
153 return header;
154 }
155
156 Paragraph* Section::GetParagraph() {
157 return paragraph;
158 }
159
160 /* despite being named a "labelled paragraph" this uses QLabels for simplicity */
161 LabelledParagraph::LabelledParagraph(const QString& label, const QString& data, QWidget* parent)
162 : QWidget(parent) 80 : QWidget(parent)
163 , labels_(label) 81 , contents_(new QWidget)
164 , data_(data) { 82 , contents_layout_(new QGridLayout) {
165 QHBoxLayout* ly = new QHBoxLayout(this); 83 QHBoxLayout* ly = new QHBoxLayout(this);
166 84
167 labels_.setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); 85 contents_layout_->setVerticalSpacing(1);
168 data_.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); 86 contents_layout_->setHorizontalSpacing(20);
87 contents_layout_->setContentsMargins(0, 0, 0, 0);
88 contents_layout_->setColumnStretch(1, 0);
169 89
170 ly->addWidget(&labels_, 0, Qt::AlignTop); 90 contents_->setLayout(contents_layout_.data());
171 ly->addWidget(&data_, 0, Qt::AlignTop); 91
172 ly->setSpacing(20); 92 ly->addWidget(contents_.data());
173 ly->setContentsMargins(0, 0, 0, 0); 93 ly->setContentsMargins(0, 0, 0, 0);
174 } 94 }
175 95
176 QLabel* LabelledParagraph::GetLabels() { 96 LabelledParagraph::~LabelledParagraph() {
177 return &labels_; 97 data_.clear();
178 } 98 }
179 99
180 QLabel* LabelledParagraph::GetData() { 100 void LabelledParagraph::Clear(void) {
181 return &data_; 101 for (auto& [label, data] : data_) {
102 contents_layout_->removeWidget(label.data());
103 contents_layout_->removeWidget(data.data());
104 }
105
106 data_.clear();
182 } 107 }
183 108
184 QLabel* LabelledParagraph::GetParagraph() { 109 void LabelledParagraph::SetData(const std::vector<std::pair<std::string, std::string>>& data) {
185 return GetData(); 110 Clear();
111
112 data_.reserve(data.size());
113 for (std::size_t i = 0; i < data.size(); i++) {
114 QSharedPointer<QLabel> first(new QLabel);
115 QSharedPointer<QLabel> second(new QLabel);
116
117 first->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
118
119 first->setText(Strings::ToQString(data[i].first));
120 second->setText(Strings::ToQString(data[i].second));
121
122 data_.push_back({first, second});
123
124 contents_layout_->addWidget(first.data(), i, 0);
125 contents_layout_->addWidget(second.data(), i, 1);
126 }
186 } 127 }
187 128
188 LabelledSection::LabelledSection(const QString& title, const QString& label, const QString& data, QWidget* parent) 129 void LabelledParagraph::SetStyle(int style) {
189 : QWidget(parent) { 130 const QString style_sheet = (style & LabelledParagraph::BoldedLabels) ? "font-weight: bold;" : "";
190 QVBoxLayout* layout = new QVBoxLayout(this); 131 for (auto& [label, data] : data_)
132 label->setStyleSheet(style_sheet);
191 133
192 header = new Header(title, this); 134 // TODO ElidedData
193
194 // this is not accessible from the object because there's really
195 // no reason to make it accessible...
196 content = new LabelledParagraph(label, data, this);
197 content->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
198 content->setContentsMargins(12, 0, 0, 0);
199
200 layout->addWidget(header);
201 layout->addWidget(content);
202 layout->setSpacing(0);
203 layout->setContentsMargins(0, 0, 0, 0);
204 }
205
206 Header* LabelledSection::GetHeader() {
207 return header;
208 }
209
210 QLabel* LabelledSection::GetLabels() {
211 return content->GetLabels();
212 }
213
214 QLabel* LabelledSection::GetData() {
215 return content->GetData();
216 }
217
218 QLabel* LabelledSection::GetParagraph() {
219 return content->GetParagraph();
220 }
221
222 SelectableSection::SelectableSection(const QString& title, const QString& data, QWidget* parent) : QWidget(parent) {
223 QVBoxLayout* layout = new QVBoxLayout(this);
224
225 header = new Header(title, this);
226
227 QWidget* content = new QWidget(this);
228 QHBoxLayout* content_layout = new QHBoxLayout(content);
229
230 paragraph = new Paragraph(data, content);
231
232 content_layout->addWidget(paragraph);
233 content_layout->setSpacing(0);
234 content_layout->setContentsMargins(12, 0, 0, 0);
235 content->setContentsMargins(0, 0, 0, 0);
236
237 layout->addWidget(header);
238 layout->addWidget(content);
239 layout->setSpacing(0);
240 layout->setContentsMargins(0, 0, 0, 0);
241 }
242
243 Header* SelectableSection::GetHeader() {
244 return header;
245 }
246
247 Paragraph* SelectableSection::GetParagraph() {
248 return paragraph;
249 }
250
251 OneLineSection::OneLineSection(const QString& title, const QString& text, QWidget* parent) : QWidget(parent) {
252 QVBoxLayout* layout = new QVBoxLayout(this);
253
254 header = new Header(title, this);
255
256 QWidget* content = new QWidget(this);
257 QHBoxLayout* content_layout = new QHBoxLayout(content);
258
259 line = new Line(text, content);
260
261 content_layout->addWidget(line);
262 content_layout->setSpacing(0);
263 content_layout->setContentsMargins(0, 0, 0, 0);
264 content->setContentsMargins(12, 0, 0, 0);
265
266 layout->addWidget(header);
267 layout->addWidget(content);
268 layout->setSpacing(0);
269 layout->setContentsMargins(0, 0, 0, 0);
270 }
271
272 Header* OneLineSection::GetHeader() {
273 return header;
274 }
275
276 Line* OneLineSection::GetLine() {
277 return line;
278 } 135 }
279 136
280 } // namespace TextWidgets 137 } // namespace TextWidgets