1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-25 22:45:06 +00:00

VisualBuilder: Add a table view with the selected widget's properties.

This commit is contained in:
Andreas Kling 2019-04-11 21:41:09 +02:00
parent c57cf9834b
commit 707bfe848d
11 changed files with 113 additions and 6 deletions

View file

@ -2,6 +2,7 @@ OBJS = \
VBForm.o \ VBForm.o \
VBWidget.o \ VBWidget.o \
VBWidgetRegistry.o \ VBWidgetRegistry.o \
VBWidgetPropertyModel.o \
VBProperty.o \ VBProperty.o \
main.o main.o

View file

@ -105,6 +105,8 @@ void VBForm::mousedown_event(GMouseEvent& event)
if (!widget) { if (!widget) {
if (m_selected_widget) { if (m_selected_widget) {
m_selected_widget = nullptr; m_selected_widget = nullptr;
if (on_widget_selected)
on_widget_selected(nullptr);
update(); update();
} }
return; return;
@ -113,6 +115,8 @@ void VBForm::mousedown_event(GMouseEvent& event)
m_selected_widget = widget->make_weak_ptr(); m_selected_widget = widget->make_weak_ptr();
m_transform_event_origin = event.position(); m_transform_event_origin = event.position();
m_transform_widget_origin_rect = widget->rect(); m_transform_widget_origin_rect = widget->rect();
if (on_widget_selected)
on_widget_selected(widget);
update(); update();
} }
} }

View file

@ -22,6 +22,8 @@ public:
void insert_widget(VBWidgetType); void insert_widget(VBWidgetType);
Function<void(VBWidget*)> on_widget_selected;
protected: protected:
virtual void paint_event(GPaintEvent&) override; virtual void paint_event(GPaintEvent&) override;
virtual void second_paint_event(GPaintEvent&) override; virtual void second_paint_event(GPaintEvent&) override;

View file

@ -9,6 +9,7 @@ public:
~VBProperty(); ~VBProperty();
String name() const { return m_name; } String name() const { return m_name; }
const GVariant& value() const { return m_value; }
bool is_readonly() const { return m_readonly; } bool is_readonly() const { return m_readonly; }
void set_readonly(bool b) { m_readonly = b; } void set_readonly(bool b) { m_readonly = b; }

View file

@ -2,11 +2,13 @@
#include "VBForm.h" #include "VBForm.h"
#include "VBProperty.h" #include "VBProperty.h"
#include "VBWidgetRegistry.h" #include "VBWidgetRegistry.h"
#include "VBWidgetPropertyModel.h"
#include <LibGUI/GPainter.h> #include <LibGUI/GPainter.h>
VBWidget::VBWidget(VBWidgetType type, VBForm& form) VBWidget::VBWidget(VBWidgetType type, VBForm& form)
: m_type(type) : m_type(type)
, m_form(form) , m_form(form)
, m_property_model(VBWidgetPropertyModel::create(*this))
{ {
m_gwidget = VBWidgetRegistry::build_gwidget(type, &form, m_properties); m_gwidget = VBWidgetRegistry::build_gwidget(type, &form, m_properties);
} }
@ -69,6 +71,6 @@ Direction VBWidget::grabber_at(const Point& position) const
void VBWidget::for_each_property(Function<void(VBProperty&)> callback) void VBWidget::for_each_property(Function<void(VBProperty&)> callback)
{ {
for (auto& it : m_properties) { for (auto& it : m_properties) {
callback(*it.value); callback(*it);
} }
} }

View file

@ -12,6 +12,7 @@ class GPainter;
class GWidget; class GWidget;
class VBForm; class VBForm;
class VBProperty; class VBProperty;
class VBWidgetPropertyModel;
enum class Direction { None, Left, UpLeft, Up, UpRight, Right, DownRight, Down, DownLeft }; enum class Direction { None, Left, UpLeft, Up, UpRight, Right, DownRight, Down, DownLeft };
template<typename Callback> template<typename Callback>
@ -28,6 +29,7 @@ inline void for_each_direction(Callback callback)
} }
class VBWidget : public Retainable<VBWidget>, public Weakable<VBWidget> { class VBWidget : public Retainable<VBWidget>, public Weakable<VBWidget> {
friend class VBWidgetPropertyModel;
public: public:
static Retained<VBWidget> create(VBWidgetType type, VBForm& form) { return adopt(*new VBWidget(type, form)); } static Retained<VBWidget> create(VBWidgetType type, VBForm& form) { return adopt(*new VBWidget(type, form)); }
~VBWidget(); ~VBWidget();
@ -47,6 +49,8 @@ public:
void for_each_property(Function<void(VBProperty&)>); void for_each_property(Function<void(VBProperty&)>);
VBWidgetPropertyModel& property_model() { return *m_property_model; }
protected: protected:
VBWidget(VBWidgetType, VBForm&); VBWidget(VBWidgetType, VBForm&);
@ -54,5 +58,6 @@ private:
VBWidgetType m_type { VBWidgetType::None }; VBWidgetType m_type { VBWidgetType::None };
VBForm& m_form; VBForm& m_form;
GWidget* m_gwidget { nullptr }; GWidget* m_gwidget { nullptr };
HashMap<String, OwnPtr<VBProperty>> m_properties; Vector<OwnPtr<VBProperty>> m_properties;
Retained<VBWidgetPropertyModel> m_property_model;
}; };

View file

