Files
z-bar-qt/Plugins/ZShell/Config/font.cpp
T

291 lines
6.5 KiB
C++

#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