From 849fdc1c0b2be599932447c3751dbc303d634ae1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 5 Mar 2020 09:21:46 +0100 Subject: LibGUI: Make Layout a Core::Object and add basic serialization This allows you to view layouts (as data) in Inspector. --- Libraries/LibGUI/BoxLayout.cpp | 7 +++++++ Libraries/LibGUI/BoxLayout.h | 9 ++++++++- Libraries/LibGUI/Layout.cpp | 29 +++++++++++++++++++++++++++++ Libraries/LibGUI/Layout.h | 10 ++++++++-- Libraries/LibGUI/Splitter.cpp | 2 +- Libraries/LibGUI/ToolBar.cpp | 2 +- Libraries/LibGUI/Widget.cpp | 7 +++++-- Libraries/LibGUI/Widget.h | 13 +++++++------ 8 files changed, 66 insertions(+), 13 deletions(-) (limited to 'Libraries/LibGUI') diff --git a/Libraries/LibGUI/BoxLayout.cpp b/Libraries/LibGUI/BoxLayout.cpp index 6a313517af..5d48fd2dd5 100644 --- a/Libraries/LibGUI/BoxLayout.cpp +++ b/Libraries/LibGUI/BoxLayout.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -174,4 +175,10 @@ void BoxLayout::run(Widget& widget) } } +void BoxLayout::save_to(JsonObject& json) +{ + Layout::save_to(json); + json.set("orientation", m_orientation == Gfx::Orientation::Vertical ? "Vertical" : "Horizontal"); +} + } diff --git a/Libraries/LibGUI/BoxLayout.h b/Libraries/LibGUI/BoxLayout.h index 5f0c85ee65..57694e95d0 100644 --- a/Libraries/LibGUI/BoxLayout.h +++ b/Libraries/LibGUI/BoxLayout.h @@ -33,19 +33,25 @@ namespace GUI { class BoxLayout : public Layout { + C_OBJECT(BoxLayout); public: - explicit BoxLayout(Gfx::Orientation); virtual ~BoxLayout() override {} Gfx::Orientation orientation() const { return m_orientation; } virtual void run(Widget&) override; +protected: + explicit BoxLayout(Gfx::Orientation); + + virtual void save_to(JsonObject &) override; + private: Gfx::Orientation m_orientation; }; class VerticalBoxLayout final : public BoxLayout { + C_OBJECT(VerticalBoxLayout); public: explicit VerticalBoxLayout() : BoxLayout(Gfx::Orientation::Vertical) @@ -55,6 +61,7 @@ public: }; class HorizontalBoxLayout final : public BoxLayout { + C_OBJECT(HorizontalBoxLayout); public: explicit HorizontalBoxLayout() : BoxLayout(Gfx::Orientation::Horizontal) diff --git a/Libraries/LibGUI/Layout.cpp b/Libraries/LibGUI/Layout.cpp index e5a6e57a53..38be0a87e1 100644 --- a/Libraries/LibGUI/Layout.cpp +++ b/Libraries/LibGUI/Layout.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include @@ -120,4 +121,32 @@ void Layout::set_margins(const Margins& margins) m_owner->notify_layout_changed({}); } +void Layout::save_to(JsonObject& json) +{ + Core::Object::save_to(json); + json.set("spacing", m_spacing); + + JsonObject margins_object; + margins_object.set("left", m_margins.left()); + margins_object.set("right", m_margins.right()); + margins_object.set("top", m_margins.top()); + margins_object.set("bottom", m_margins.bottom()); + json.set("margins", move(margins_object)); + + JsonArray entries_array; + for (auto& entry : m_entries) { + JsonObject entry_object; + if (entry.type == Entry::Type::Widget) { + entry_object.set("type", "Widget"); + entry_object.set("widget", (uintptr_t)entry.widget.ptr()); + } else if (entry.type == Entry::Type::Spacer) { + entry_object.set("type", "Spacer"); + } else { + ASSERT_NOT_REACHED(); + } + entries_array.append(move(entry_object)); + } + json.set("entries", move(entries_array)); +} + } diff --git a/Libraries/LibGUI/Layout.h b/Libraries/LibGUI/Layout.h index f10555182a..1d4bfc0d9d 100644 --- a/Libraries/LibGUI/Layout.h +++ b/Libraries/LibGUI/Layout.h @@ -29,14 +29,16 @@ #include #include #include +#include #include #include namespace GUI { -class Layout { +class Layout : public Core::Object { + C_OBJECT_ABSTRACT(Layout); + public: - Layout(); virtual ~Layout(); void add_widget(Widget&); @@ -57,7 +59,11 @@ public: int spacing() const { return m_spacing; } void set_spacing(int); + virtual void save_to(JsonObject&) override; + protected: + Layout(); + struct Entry { enum class Type { Invalid = 0, diff --git a/Libraries/LibGUI/Splitter.cpp b/Libraries/LibGUI/Splitter.cpp index 671c540776..b58113f09b 100644 --- a/Libraries/LibGUI/Splitter.cpp +++ b/Libraries/LibGUI/Splitter.cpp @@ -36,7 +36,7 @@ Splitter::Splitter(Orientation orientation) : m_orientation(orientation) { set_background_role(ColorRole::Button); - set_layout(make(orientation)); + set_layout(orientation); set_fill_with_background_color(true); layout()->set_spacing(4); } diff --git a/Libraries/LibGUI/ToolBar.cpp b/Libraries/LibGUI/ToolBar.cpp index fb56811211..e93a31c3fb 100644 --- a/Libraries/LibGUI/ToolBar.cpp +++ b/Libraries/LibGUI/ToolBar.cpp @@ -44,7 +44,7 @@ ToolBar::ToolBar(Orientation orientation, int button_size) set_size_policy(SizePolicy::Fixed, SizePolicy::Fill); set_preferred_size(button_size + 12, 0); } - set_layout(make(orientation)); + set_layout(orientation); layout()->set_spacing(0); layout()->set_margins({ 2, 2, 2, 2 }); } diff --git a/Libraries/LibGUI/Widget.cpp b/Libraries/LibGUI/Widget.cpp index 6020d65c50..08d2273f57 100644 --- a/Libraries/LibGUI/Widget.cpp +++ b/Libraries/LibGUI/Widget.cpp @@ -242,12 +242,15 @@ void Widget::handle_paint_event(PaintEvent& event) second_paint_event(event); } -void Widget::set_layout(OwnPtr&& layout) +void Widget::set_layout(NonnullRefPtr layout) { - if (m_layout) + if (m_layout) { m_layout->notify_disowned({}, *this); + m_layout->remove_from_parent(); + } m_layout = move(layout); if (m_layout) { + add_child(*m_layout); m_layout->notify_adopted({}, *this); do_layout(); } else { diff --git a/Libraries/LibGUI/Widget.h b/Libraries/LibGUI/Widget.h index 7e37f5a32e..b0e4b5e3cd 100644 --- a/Libraries/LibGUI/Widget.h +++ b/Libraries/LibGUI/Widget.h @@ -96,13 +96,14 @@ public: Layout* layout() { return m_layout.ptr(); } const Layout* layout() const { return m_layout.ptr(); } - void set_layout(OwnPtr&&); + void set_layout(NonnullRefPtr); - template - T& set_layout() + template + inline T& set_layout(Args&&... args) { - set_layout(make()); - return static_cast(*layout()); + auto layout = T::construct(forward(args)...); + set_layout(*layout); + return layout; } SizePolicy horizontal_size_policy() const { return m_horizontal_size_policy; } @@ -304,7 +305,7 @@ private: void focus_next_widget(); Window* m_window { nullptr }; - OwnPtr m_layout; + RefPtr m_layout; Gfx::Rect m_relative_rect; Gfx::ColorRole m_background_role; -- cgit v1.2.3