feat: use QQuickAttachedPropertyPropagator
Instead of manually trying to find ancestor ConfigScope, set attached prop on ancestor and propagate via attached props
This commit is contained in:
parent
8883156dd9
commit
8c8d196e20
14 changed files with 185 additions and 235 deletions
|
|
@ -8,16 +8,10 @@ PanelWindow {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property string name
|
required property string name
|
||||||
readonly property alias configScope: scope
|
|
||||||
default property alias contentData: scope.data
|
|
||||||
|
|
||||||
WlrLayershell.namespace: `caelestia-${name}`
|
WlrLayershell.namespace: `caelestia-${name}`
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
ConfigScope {
|
contentItem.Config.screen: screen.name
|
||||||
id: scope
|
contentItem.Tokens.screen: screen.name
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
screen: root.screen.name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ StyledWindow {
|
||||||
}
|
}
|
||||||
return monitor?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false;
|
return monitor?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false;
|
||||||
}
|
}
|
||||||
property real borderThickness: hasFullscreen ? 0 : configScope.Config.border.thickness
|
property real borderThickness: hasFullscreen ? 0 : contentItem.Config.border.thickness
|
||||||
readonly property real borderLayoutThickness: hasFullscreen ? 0 : configScope.Config.border.thickness
|
readonly property real borderLayoutThickness: hasFullscreen ? 0 : contentItem.Config.border.thickness
|
||||||
property real borderRounding: hasFullscreen ? 0 : configScope.Config.border.rounding
|
property real borderRounding: hasFullscreen ? 0 : contentItem.Config.border.rounding
|
||||||
property real shadowOpacity: hasFullscreen ? 0 : 0.7
|
property real shadowOpacity: hasFullscreen ? 0 : 0.7
|
||||||
|
|
||||||
readonly property int dragMaskPadding: {
|
readonly property int dragMaskPadding: {
|
||||||
|
|
@ -44,8 +44,8 @@ StyledWindow {
|
||||||
|
|
||||||
const thresholds = [];
|
const thresholds = [];
|
||||||
for (const panel of ["dashboard", "launcher", "session", "sidebar"])
|
for (const panel of ["dashboard", "launcher", "session", "sidebar"])
|
||||||
if (configScope.Config[panel].enabled)
|
if (contentItem.Config[panel].enabled)
|
||||||
thresholds.push(configScope.Config[panel].dragThreshold);
|
thresholds.push(contentItem.Config[panel].dragThreshold);
|
||||||
return Math.max(...thresholds);
|
return Math.max(...thresholds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ Region {
|
||||||
required property Panels panels
|
required property Panels panels
|
||||||
required property var win
|
required property var win
|
||||||
|
|
||||||
readonly property real borderThickness: win.configScope.Config.border.thickness
|
readonly property real borderThickness: win.contentItem.Config.border.thickness
|
||||||
readonly property real clampedThickness: win.configScope.Config.border.clampedThickness
|
readonly property real clampedThickness: win.contentItem.Config.border.clampedThickness
|
||||||
|
|
||||||
x: bar.clampedWidth + win.dragMaskPadding
|
x: bar.clampedWidth + win.dragMaskPadding
|
||||||
y: clampedThickness + win.dragMaskPadding
|
y: clampedThickness + win.dragMaskPadding
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ WlSessionLockSurface {
|
||||||
|
|
||||||
readonly property alias unlocking: unlockAnim.running
|
readonly property alias unlocking: unlockAnim.running
|
||||||
|
|
||||||
|
contentItem.Config.screen: screen.name
|
||||||
|
contentItem.Tokens.screen: screen.name
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
@ -159,79 +162,72 @@ WlSessionLockSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigScope {
|
ScreencopyView {
|
||||||
id: configScope
|
id: background
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
screen: root.screen
|
captureSource: root.screen
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
ScreencopyView {
|
layer.enabled: true
|
||||||
id: background
|
layer.effect: MultiEffect {
|
||||||
|
autoPaddingEnabled: false
|
||||||
|
blurEnabled: true
|
||||||
|
blur: 1
|
||||||
|
blurMax: 64
|
||||||
|
blurMultiplier: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: lockContent
|
||||||
|
|
||||||
|
readonly property int size: lockIcon.implicitHeight + Tokens.padding.large * 4
|
||||||
|
readonly property int radius: size / 4 * Tokens.rounding.scale
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
implicitWidth: size
|
||||||
|
implicitHeight: size
|
||||||
|
|
||||||
|
rotation: 180
|
||||||
|
scale: 0
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
id: lockBg
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
captureSource: root.screen
|
color: Colours.palette.m3surface
|
||||||
opacity: 0
|
radius: parent.radius
|
||||||
|
opacity: Colours.transparency.enabled ? Colours.transparency.base : 1
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
autoPaddingEnabled: false
|
shadowEnabled: true
|
||||||
blurEnabled: true
|
blurMax: 15
|
||||||
blur: 1
|
shadowColor: Qt.alpha(Colours.palette.m3shadow, 0.7)
|
||||||
blurMax: 64
|
|
||||||
blurMultiplier: 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
MaterialIcon {
|
||||||
id: lockContent
|
id: lockIcon
|
||||||
|
|
||||||
readonly property int size: lockIcon.implicitHeight + Tokens.padding.large * 4
|
|
||||||
readonly property int radius: size / 4 * Tokens.rounding.scale
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: size
|
text: "lock"
|
||||||
implicitHeight: size
|
font.pointSize: Tokens.font.size.extraLarge * 4
|
||||||
|
font.bold: true
|
||||||
rotation: 180
|
rotation: 180
|
||||||
|
}
|
||||||
|
|
||||||
|
Content {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: (root.screen?.height ?? 0) * Tokens.sizes.lock.heightMult * Tokens.sizes.lock.ratio - Tokens.padding.large * 2
|
||||||
|
height: (root.screen?.height ?? 0) * Tokens.sizes.lock.heightMult - Tokens.padding.large * 2
|
||||||
|
|
||||||
|
lock: root
|
||||||
|
opacity: 0
|
||||||
scale: 0
|
scale: 0
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
id: lockBg
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Colours.palette.m3surface
|
|
||||||
radius: parent.radius
|
|
||||||
opacity: Colours.transparency.enabled ? Colours.transparency.base : 1
|
|
||||||
|
|
||||||
layer.enabled: true
|
|
||||||
layer.effect: MultiEffect {
|
|
||||||
shadowEnabled: true
|
|
||||||
blurMax: 15
|
|
||||||
shadowColor: Qt.alpha(Colours.palette.m3shadow, 0.7)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
id: lockIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: "lock"
|
|
||||||
font.pointSize: Tokens.font.size.extraLarge * 4
|
|
||||||
font.bold: true
|
|
||||||
rotation: 180
|
|
||||||
}
|
|
||||||
|
|
||||||
Content {
|
|
||||||
id: content
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: (root.screen?.height ?? 0) * Tokens.sizes.lock.heightMult * Tokens.sizes.lock.ratio - Tokens.padding.large * 2
|
|
||||||
height: (root.screen?.height ?? 0) * Tokens.sizes.lock.heightMult - Tokens.padding.large * 2
|
|
||||||
|
|
||||||
lock: root
|
|
||||||
opacity: 0
|
|
||||||
scale: 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools Core Qml Gui Quick Concurrent Sql Network DBus)
|
find_package(Qt6 REQUIRED COMPONENTS ShaderTools Core Qml Gui Quick QuickControls2 Concurrent Sql Network DBus)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED)
|
pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED)
|
||||||
pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED)
|
pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ qml_module(caelestia-config
|
||||||
configattached.cpp
|
configattached.cpp
|
||||||
configobject.cpp
|
configobject.cpp
|
||||||
rootconfig.cpp
|
rootconfig.cpp
|
||||||
configscope.cpp
|
|
||||||
appearanceconfig.cpp
|
appearanceconfig.cpp
|
||||||
tokens.cpp
|
tokens.cpp
|
||||||
tokensattached.cpp
|
tokensattached.cpp
|
||||||
|
|
@ -29,4 +28,5 @@ qml_module(caelestia-config
|
||||||
winfoconfig.hpp
|
winfoconfig.hpp
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::Quick
|
Qt::Quick
|
||||||
|
Qt::QuickControls2
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ namespace caelestia::config {
|
||||||
|
|
||||||
class AnimCurves;
|
class AnimCurves;
|
||||||
class AnimDurations;
|
class AnimDurations;
|
||||||
class ConfigScope;
|
|
||||||
|
|
||||||
class AnimTokens : public QObject {
|
class AnimTokens : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_MOC_INCLUDE("appearanceconfig.hpp")
|
Q_MOC_INCLUDE("tokens.hpp") // AnimCurves
|
||||||
|
Q_MOC_INCLUDE("appearanceconfig.hpp") // AnimDurations
|
||||||
QML_ANONYMOUS
|
QML_ANONYMOUS
|
||||||
|
|
||||||
Q_PROPERTY(QEasingCurve emphasized READ emphasized NOTIFY curvesChanged)
|
Q_PROPERTY(QEasingCurve emphasized READ emphasized NOTIFY curvesChanged)
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,56 @@
|
||||||
#include "configattached.hpp"
|
#include "configattached.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "configscope.hpp"
|
|
||||||
#include "monitorconfigmanager.hpp"
|
#include "monitorconfigmanager.hpp"
|
||||||
|
|
||||||
namespace caelestia::config {
|
namespace caelestia::config {
|
||||||
|
|
||||||
Config::Config(ConfigScope* scope, QObject* parent)
|
Config::Config(QObject* parent)
|
||||||
: QObject(parent)
|
: QQuickAttachedPropertyPropagator(parent) {
|
||||||
, m_scope(scope) {
|
initialize();
|
||||||
connectScope();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigScope* Config::scope() const {
|
QString Config::screen() const {
|
||||||
return m_scope;
|
return m_screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::connectScope() {
|
void Config::inheritScreen(const QString& screen) {
|
||||||
if (!m_scope)
|
if (screen == m_screen)
|
||||||
return;
|
return;
|
||||||
connect(m_scope, &ConfigScope::configChanged, this, &Config::sourceChanged);
|
|
||||||
connect(m_scope, &ConfigScope::tokensChanged, this, &Config::sourceChanged);
|
m_screen = screen;
|
||||||
|
|
||||||
|
if (m_screen.isEmpty())
|
||||||
|
m_config = nullptr;
|
||||||
|
else
|
||||||
|
m_config = MonitorConfigManager::instance()->configForScreen(m_screen);
|
||||||
|
|
||||||
|
propagateScreen();
|
||||||
|
emit sourceChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::propagateScreen() {
|
||||||
|
const auto children = attachedChildren();
|
||||||
|
for (auto* const child : children) {
|
||||||
|
auto* const config = qobject_cast<Config*>(child);
|
||||||
|
if (config)
|
||||||
|
config->inheritScreen(m_screen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::attachedParentChange(
|
||||||
|
QQuickAttachedPropertyPropagator* newParent, QQuickAttachedPropertyPropagator* oldParent) {
|
||||||
|
Q_UNUSED(oldParent);
|
||||||
|
auto* const config = qobject_cast<Config*>(newParent);
|
||||||
|
if (config)
|
||||||
|
inheritScreen(config->screen());
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_ATTACHED_GETTER(Type, name) \
|
#define CONFIG_ATTACHED_GETTER(Type, name) \
|
||||||
const Type* Config::name() const { \
|
const Type* Config::name() const { \
|
||||||
if (m_scope && m_scope->config()) \
|
if (m_config) \
|
||||||
return m_scope->config()->name(); \
|
return m_config->name(); \
|
||||||
if (parent()) \
|
if (parent()) \
|
||||||
qCWarning(lcConfig, "Config.%s accessed without a ConfigScope ancestor on %s", #name, \
|
qCWarning(lcConfig, "Config.%s accessed without a screen set on %s", #name, \
|
||||||
parent()->metaObject()->className()); \
|
parent()->metaObject()->className()); \
|
||||||
return GlobalConfig::instance()->name(); \
|
return GlobalConfig::instance()->name(); \
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +80,7 @@ GlobalConfig* Config::forScreen(const QString& screen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* Config::qmlAttachedProperties(QObject* object) {
|
Config* Config::qmlAttachedProperties(QObject* object) {
|
||||||
return new Config(ConfigScope::find(object), object);
|
return new Config(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace caelestia::config
|
} // namespace caelestia::config
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "configscope.hpp"
|
|
||||||
|
#include <qquickattachedpropertypropagator.h>
|
||||||
|
|
||||||
namespace caelestia::config {
|
namespace caelestia::config {
|
||||||
|
|
||||||
class Config : public QObject {
|
class Config : public QQuickAttachedPropertyPropagator {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
QML_UNCREATABLE("")
|
QML_UNCREATABLE("")
|
||||||
QML_ATTACHED(Config)
|
QML_ATTACHED(Config)
|
||||||
|
|
||||||
Q_PROPERTY(caelestia::config::ConfigScope* scope READ scope NOTIFY sourceChanged)
|
Q_PROPERTY(QString screen READ screen WRITE inheritScreen NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(const caelestia::config::AppearanceConfig* appearance READ appearance NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::AppearanceConfig* appearance READ appearance NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(const caelestia::config::GeneralConfig* general READ general NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::GeneralConfig* general READ general NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(const caelestia::config::BackgroundConfig* background READ background NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::BackgroundConfig* background READ background NOTIFY sourceChanged)
|
||||||
|
|
@ -31,9 +32,10 @@ class Config : public QObject {
|
||||||
Q_PROPERTY(const caelestia::config::UserPaths* paths READ paths NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::UserPaths* paths READ paths NOTIFY sourceChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Config(ConfigScope* scope, QObject* parent = nullptr);
|
explicit Config(QObject* parent = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] ConfigScope* scope() const;
|
[[nodiscard]] QString screen() const;
|
||||||
|
void inheritScreen(const QString& screen);
|
||||||
|
|
||||||
[[nodiscard]] const AppearanceConfig* appearance() const;
|
[[nodiscard]] const AppearanceConfig* appearance() const;
|
||||||
[[nodiscard]] const GeneralConfig* general() const;
|
[[nodiscard]] const GeneralConfig* general() const;
|
||||||
|
|
@ -60,10 +62,15 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void sourceChanged();
|
void sourceChanged();
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void connectScope();
|
void attachedParentChange(
|
||||||
|
QQuickAttachedPropertyPropagator* newParent, QQuickAttachedPropertyPropagator* oldParent) override;
|
||||||
|
|
||||||
ConfigScope* m_scope;
|
private:
|
||||||
|
void propagateScreen();
|
||||||
|
|
||||||
|
QString m_screen;
|
||||||
|
GlobalConfig* m_config = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace caelestia::config
|
} // namespace caelestia::config
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
#include "configscope.hpp"
|
|
||||||
#include "monitorconfigmanager.hpp"
|
|
||||||
|
|
||||||
namespace caelestia::config {
|
|
||||||
|
|
||||||
ConfigScope::ConfigScope(QQuickItem* parent)
|
|
||||||
: QQuickItem(parent) {}
|
|
||||||
|
|
||||||
QString ConfigScope::screen() const {
|
|
||||||
return m_screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalConfig* ConfigScope::config() const {
|
|
||||||
return m_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenConfig* ConfigScope::tokens() const {
|
|
||||||
return m_tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigScope::setScreen(const QString& screen) {
|
|
||||||
if (m_screen == screen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_screen = screen;
|
|
||||||
emit screenChanged();
|
|
||||||
resolveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigScope::resolveConfig() {
|
|
||||||
GlobalConfig* newConfig = nullptr;
|
|
||||||
TokenConfig* newTokens = nullptr;
|
|
||||||
|
|
||||||
if (!m_screen.isEmpty()) {
|
|
||||||
if (auto* mgr = MonitorConfigManager::instance()) {
|
|
||||||
newConfig = mgr->configForScreen(m_screen);
|
|
||||||
newTokens = mgr->tokensForScreen(m_screen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_config != newConfig) {
|
|
||||||
m_config = newConfig;
|
|
||||||
emit configChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_tokens != newTokens) {
|
|
||||||
m_tokens = newTokens;
|
|
||||||
emit tokensChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigScope* ConfigScope::find(QObject* object) {
|
|
||||||
auto* item = qobject_cast<QQuickItem*>(object);
|
|
||||||
|
|
||||||
while (item) {
|
|
||||||
if (auto* scope = qobject_cast<ConfigScope*>(item))
|
|
||||||
return scope;
|
|
||||||
item = item->parentItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace caelestia::config
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <qqmlintegration.h>
|
|
||||||
#include <qquickitem.h>
|
|
||||||
|
|
||||||
namespace caelestia::config {
|
|
||||||
|
|
||||||
class GlobalConfig;
|
|
||||||
class TokenConfig;
|
|
||||||
|
|
||||||
class ConfigScope : public QQuickItem {
|
|
||||||
Q_OBJECT
|
|
||||||
Q_MOC_INCLUDE("config.hpp")
|
|
||||||
Q_MOC_INCLUDE("tokens.hpp")
|
|
||||||
QML_ELEMENT
|
|
||||||
|
|
||||||
Q_PROPERTY(QString screen READ screen WRITE setScreen NOTIFY screenChanged)
|
|
||||||
Q_PROPERTY(caelestia::config::GlobalConfig* config READ config NOTIFY configChanged)
|
|
||||||
Q_PROPERTY(caelestia::config::TokenConfig* tokens READ tokens NOTIFY tokensChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ConfigScope(QQuickItem* parent = nullptr);
|
|
||||||
|
|
||||||
[[nodiscard]] QString screen() const;
|
|
||||||
void setScreen(const QString& screen);
|
|
||||||
|
|
||||||
[[nodiscard]] GlobalConfig* config() const;
|
|
||||||
[[nodiscard]] TokenConfig* tokens() const;
|
|
||||||
|
|
||||||
static ConfigScope* find(QObject* object);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void screenChanged();
|
|
||||||
void configChanged();
|
|
||||||
void tokensChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void resolveConfig();
|
|
||||||
|
|
||||||
QString m_screen;
|
|
||||||
GlobalConfig* m_config = nullptr;
|
|
||||||
TokenConfig* m_tokens = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace caelestia::config
|
|
||||||
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
namespace caelestia::config {
|
namespace caelestia::config {
|
||||||
|
|
||||||
class ConfigScope;
|
|
||||||
|
|
||||||
class AnimCurves : public ConfigObject {
|
class AnimCurves : public ConfigObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_ANONYMOUS
|
QML_ANONYMOUS
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#include "tokensattached.hpp"
|
#include "tokensattached.hpp"
|
||||||
#include "anim.hpp"
|
#include "anim.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "configscope.hpp"
|
|
||||||
#include "monitorconfigmanager.hpp"
|
#include "monitorconfigmanager.hpp"
|
||||||
#include "tokens.hpp"
|
#include "tokens.hpp"
|
||||||
|
|
||||||
|
|
@ -9,29 +8,60 @@ namespace caelestia::config {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const AppearanceConfig* resolveAppearance(ConfigScope* scope, const char* prop, QObject* parent) {
|
const AppearanceConfig* resolveAppearance(GlobalConfig* config, const char* prop, QObject* parent) {
|
||||||
if (scope && scope->config())
|
if (config)
|
||||||
return scope->config()->appearance();
|
return config->appearance();
|
||||||
if (parent)
|
if (parent)
|
||||||
qCWarning(lcConfig, "Tokens.%s accessed without a ConfigScope ancestor on %s", prop,
|
qCWarning(lcConfig, "Tokens.%s accessed without a screen set on %s", prop, parent->metaObject()->className());
|
||||||
parent->metaObject()->className());
|
|
||||||
return GlobalConfig::instance()->appearance();
|
return GlobalConfig::instance()->appearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Tokens::Tokens(ConfigScope* scope, QObject* parent)
|
Tokens::Tokens(QObject* parent)
|
||||||
: QObject(parent)
|
: QQuickAttachedPropertyPropagator(parent)
|
||||||
, m_scope(scope)
|
|
||||||
, m_anim(new AnimTokens(this)) {
|
, m_anim(new AnimTokens(this)) {
|
||||||
connectScope();
|
|
||||||
bindAnim();
|
bindAnim();
|
||||||
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tokens::connectScope() {
|
QString Tokens::screen() const {
|
||||||
if (!m_scope)
|
return m_screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tokens::inheritScreen(const QString& screen) {
|
||||||
|
if (screen == m_screen)
|
||||||
return;
|
return;
|
||||||
connect(m_scope, &ConfigScope::configChanged, this, &Tokens::sourceChanged);
|
|
||||||
|
m_screen = screen;
|
||||||
|
|
||||||
|
if (m_screen.isEmpty()) {
|
||||||
|
m_config = nullptr;
|
||||||
|
m_tokens = nullptr;
|
||||||
|
} else {
|
||||||
|
m_config = MonitorConfigManager::instance()->configForScreen(m_screen);
|
||||||
|
m_tokens = MonitorConfigManager::instance()->tokensForScreen(m_screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
propagateScreen();
|
||||||
|
emit sourceChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tokens::propagateScreen() {
|
||||||
|
const auto children = attachedChildren();
|
||||||
|
for (auto* const child : children) {
|
||||||
|
auto* const tokens = qobject_cast<Tokens*>(child);
|
||||||
|
if (tokens)
|
||||||
|
tokens->inheritScreen(m_screen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tokens::attachedParentChange(
|
||||||
|
QQuickAttachedPropertyPropagator* newParent, QQuickAttachedPropertyPropagator* oldParent) {
|
||||||
|
Q_UNUSED(oldParent);
|
||||||
|
auto* const tokens = qobject_cast<Tokens*>(newParent);
|
||||||
|
if (tokens)
|
||||||
|
inheritScreen(tokens->screen());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tokens::bindAnim() {
|
void Tokens::bindAnim() {
|
||||||
|
|
@ -41,7 +71,7 @@ void Tokens::bindAnim() {
|
||||||
|
|
||||||
#define TOKENS_ATTACHED_GETTER(Type, name) \
|
#define TOKENS_ATTACHED_GETTER(Type, name) \
|
||||||
const Type* Tokens::name() const { \
|
const Type* Tokens::name() const { \
|
||||||
auto* a = resolveAppearance(m_scope, #name, parent()); \
|
auto* a = resolveAppearance(m_config, #name, parent()); \
|
||||||
return a ? a->name() : nullptr; \
|
return a ? a->name() : nullptr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,11 +87,10 @@ const AppearanceTransparency* Tokens::transparency() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SizeTokens* Tokens::sizes() const {
|
const SizeTokens* Tokens::sizes() const {
|
||||||
if (m_scope && m_scope->tokens())
|
if (m_tokens)
|
||||||
return m_scope->tokens()->sizes();
|
return m_tokens->sizes();
|
||||||
if (parent())
|
if (parent())
|
||||||
qCWarning(lcConfig, "Tokens.sizes accessed without a ConfigScope ancestor on %s",
|
qCWarning(lcConfig, "Tokens.sizes accessed without a screen set on %s", parent()->metaObject()->className());
|
||||||
parent()->metaObject()->className());
|
|
||||||
return TokenConfig::instance()->sizes();
|
return TokenConfig::instance()->sizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +103,7 @@ TokenConfig* Tokens::forScreen(const QString& screen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Tokens* Tokens::qmlAttachedProperties(QObject* object) {
|
Tokens* Tokens::qmlAttachedProperties(QObject* object) {
|
||||||
return new Tokens(ConfigScope::find(object), object);
|
return new Tokens(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace caelestia::config
|
} // namespace caelestia::config
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,20 @@
|
||||||
|
|
||||||
#include "anim.hpp"
|
#include "anim.hpp"
|
||||||
#include "appearanceconfig.hpp"
|
#include "appearanceconfig.hpp"
|
||||||
#include "configscope.hpp"
|
#include "config.hpp"
|
||||||
#include "tokens.hpp"
|
#include "tokens.hpp"
|
||||||
|
|
||||||
|
#include <qquickattachedpropertypropagator.h>
|
||||||
|
|
||||||
namespace caelestia::config {
|
namespace caelestia::config {
|
||||||
|
|
||||||
class Tokens : public QObject {
|
class Tokens : public QQuickAttachedPropertyPropagator {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
QML_UNCREATABLE("")
|
QML_UNCREATABLE("")
|
||||||
QML_ATTACHED(Tokens)
|
QML_ATTACHED(Tokens)
|
||||||
|
|
||||||
|
Q_PROPERTY(QString screen READ screen WRITE inheritScreen NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(const caelestia::config::AppearanceRounding* rounding READ rounding NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::AppearanceRounding* rounding READ rounding NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(const caelestia::config::AppearanceSpacing* spacing READ spacing NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::AppearanceSpacing* spacing READ spacing NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(const caelestia::config::AppearancePadding* padding READ padding NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::AppearancePadding* padding READ padding NOTIFY sourceChanged)
|
||||||
|
|
@ -22,7 +25,10 @@ class Tokens : public QObject {
|
||||||
Q_PROPERTY(const caelestia::config::AnimTokens* anim READ anim NOTIFY sourceChanged)
|
Q_PROPERTY(const caelestia::config::AnimTokens* anim READ anim NOTIFY sourceChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Tokens(ConfigScope* scope, QObject* parent = nullptr);
|
explicit Tokens(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
[[nodiscard]] QString screen() const;
|
||||||
|
void inheritScreen(const QString& screen);
|
||||||
|
|
||||||
[[nodiscard]] const AppearanceRounding* rounding() const;
|
[[nodiscard]] const AppearanceRounding* rounding() const;
|
||||||
[[nodiscard]] const AppearanceSpacing* spacing() const;
|
[[nodiscard]] const AppearanceSpacing* spacing() const;
|
||||||
|
|
@ -40,11 +46,17 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void sourceChanged();
|
void sourceChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void attachedParentChange(
|
||||||
|
QQuickAttachedPropertyPropagator* newParent, QQuickAttachedPropertyPropagator* oldParent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void connectScope();
|
void propagateScreen();
|
||||||
void bindAnim();
|
void bindAnim();
|
||||||
|
|
||||||
ConfigScope* m_scope;
|
QString m_screen;
|
||||||
|
GlobalConfig* m_config = nullptr;
|
||||||
|
TokenConfig* m_tokens = nullptr;
|
||||||
AnimTokens* m_anim = nullptr;
|
AnimTokens* m_anim = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue