mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:02:45 +00:00 
			
		
		
		
	VisualBuilder: Add a table view with the selected widget's properties.
This commit is contained in:
		
							parent
							
								
									c57cf9834b
								
							
						
					
					
						commit
						707bfe848d
					
				
					 11 changed files with 113 additions and 6 deletions
				
			
		|  | @ -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 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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; } | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| }; | }; | ||||||
|  |  | ||||||
							
								
								
									
										52
									
								
								Applications/VisualBuilder/VBWidgetPropertyModel.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								Applications/VisualBuilder/VBWidgetPropertyModel.cpp
									
										
									
									
									
										Normal 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 { }; | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								Applications/VisualBuilder/VBWidgetPropertyModel.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Applications/VisualBuilder/VBWidgetPropertyModel.h
									
										
									
									
									
										Normal 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; | ||||||
|  | }; | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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>>&); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling