mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 04:42:44 +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 \
 | ||||
|     VBWidget.o \
 | ||||
|     VBWidgetRegistry.o \
 | ||||
|     VBWidgetPropertyModel.o \
 | ||||
|     VBProperty.o \
 | ||||
|     main.o | ||||
| 
 | ||||
|  |  | |||
|  | @ -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(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; } | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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
									
								
								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 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; | ||||
|  |  | |||
|  | @ -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>>&); | ||||
| }; | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling