|
@@ -27,6 +27,7 @@
|
|
#pragma once
|
|
#pragma once
|
|
|
|
|
|
#include <AK/Forward.h>
|
|
#include <AK/Forward.h>
|
|
|
|
+#include <AK/HashMap.h>
|
|
#include <AK/IntrusiveList.h>
|
|
#include <AK/IntrusiveList.h>
|
|
#include <AK/Noncopyable.h>
|
|
#include <AK/Noncopyable.h>
|
|
#include <AK/NonnullRefPtrVector.h>
|
|
#include <AK/NonnullRefPtrVector.h>
|
|
@@ -34,6 +35,7 @@
|
|
#include <AK/TypeCasts.h>
|
|
#include <AK/TypeCasts.h>
|
|
#include <AK/Weakable.h>
|
|
#include <AK/Weakable.h>
|
|
#include <LibCore/Forward.h>
|
|
#include <LibCore/Forward.h>
|
|
|
|
+#include <LibCore/Property.h>
|
|
|
|
|
|
namespace Core {
|
|
namespace Core {
|
|
|
|
|
|
@@ -112,8 +114,10 @@ public:
|
|
virtual bool is_action() const { return false; }
|
|
virtual bool is_action() const { return false; }
|
|
virtual bool is_window() const { return false; }
|
|
virtual bool is_window() const { return false; }
|
|
|
|
|
|
- virtual void save_to(AK::JsonObject&);
|
|
|
|
- virtual bool set_property(const StringView& name, const JsonValue& value);
|
|
|
|
|
|
+ void save_to(AK::JsonObject&);
|
|
|
|
+
|
|
|
|
+ bool set_property(const StringView& name, const JsonValue& value);
|
|
|
|
+ JsonValue property(const StringView& name);
|
|
|
|
|
|
static IntrusiveList<Object, &Object::m_all_objects_list_node>& all_objects();
|
|
static IntrusiveList<Object, &Object::m_all_objects_list_node>& all_objects();
|
|
|
|
|
|
@@ -143,6 +147,8 @@ public:
|
|
protected:
|
|
protected:
|
|
explicit Object(Object* parent = nullptr, bool is_widget = false);
|
|
explicit Object(Object* parent = nullptr, bool is_widget = false);
|
|
|
|
|
|
|
|
+ void register_property(const String& name, Function<JsonValue()> getter, Function<bool(const JsonValue&)> setter = nullptr);
|
|
|
|
+
|
|
virtual void timer_event(TimerEvent&);
|
|
virtual void timer_event(TimerEvent&);
|
|
virtual void custom_event(CustomEvent&);
|
|
virtual void custom_event(CustomEvent&);
|
|
|
|
|
|
@@ -158,6 +164,7 @@ private:
|
|
int m_timer_id { 0 };
|
|
int m_timer_id { 0 };
|
|
unsigned m_inspector_count { 0 };
|
|
unsigned m_inspector_count { 0 };
|
|
bool m_widget { false };
|
|
bool m_widget { false };
|
|
|
|
+ HashMap<String, NonnullOwnPtr<Property>> m_properties;
|
|
NonnullRefPtrVector<Object> m_children;
|
|
NonnullRefPtrVector<Object> m_children;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -176,4 +183,103 @@ inline void Object::for_each_child_of_type(Callback callback)
|
|
|
|
|
|
const LogStream& operator<<(const LogStream&, const Object&);
|
|
const LogStream& operator<<(const LogStream&, const Object&);
|
|
|
|
|
|
|
|
+#define REGISTER_INT_PROPERTY(property_name, getter, setter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, \
|
|
|
|
+ [this] { return this->getter(); }, \
|
|
|
|
+ [this](auto& value) { \
|
|
|
|
+ this->setter(value.template to_number<int>()); \
|
|
|
|
+ return true; \
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+#define REGISTER_BOOL_PROPERTY(property_name, getter, setter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, \
|
|
|
|
+ [this] { return this->getter(); }, \
|
|
|
|
+ [this](auto& value) { \
|
|
|
|
+ this->setter(value.to_bool()); \
|
|
|
|
+ return true; \
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+#define REGISTER_STRING_PROPERTY(property_name, getter, setter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, \
|
|
|
|
+ [this] { return this->getter(); }, \
|
|
|
|
+ [this](auto& value) { \
|
|
|
|
+ this->setter(value.to_string()); \
|
|
|
|
+ return true; \
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+#define REGISTER_READONLY_STRING_PROPERTY(property_name, getter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, \
|
|
|
|
+ [this] { return this->getter(); }, \
|
|
|
|
+ nullptr);
|
|
|
|
+
|
|
|
|
+#define REGISTER_RECT_PROPERTY(property_name, getter, setter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, \
|
|
|
|
+ [this] { \
|
|
|
|
+ auto rect = this->getter(); \
|
|
|
|
+ JsonObject rect_object; \
|
|
|
|
+ rect_object.set("x", rect.x()); \
|
|
|
|
+ rect_object.set("y", rect.y()); \
|
|
|
|
+ rect_object.set("width", rect.width()); \
|
|
|
|
+ rect_object.set("height", rect.height()); \
|
|
|
|
+ return rect_object; \
|
|
|
|
+ }, \
|
|
|
|
+ [this](auto& value) { \
|
|
|
|
+ if (!value.is_object()) \
|
|
|
|
+ return false; \
|
|
|
|
+ Gfx::IntRect rect; \
|
|
|
|
+ rect.set_x(value.as_object().get("x").to_i32()); \
|
|
|
|
+ rect.set_y(value.as_object().get("y").to_i32()); \
|
|
|
|
+ rect.set_width(value.as_object().get("width").to_i32()); \
|
|
|
|
+ rect.set_height(value.as_object().get("height").to_i32()); \
|
|
|
|
+ setter(rect); \
|
|
|
|
+ return true; \
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+#define REGISTER_SIZE_PROPERTY(property_name, getter, setter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, \
|
|
|
|
+ [this] { \
|
|
|
|
+ auto size = this->getter(); \
|
|
|
|
+ JsonObject size_object; \
|
|
|
|
+ size_object.set("width", size.width()); \
|
|
|
|
+ size_object.set("height", size.height()); \
|
|
|
|
+ return size_object; \
|
|
|
|
+ }, \
|
|
|
|
+ [this](auto& value) { \
|
|
|
|
+ if (!value.is_object()) \
|
|
|
|
+ return false; \
|
|
|
|
+ Gfx::IntSize size; \
|
|
|
|
+ size.set_width(value.as_object().get("width").to_i32()); \
|
|
|
|
+ size.set_height(value.as_object().get("height").to_i32()); \
|
|
|
|
+ setter(size); \
|
|
|
|
+ return true; \
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+#define REGISTER_SIZE_POLICY_PROPERTY(property_name, getter, setter) \
|
|
|
|
+ register_property( \
|
|
|
|
+ property_name, [this]() -> JsonValue { \
|
|
|
|
+ auto policy = this->getter(); \
|
|
|
|
+ if (policy == GUI::SizePolicy::Fill) \
|
|
|
|
+ return "Fill"; \
|
|
|
|
+ if (policy == GUI::SizePolicy::Fixed) \
|
|
|
|
+ return "Fixed"; \
|
|
|
|
+ return JsonValue(); }, \
|
|
|
|
+ [this](auto& value) { \
|
|
|
|
+ if (!value.is_string()) \
|
|
|
|
+ return false; \
|
|
|
|
+ if (value.as_string() == "Fill") { \
|
|
|
|
+ setter(GUI::SizePolicy::Fill); \
|
|
|
|
+ return true; \
|
|
|
|
+ } \
|
|
|
|
+ if (value.as_string() == "Fixed") { \
|
|
|
|
+ setter(GUI::SizePolicy::Fixed); \
|
|
|
|
+ return true; \
|
|
|
|
+ } \
|
|
|
|
+ return false; \
|
|
|
|
+ });
|
|
}
|
|
}
|