浏览代码

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

Andreas Kling 6 年之前
父节点
当前提交
707bfe848d

+ 1 - 0
Applications/VisualBuilder/Makefile

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

+ 4 - 0
Applications/VisualBuilder/VBForm.cpp

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

+ 2 - 0
Applications/VisualBuilder/VBForm.h

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

+ 1 - 0
Applications/VisualBuilder/VBProperty.h

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

+ 3 - 1
Applications/VisualBuilder/VBWidget.cpp

@@ -2,11 +2,13 @@
 #include "VBForm.h"
 #include "VBProperty.h"
 #include "VBWidgetRegistry.h"
+#include "VBWidgetPropertyModel.h"
 #include <LibGUI/GPainter.h>
 
 VBWidget::VBWidget(VBWidgetType type, VBForm& form)
     : m_type(type)
     , m_form(form)
+    , m_property_model(VBWidgetPropertyModel::create(*this))
 {
     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)
 {
     for (auto& it : m_properties) {
-        callback(*it.value);
+        callback(*it);
     }
 }

+ 6 - 1
Applications/VisualBuilder/VBWidget.h

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

+ 52 - 0
Applications/VisualBuilder/VBWidgetPropertyModel.cpp

@@ -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 { };
+}

+ 30 - 0
Applications/VisualBuilder/VBWidgetPropertyModel.h

@@ -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;
+};

+ 2 - 2
Applications/VisualBuilder/VBWidgetRegistry.cpp

@@ -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 add_property = [&properties] (const String& name, const GVariant& value, bool is_readonly) {
         auto property = make<VBProperty>(name, value);
         property->set_readonly(is_readonly);
-        properties.set(name, move(property));
+        properties.append(move(property));
     };
     add_property("ClassName", to_class_name(type), true);
     return gwidget;

+ 1 - 1
Applications/VisualBuilder/VBWidgetRegistry.h

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

+ 11 - 1
Applications/VisualBuilder/main.cpp

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