291 lines
6.5 KiB
C++
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
|