forked from quickshell/quickshell
feat: add PersistentProperties
This commit is contained in:
parent
ed62193978
commit
083fff57be
|
@ -39,6 +39,7 @@ qt_add_executable(quickshell
|
|||
src/cpp/qmlscreen.cpp
|
||||
src/cpp/watcher.cpp
|
||||
src/cpp/region.cpp
|
||||
src/cpp/persistentprops.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(quickshell URI QuickShell)
|
||||
|
|
|
@ -9,6 +9,7 @@ headers = [
|
|||
"proxywindow.hpp",
|
||||
"layershell.hpp",
|
||||
"region.hpp",
|
||||
"persistentprops.hpp",
|
||||
]
|
||||
-----
|
||||
The core types provided by QuickShell
|
||||
|
|
24
src/cpp/persistentprops.cpp
Normal file
24
src/cpp/persistentprops.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "persistentprops.hpp"
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
void PersistentProperties::onReload(QObject* oldInstance) {
|
||||
if (qobject_cast<PersistentProperties*>(oldInstance) == nullptr) {
|
||||
emit this->loaded();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* metaObject = this->metaObject();
|
||||
for (auto i = metaObject->propertyOffset(); i < metaObject->propertyCount(); i++) {
|
||||
const auto prop = metaObject->property(i);
|
||||
auto oldProp = oldInstance->property(prop.name());
|
||||
|
||||
if (oldProp.isValid()) {
|
||||
this->setProperty(prop.name(), oldProp);
|
||||
}
|
||||
}
|
||||
|
||||
emit this->loaded();
|
||||
emit this->reloaded();
|
||||
}
|
57
src/cpp/persistentprops.hpp
Normal file
57
src/cpp/persistentprops.hpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
#include "reload.hpp"
|
||||
|
||||
///! Object that holds properties that can persist across a config reload.
|
||||
/// PersistentProperties holds properties declated in it across a reload, which is
|
||||
/// often useful for things like keeping expandable popups open and styling them.
|
||||
///
|
||||
/// Below is an example of using `PersistentProperties` to keep track of the state
|
||||
/// of an expandable panel. When the configuration is reloaded, the `expanderOpen` property
|
||||
/// will be saved and the expandable panel will stay in the open/closed state.
|
||||
///
|
||||
/// ```qml
|
||||
/// PersistentProperties {
|
||||
/// id: persist
|
||||
/// reloadableId: "persistedStates"
|
||||
///
|
||||
/// property bool expanderOpen: false
|
||||
/// }
|
||||
///
|
||||
/// Button {
|
||||
/// id: expanderButton
|
||||
/// anchors.centerIn: parent
|
||||
/// text: "toggle expander"
|
||||
/// onClicked: persist.expanderOpen = !persist.expanderOpen
|
||||
/// }
|
||||
///
|
||||
/// Rectangle {
|
||||
/// anchors.top: expanderButton.bottom
|
||||
/// anchors.left: expanderButton.left
|
||||
/// anchors.right: expanderButton.right
|
||||
/// height: 100
|
||||
///
|
||||
/// color: "lightblue"
|
||||
/// visible: persist.expanderOpen
|
||||
/// }
|
||||
/// ```
|
||||
class PersistentProperties: public Reloadable {
|
||||
Q_OBJECT;
|
||||
QML_ELEMENT;
|
||||
|
||||
public:
|
||||
PersistentProperties(QObject* parent = nullptr): Reloadable(parent) {}
|
||||
|
||||
void onReload(QObject* oldInstance) override;
|
||||
|
||||
signals:
|
||||
/// Called every time the reload stage completes.
|
||||
/// Will be called every time, including when nothing was loaded from an old instance.
|
||||
void loaded();
|
||||
/// Called every time the properties are reloaded.
|
||||
/// Will not be called if no old instance was loaded.
|
||||
void reloaded();
|
||||
};
|
|
@ -52,7 +52,9 @@ class Reloadable: public QObject, public QQmlParserStatus {
|
|||
public:
|
||||
explicit Reloadable(QObject* parent = nullptr): QObject(parent) {}
|
||||
|
||||
/// called unconditionally in the reload phase, with nullptr if no source could be determined
|
||||
// Called unconditionally in the reload phase, with nullptr if no source could be determined.
|
||||
// If non null the old instance may or may not be of the same type, and should be checked
|
||||
// by `onReload`.
|
||||
virtual void onReload(QObject* oldInstance) = 0;
|
||||
|
||||
// TODO: onReload runs after initialization for reloadable objects created late
|
||||
|
|
Loading…
Reference in a new issue