view src/gui/widgets/text.cc @ 229:adc20fa321c1

theme: force Fusion style on platforms other than Win32 or OS X I was reluctant to do this, but most of the other styles just look like pure shite regardless of whether I force a stylesheet on them or not. KDE's style is actually hilariously bad paired with my stylesheet, so I've decided to also make the stylesheet Windows-specific as well, because that's really the only platform where it makes sense in the first place.
author Paper <paper@paper.us.eu.org>
date Wed, 10 Jan 2024 21:23:57 -0500
parents 01d259b9c89f
children 4d461ef7d424
line wrap: on
line source

#include "gui/widgets/text.h"
#include "core/session.h"
#include <QDebug>
#include <QFrame>
#include <QLabel>
#include <QTextBlock>
#include <QVBoxLayout>

namespace TextWidgets {

Header::Header(const QString& title, QWidget* parent) : QWidget(parent) {
	QVBoxLayout* layout = new QVBoxLayout(this);
	setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);

	static_text_title = new QLabel(title, this);
	static_text_title->setTextFormat(Qt::PlainText);

	{
		QFont font = static_text_title->font();
		font.setWeight(QFont::Bold);
		static_text_title->setFont(font);
	}

	static_text_line = new QFrame(this);
	static_text_line->setFrameShape(QFrame::HLine);
	static_text_line->setFrameShadow(QFrame::Sunken);
	static_text_line->setFixedHeight(2);

	layout->addWidget(static_text_title);
	layout->addWidget(static_text_line);
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);
}

void Header::SetText(const QString& text) {
	static_text_title->setText(text);
	updateGeometry();
}

/* inherits QPlainTextEdit and gives a much more reasonable minimum size */
Paragraph::Paragraph(const QString& text, QWidget* parent) : QPlainTextEdit(text, parent) {
	setTextInteractionFlags(Qt::TextBrowserInteraction);
	setFrameShape(QFrame::NoFrame);
	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

	QPalette pal;
	pal.setColor(QPalette::Base, Qt::transparent);
	setPalette(pal);

	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}

void Paragraph::SetText(const QString& text) {
	QTextDocument* document = new QTextDocument(this);
	document->setDocumentLayout(new QPlainTextDocumentLayout(document));
	document->setPlainText(text);
	setDocument(document);
	updateGeometry();
}

/* highly based upon... some stackoverflow answer for PyQt */
QSize Paragraph::minimumSizeHint() const {
	return QSize(0, 0);
}

QSize Paragraph::sizeHint() const {
	QTextDocument* doc = document();
	doc->adjustSize();
	long h = 0;
	for (QTextBlock line = doc->begin(); line != doc->end(); line = line.next()) {
		h += doc->documentLayout()->blockBoundingRect(line).height();
	}
	return QSize(doc->size().width(), h);
}

/* Equivalent to Paragraph(), but is only capable of showing one line. Only
   exists because with SelectableSection it will let you go
   out of bounds and that looks really fugly for most things */
Line::Line(QWidget* parent) : QLineEdit(parent) {
	setFrame(false);
	setReadOnly(true);
	setCursor(Qt::IBeamCursor);

	QPalette pal;
	pal.setColor(QPalette::Window, Qt::transparent);
	pal.setColor(QPalette::Base, Qt::transparent);
	setPalette(pal);

	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
}

Line::Line(const QString& text, QWidget* parent) : Line(parent) {
	SetText(text);
}

void Line::SetText(const QString& text) {
	setText(text);
	setCursorPosition(0); /* displays left text first */
}

Title::Title(const QString& title, QWidget* parent) : Line(title, parent) {
	QFont fnt(font());
	fnt.setPixelSize(16);
	setFont(fnt);

	QPalette pal(palette());
	pal.setColor(QPalette::Text, pal.color(QPalette::Highlight));
	setPalette(pal);
}