@ -0,0 +1,52 @@
#include "VBWidgetPropertyModel.h"
#include "VBWidget.h"
#include "VBProperty.h"
VBWidgetPropertyModel::VBWidgetPropertyModel(VBWidget& widget)
: m_widget(widget)
{
}
VBWidgetPropertyModel::~VBWidgetPropertyModel()
{
ASSERT_NOT_REACHED();
}
int VBWidgetPropertyModel::row_count(const GModelIndex&) const
{
dbgprintf("row count: %d\n", m_widget.m_properties.size());
return m_widget.m_properties.size();
}
String VBWidgetPropertyModel::column_name(int column) const
{
switch (column) {
case Column::Name: return "Name";
case Column::Value: return "Value";
default: ASSERT_NOT_REACHED();
}
}
GModel::ColumnMetadata VBWidgetPropertyModel::column_metadata(int column) const
{
UNUSED_PARAM(column);
return { 100, TextAlignment::CenterLeft };
}
GVariant VBWidgetPropertyModel::data(const GModelIndex& index, Role role) const
{
if (role == Role::Display) {
dbgprintf("Accessing prop #%d (size=%d) column %d\n", index.row(), m_widget.m_properties.size(), index.column());
auto& property = *m_widget.m_properties[index.row()];
auto value = property.value();
dbgprintf("value type=%u\n", (unsigned)value.type());
dbgprintf("value impl=%x\n", (unsigned)value.to_string().impl());
dbgprintf("value len=%x\n", (unsigned)value.to_string().impl()->length());
dbgprintf("for value='%s'\n", value.to_string().characters());
switch (index.column()) {
case Column::Name: return property.name();
case Column::Value: return property.value();
}
}
return { };
}

View file

@ -0,0 +1,30 @@
#pragma once
#include <LibGUI/GModel.h>
class VBWidget;
class VBProperty;
class VBWidgetPropertyModel : public GModel {
public:
enum Column {
Name = 0,
Value,
__Count
};
static Retained<VBWidgetPropertyModel> create(VBWidget& widget) { return adopt(*new VBWidgetPropertyModel(widget)); }
virtual ~VBWidgetPropertyModel() override;
virtual int row_count(const GModelIndex&) const override;
virtual int column_count(const GModelIndex&) const override { return Column::__Count; }
virtual String column_name(int column) const override;
virtual ColumnMetadata column_metadata(int column) const override;
virtual GVariant data(const GModelIndex&, Role = Role::Display) const override;
virtual void update() override { }
private:
explicit VBWidgetPropertyModel(VBWidget&);
VBWidget& m_widget;
};

View file

@ -74,13 +74,13 @@ static GWidget* build_gwidget(VBWidgetType type, GWidget* parent)
} }
GWidget* VBWidgetRegistry::build_gwidget(VBWidgetType type, GWidget* parent, HashMap<String, OwnPtr<VBProperty>>& properties) GWidget* VBWidgetRegistry::build_gwidget(VBWidgetType type, GWidget* parent, Vector<OwnPtr<VBProperty>>& properties)
{ {
auto* gwidget = ::build_gwidget(type, parent); auto* gwidget = ::build_gwidget(type, parent);
auto add_property = [&properties] (const String& name, const GVariant& value, bool is_readonly) { auto add_property = [&properties] (const String& name, const GVariant& value, bool is_readonly) {
auto property = make<VBProperty>(name, value); auto property = make<VBProperty>(name, value);
property->set_readonly(is_readonly); property->set_readonly(is_readonly);
properties.set(name, move(property)); properties.append(move(property));
}; };
add_property("ClassName", to_class_name(type), true); add_property("ClassName", to_class_name(type), true);
return gwidget; return gwidget;

View file

@ -16,5 +16,5 @@ public:
callback((VBWidgetType)i); callback((VBWidgetType)i);
} }
static GWidget* build_gwidget(VBWidgetType, GWidget* parent, HashMap<String, OwnPtr<VBProperty>>&); static GWidget* build_gwidget(VBWidgetType, GWidget* parent, Vector<OwnPtr<VBProperty>>&);
}; };

View file

@ -5,8 +5,10 @@
#include <LibGUI/GMenuBar.h> #include <LibGUI/GMenuBar.h>
#include <LibGUI/GAction.h> #include <LibGUI/GAction.h>
#include <LibGUI/GButton.h> #include <LibGUI/GButton.h>
#include <LibGUI/GTableView.h>
#include "VBForm.h" #include "VBForm.h"
#include "VBWidget.h" #include "VBWidget.h"
#include "VBWidgetPropertyModel.h"
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
@ -15,11 +17,18 @@
static GWindow* make_toolbox_window(); static GWindow* make_toolbox_window();
static GWindow* make_properties_window(); static GWindow* make_properties_window();
GTableView* g_property_table_view;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
GApplication app(argc, argv); GApplication app(argc, argv);
auto* propbox = make_properties_window();
auto* form1 = new VBForm("Form1"); auto* form1 = new VBForm("Form1");
form1->on_widget_selected = [] (VBWidget* widget) {
g_property_table_view->set_model(widget ? &widget->property_model() : nullptr);
};
auto menubar = make<GMenuBar>(); auto menubar = make<GMenuBar>();
auto app_menu = make<GMenu>("Visual Builder"); auto app_menu = make<GMenu>("Visual Builder");
@ -53,7 +62,6 @@ int main(int argc, char** argv)
auto* toolbox = make_toolbox_window(); auto* toolbox = make_toolbox_window();
toolbox->show(); toolbox->show();
auto* propbox = make_properties_window();
propbox->show(); propbox->show();
return app.exec(); return app.exec();
@ -141,5 +149,7 @@ GWindow* make_properties_window()
widget->set_layout(make<GBoxLayout>(Orientation::Vertical)); widget->set_layout(make<GBoxLayout>(Orientation::Vertical));
window->set_main_widget(widget); window->set_main_widget(widget);
g_property_table_view = new GTableView(widget);
return window; return window;
} }