feat: fontbuilder to streamline font styling
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m10s
Python / verify (pull_request) Successful in 1m53s
Rust / fmt (pull_request) Successful in 34s
Rust / clippy (pull_request) Successful in 57s
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m10s
Python / verify (pull_request) Successful in 1m53s
Rust / fmt (pull_request) Successful in 34s
Rust / clippy (pull_request) Successful in 57s
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
#include "font.hpp"
|
||||
|
||||
#include "appearance.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
FontStyleBase::FontStyleBase(QObject* parent) : QObject(parent) {}
|
||||
|
||||
QFont FontStyleBase::large() const {
|
||||
return m_large;
|
||||
}
|
||||
|
||||
QFont FontStyleBase::medium() const {
|
||||
return m_medium;
|
||||
}
|
||||
|
||||
QFont FontStyleBase::small() const {
|
||||
return m_small;
|
||||
}
|
||||
|
||||
QFont FontStyleBase::buildFont(
|
||||
const FontSizeNode* cfg, const QString& fallbackFamily, qreal scale) {
|
||||
const auto family = cfg->property("family").toString();
|
||||
const auto size = cfg->property("size").toInt();
|
||||
const auto weight = cfg->property("weight").value<QFont::Weight>();
|
||||
const auto italic = cfg->property("italic").toBool();
|
||||
const auto vaxes = cfg->property("vaxes").toMap();
|
||||
|
||||
QFont font;
|
||||
font.setFamily(family.isEmpty() ? fallbackFamily : family);
|
||||
const int scaledSize = static_cast<int>(size * scale);
|
||||
const int cappedSize = scaledSize > 0 ? scaledSize : 1;
|
||||
font.setPointSize(cappedSize);
|
||||
font.setVariableAxis("opsz", static_cast<float>(cappedSize));
|
||||
font.setWeight(weight);
|
||||
font.setVariableAxis("wght", static_cast<float>(weight));
|
||||
font.setItalic(italic);
|
||||
|
||||
for (auto it = vaxes.constBegin(); it != vaxes.constEnd(); ++it) {
|
||||
if (auto tag = QFont::Tag::fromString(it.key()))
|
||||
font.setVariableAxis(*tag, it.value().toFloat());
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void FontStyleBase::bind(FontStyleNode* cfg) {
|
||||
if (m_cfg == cfg) return;
|
||||
|
||||
if (m_cfg) {
|
||||
disconnect(m_cfg, nullptr, this, nullptr);
|
||||
disconnect(m_cfg->largeNode(), nullptr, this, nullptr);
|
||||
disconnect(m_cfg->mediumNode(), nullptr, this, nullptr);
|
||||
disconnect(m_cfg->smallNode(), nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
m_cfg = cfg;
|
||||
|
||||
if (cfg) {
|
||||
connect(
|
||||
cfg, &ConfigNode::propertiesChanged, this, &FontStyleBase::rebuild);
|
||||
connect(
|
||||
cfg->largeNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&FontStyleBase::rebuild);
|
||||
connect(
|
||||
cfg->mediumNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&FontStyleBase::rebuild);
|
||||
connect(
|
||||
cfg->smallNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&FontStyleBase::rebuild);
|
||||
}
|
||||
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void FontStyleBase::rebuild() {
|
||||
if (m_cfg) {
|
||||
const auto family = m_cfg->property("family").toString();
|
||||
m_large = buildFont(m_cfg->largeNode(), family, m_scale);
|
||||
m_medium = buildFont(m_cfg->mediumNode(), family, m_scale);
|
||||
m_small = buildFont(m_cfg->smallNode(), family, m_scale);
|
||||
} else {
|
||||
m_large = QFont();
|
||||
m_medium = QFont();
|
||||
m_small = QFont();
|
||||
}
|
||||
emit fontsChanged();
|
||||
}
|
||||
|
||||
void FontStyleBase::setScale(qreal scale) {
|
||||
if (qFuzzyCompare(m_scale + 1.0, scale + 1.0)) return;
|
||||
m_scale = scale;
|
||||
rebuild();
|
||||
}
|
||||
|
||||
FontStyle::FontStyle(QObject* parent)
|
||||
: FontStyleBase(parent), m_builders(new FontBuilders(this, this)) {}
|
||||
|
||||
FontBuilders* FontStyle::builders() const {
|
||||
return m_builders;
|
||||
}
|
||||
|
||||
IconFontStyle::IconFontStyle(QObject* parent)
|
||||
: FontStyleBase(parent), m_builders(new IconFontBuilders(this, this)) {}
|
||||
|
||||
FontBuilder IconFontStyle::size(int pointSize) {
|
||||
return FontBuilder(m_small).size(pointSize);
|
||||
}
|
||||
|
||||
FontBuilder IconFontStyle::pixelSize(int pixelSize) {
|
||||
return FontBuilder(m_small).pixelSize(pixelSize);
|
||||
}
|
||||
|
||||
void IconFontStyle::bind(FontStyleNode* cfg) {
|
||||
if (m_cfg == cfg) return;
|
||||
|
||||
if (m_cfg) disconnect(m_cfg->extraLargeNode(), nullptr, this, nullptr);
|
||||
|
||||
FontStyleBase::bind(cfg);
|
||||
|
||||
if (cfg)
|
||||
connect(
|
||||
cfg->extraLargeNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&IconFontStyle::rebuild);
|
||||
}
|
||||
|
||||
QFont IconFontStyle::extraLarge() const {
|
||||
return m_extraLarge;
|
||||
}
|
||||
|
||||
IconFontBuilders* IconFontStyle::builders() const {
|
||||
return m_builders;
|
||||
}
|
||||
|
||||
void IconFontStyle::rebuild() {
|
||||
if (m_cfg) {
|
||||
const auto family = m_cfg->property("family").toString();
|
||||
m_extraLarge = buildFont(m_cfg->extraLargeNode(), family, m_scale);
|
||||
} else {
|
||||
m_extraLarge = QFont();
|
||||
}
|
||||
FontStyleBase::rebuild();
|
||||
}
|
||||
|
||||
FontBuilders::FontBuilders(const FontStyleBase* style, QObject* parent)
|
||||
: QObject(parent), m_style(style) {
|
||||
connect(
|
||||
style,
|
||||
&FontStyleBase::fontsChanged,
|
||||
this,
|
||||
&FontBuilders::buildersChanged);
|
||||
}
|
||||
|
||||
FontBuilder FontBuilders::large() const {
|
||||
return FontBuilder(m_style->large());
|
||||
}
|
||||
|
||||
FontBuilder FontBuilders::medium() const {
|
||||
return FontBuilder(m_style->medium());
|
||||
}
|
||||
|
||||
FontBuilder FontBuilders::small() const {
|
||||
return FontBuilder(m_style->small());
|
||||
}
|
||||
|
||||
IconFontBuilders::IconFontBuilders(const IconFontStyle* style, QObject* parent)
|
||||
: FontBuilders(style, parent) {}
|
||||
|
||||
FontBuilder IconFontBuilders::extraLarge() const {
|
||||
return FontBuilder(
|
||||
static_cast<const IconFontStyle*>(m_style)->extraLarge());
|
||||
}
|
||||
|
||||
FontTokens::FontTokens(QObject* parent)
|
||||
: ConfigObject(parent)
|
||||
, m_size(new FontSizeTokens(this))
|
||||
, m_headline(new FontStyle(this))
|
||||
, m_title(new FontStyle(this))
|
||||
, m_body(new FontStyle(this))
|
||||
, m_label(new FontStyle(this))
|
||||
, m_mono(new FontStyle(this))
|
||||
, m_icon(new IconFontStyle(this)) {
|
||||
if (!Config::instance()) new Config();
|
||||
bindFont(Config::instance()->appearance()->font());
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::headline() const {
|
||||
return m_headline;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::title() const {
|
||||
return m_title;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::body() const {
|
||||
return m_body;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::label() const {
|
||||
return m_label;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::mono() const {
|
||||
return m_mono;
|
||||
}
|
||||
|
||||
IconFontStyle* FontTokens::icon() const {
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
FontBuilder FontTokens::clock() const {
|
||||
return FontBuilder(m_clock);
|
||||
}
|
||||
|
||||
QString FontTokens::workspaces() const {
|
||||
return m_font ? m_font->workspaces() : QString();
|
||||
}
|
||||
|
||||
void FontTokens::bindFont(AppearanceFont* font) {
|
||||
if (m_font == font) return;
|
||||
|
||||
if (m_font) disconnect(m_font, nullptr, this, nullptr);
|
||||
|
||||
m_font = font;
|
||||
|
||||
if (font) {
|
||||
rebuildScale();
|
||||
m_headline->bind(font->headline());
|
||||
m_title->bind(font->title());
|
||||
m_body->bind(font->body());
|
||||
m_label->bind(font->label());
|
||||
m_mono->bind(font->mono());
|
||||
m_icon->bind(font->icon());
|
||||
|
||||
connect(
|
||||
font,
|
||||
&AppearanceFont::clockChanged,
|
||||
this,
|
||||
&FontTokens::rebuildClock);
|
||||
connect(
|
||||
font,
|
||||
&AppearanceFont::scaleChanged,
|
||||
this,
|
||||
&FontTokens::rebuildScale);
|
||||
connect(
|
||||
font,
|
||||
&AppearanceFont::workspacesChanged,
|
||||
this,
|
||||
&FontTokens::workspacesChanged);
|
||||
} else {
|
||||
rebuildScale();
|
||||
m_headline->bind(nullptr);
|
||||
m_title->bind(nullptr);
|
||||
m_body->bind(nullptr);
|
||||
m_label->bind(nullptr);
|
||||
m_mono->bind(nullptr);
|
||||
m_icon->bind(nullptr);
|
||||
}
|
||||
|
||||
rebuildClock();
|
||||
emit workspacesChanged();
|
||||
}
|
||||
|
||||
void FontTokens::rebuildScale() {
|
||||
const qreal s = m_font ? m_font->scale() : 1;
|
||||
m_headline->setScale(s);
|
||||
m_title->setScale(s);
|
||||
m_body->setScale(s);
|
||||
m_label->setScale(s);
|
||||
m_mono->setScale(s);
|
||||
m_icon->setScale(s);
|
||||
}
|
||||
|
||||
void FontTokens::rebuildClock() {
|
||||
QFont f;
|
||||
if (m_font) f.setFamily(m_font->clock());
|
||||
m_clock = f;
|
||||
emit clockChanged();
|
||||
}
|
||||
|
||||
} // namespace ZShell::config
|
||||
Reference in New Issue
Block a user