Section::Section(const QString& title, const QString& data, QWidget* parent) : QWidget(parent) {
	QVBoxLayout* layout = new QVBoxLayout(this);

	header = new Header(title, this);

	QWidget* content = new QWidget(this);
	QHBoxLayout* content_layout = new QHBoxLayout(content);

	paragraph = new Paragraph(data, this);
	paragraph->setTextInteractionFlags(Qt::NoTextInteraction);
	paragraph->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents);
	paragraph->setWordWrapMode(QTextOption::NoWrap);

	content_layout->addWidget(paragraph);
	content_layout->setSpacing(0);
	content_layout->setContentsMargins(0, 0, 0, 0);
	content->setContentsMargins(12, 0, 0, 0);

	layout->addWidget(header);
	layout->addWidget(paragraph);
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);
}

Header* Section::GetHeader() {
	return header;
}

Paragraph* Section::GetParagraph() {
	return paragraph;
}

LabelledSection::LabelledSection(const QString& title, const QString& label, const QString& data, QWidget* parent) : QWidget(parent) {
	QVBoxLayout* layout = new QVBoxLayout(this);

	header = new Header(title, this);

	// this is not accessible from the object because there's really
	// no reason to make it accessible...
	QWidget* content = new QWidget(this);
	content->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);

	labels = new Paragraph(label, this);
	labels->setTextInteractionFlags(Qt::NoTextInteraction);
	labels->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents);
	labels->setWordWrapMode(QTextOption::NoWrap);
	labels->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);

	paragraph = new Paragraph(data, this);
	paragraph->setTextInteractionFlags(Qt::NoTextInteraction);
	paragraph->setAttribute(Qt::WidgetAttribute::WA_TransparentForMouseEvents);
	paragraph->setWordWrapMode(QTextOption::NoWrap);
	paragraph->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);

	QHBoxLayout* content_layout = new QHBoxLayout(content);
	content_layout->addWidget(labels, 0, Qt::AlignTop);
	content_layout->addWidget(paragraph, 0, Qt::AlignTop);
	content_layout->setSpacing(20);
	content_layout->setContentsMargins(0, 0, 0, 0);

	content->setContentsMargins(12, 0, 0, 0);

	layout->addWidget(header);
	layout->addWidget(content);
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);
}

Header* LabelledSection::GetHeader() {
	return header;
}

Paragraph* LabelledSection::GetLabels() {
	return labels;
}

Paragraph* LabelledSection::GetParagraph() {
	return paragraph;
}

SelectableSection::SelectableSection(const QString& title, const QString& data, QWidget* parent) : QWidget(parent) {
	QVBoxLayout* layout = new QVBoxLayout(this);

	header = new Header(title, this);

	QWidget* content = new QWidget(this);
	QHBoxLayout* content_layout = new QHBoxLayout(content);

	paragraph = new Paragraph(data, content);

	content_layout->addWidget(paragraph);
	content_layout->setSpacing(0);
	content_layout->setContentsMargins(12, 0, 0, 0);
	content->setContentsMargins(0, 0, 0, 0);

	layout->addWidget(header);
	layout->addWidget(content);
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);
}

Header* SelectableSection::GetHeader() {
	return header;
}

Paragraph* SelectableSection::GetParagraph() {
	return paragraph;
}

OneLineSection::OneLineSection(const QString& title, const QString& text, QWidget* parent) : QWidget(parent) {
	QVBoxLayout* layout = new QVBoxLayout(this);

	header = new Header(title, this);

	QWidget* content = new QWidget(this);
	QHBoxLayout* content_layout = new QHBoxLayout(content);

	line = new Line(text, content);

	content_layout->addWidget(line);
	content_layout->setSpacing(0);
	content_layout->setContentsMargins(0, 0, 0, 0);
	content->setContentsMargins(12, 0, 0, 0);

	layout->addWidget(header);
	layout->addWidget(content);
	layout->setSpacing(0);
	layout->setContentsMargins(0, 0, 0, 0);
}

Header* OneLineSection::GetHeader() {
	return header;
}

Line* OneLineSection::GetLine() {
	return line;
}

} // namespace TextWidgets

#include "gui/widgets/moc_text.cpp"