mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:37:44 +00:00
LibGUI: Make Layout a Core::Object and add basic serialization
This allows you to view layouts (as data) in Inspector.
This commit is contained in:
parent
ecc39678f5
commit
849fdc1c0b
8 changed files with 66 additions and 13 deletions
|
@ -24,6 +24,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/JsonObject.h>
|
||||||
#include <LibGUI/BoxLayout.h>
|
#include <LibGUI/BoxLayout.h>
|
||||||
#include <LibGUI/Widget.h>
|
#include <LibGUI/Widget.h>
|
||||||
#include <LibGfx/Orientation.h>
|
#include <LibGfx/Orientation.h>
|
||||||
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,19 +33,25 @@
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
class BoxLayout : public Layout {
|
class BoxLayout : public Layout {
|
||||||
|
C_OBJECT(BoxLayout);
|
||||||
public:
|
public:
|
||||||
explicit BoxLayout(Gfx::Orientation);
|
|
||||||
virtual ~BoxLayout() override {}
|
virtual ~BoxLayout() override {}
|
||||||
|
|
||||||
Gfx::Orientation orientation() const { return m_orientation; }
|
Gfx::Orientation orientation() const { return m_orientation; }
|
||||||
|
|
||||||
virtual void run(Widget&) override;
|
virtual void run(Widget&) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit BoxLayout(Gfx::Orientation);
|
||||||
|
|
||||||
|
virtual void save_to(JsonObject &) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gfx::Orientation m_orientation;
|
Gfx::Orientation m_orientation;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VerticalBoxLayout final : public BoxLayout {
|
class VerticalBoxLayout final : public BoxLayout {
|
||||||
|
C_OBJECT(VerticalBoxLayout);
|
||||||
public:
|
public:
|
||||||
explicit VerticalBoxLayout()
|
explicit VerticalBoxLayout()
|
||||||
: BoxLayout(Gfx::Orientation::Vertical)
|
: BoxLayout(Gfx::Orientation::Vertical)
|
||||||
|
@ -55,6 +61,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class HorizontalBoxLayout final : public BoxLayout {
|
class HorizontalBoxLayout final : public BoxLayout {
|
||||||
|
C_OBJECT(HorizontalBoxLayout);
|
||||||
public:
|
public:
|
||||||
explicit HorizontalBoxLayout()
|
explicit HorizontalBoxLayout()
|
||||||
: BoxLayout(Gfx::Orientation::Horizontal)
|
: BoxLayout(Gfx::Orientation::Horizontal)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
|
#include <AK/JsonObject.h>
|
||||||
#include <LibGUI/Layout.h>
|
#include <LibGUI/Layout.h>
|
||||||
#include <LibGUI/Widget.h>
|
#include <LibGUI/Widget.h>
|
||||||
|
|
||||||
|
@ -120,4 +121,32 @@ void Layout::set_margins(const Margins& margins)
|
||||||
m_owner->notify_layout_changed({});
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,16 @@
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <AK/WeakPtr.h>
|
#include <AK/WeakPtr.h>
|
||||||
|
#include <LibCore/Object.h>
|
||||||
#include <LibGUI/Forward.h>
|
#include <LibGUI/Forward.h>
|
||||||
#include <LibGUI/Margins.h>
|
#include <LibGUI/Margins.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
class Layout {
|
class Layout : public Core::Object {
|
||||||
|
C_OBJECT_ABSTRACT(Layout);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Layout();
|
|
||||||
virtual ~Layout();
|
virtual ~Layout();
|
||||||
|
|
||||||
void add_widget(Widget&);
|
void add_widget(Widget&);
|
||||||
|
@ -57,7 +59,11 @@ public:
|
||||||
int spacing() const { return m_spacing; }
|
int spacing() const { return m_spacing; }
|
||||||
void set_spacing(int);
|
void set_spacing(int);
|
||||||
|
|
||||||
|
virtual void save_to(JsonObject&) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Layout();
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
|
|
|
@ -36,7 +36,7 @@ Splitter::Splitter(Orientation orientation)
|
||||||
: m_orientation(orientation)
|
: m_orientation(orientation)
|
||||||
{
|
{
|
||||||
set_background_role(ColorRole::Button);
|
set_background_role(ColorRole::Button);
|
||||||
set_layout(make<BoxLayout>(orientation));
|
set_layout<BoxLayout>(orientation);
|
||||||
set_fill_with_background_color(true);
|
set_fill_with_background_color(true);
|
||||||
layout()->set_spacing(4);
|
layout()->set_spacing(4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ ToolBar::ToolBar(Orientation orientation, int button_size)
|
||||||
set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
|
set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
|
||||||
set_preferred_size(button_size + 12, 0);
|
set_preferred_size(button_size + 12, 0);
|
||||||
}
|
}
|
||||||
set_layout(make<BoxLayout>(orientation));
|
set_layout<BoxLayout>(orientation);
|
||||||
layout()->set_spacing(0);
|
layout()->set_spacing(0);
|
||||||
layout()->set_margins({ 2, 2, 2, 2 });
|
layout()->set_margins({ 2, 2, 2, 2 });
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,12 +242,15 @@ void Widget::handle_paint_event(PaintEvent& event)
|
||||||
second_paint_event(event);
|
second_paint_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::set_layout(OwnPtr<Layout>&& layout)
|
void Widget::set_layout(NonnullRefPtr<Layout> layout)
|
||||||
{
|
{
|
||||||
if (m_layout)
|
if (m_layout) {
|
||||||
m_layout->notify_disowned({}, *this);
|
m_layout->notify_disowned({}, *this);
|
||||||
|
m_layout->remove_from_parent();
|
||||||
|
}
|
||||||
m_layout = move(layout);
|
m_layout = move(layout);
|
||||||
if (m_layout) {
|
if (m_layout) {
|
||||||
|
add_child(*m_layout);
|
||||||
m_layout->notify_adopted({}, *this);
|
m_layout->notify_adopted({}, *this);
|
||||||
do_layout();
|
do_layout();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -96,13 +96,14 @@ public:
|
||||||
|
|
||||||
Layout* layout() { return m_layout.ptr(); }
|
Layout* layout() { return m_layout.ptr(); }
|
||||||
const Layout* layout() const { return m_layout.ptr(); }
|
const Layout* layout() const { return m_layout.ptr(); }
|
||||||
void set_layout(OwnPtr<Layout>&&);
|
void set_layout(NonnullRefPtr<Layout>);
|
||||||
|
|
||||||
template<typename T>
|
template<class T, class... Args>
|
||||||
T& set_layout()
|
inline T& set_layout(Args&&... args)
|
||||||
{
|
{
|
||||||
set_layout(make<T>());
|
auto layout = T::construct(forward<Args>(args)...);
|
||||||
return static_cast<T&>(*layout());
|
set_layout(*layout);
|
||||||
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
SizePolicy horizontal_size_policy() const { return m_horizontal_size_policy; }
|
SizePolicy horizontal_size_policy() const { return m_horizontal_size_policy; }
|
||||||
|
@ -304,7 +305,7 @@ private:
|
||||||
void focus_next_widget();
|
void focus_next_widget();
|
||||||
|
|
||||||
Window* m_window { nullptr };
|
Window* m_window { nullptr };
|
||||||
OwnPtr<Layout> m_layout;
|
RefPtr<Layout> m_layout;
|
||||||
|
|
||||||
Gfx::Rect m_relative_rect;
|
Gfx::Rect m_relative_rect;
|
||||||
Gfx::ColorRole m_background_role;
|
Gfx::ColorRole m_background_role;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue