diff --git a/DevTools/VisualBuilder/VBForm.cpp b/DevTools/VisualBuilder/VBForm.cpp index d85908658b..09dfc99f33 100644 --- a/DevTools/VisualBuilder/VBForm.cpp +++ b/DevTools/VisualBuilder/VBForm.cpp @@ -1,6 +1,7 @@ #include "VBForm.h" #include "VBProperty.h" #include "VBWidget.h" +#include "VBWidgetRegistry.h" #include #include #include @@ -24,22 +25,6 @@ VBForm::VBForm(const String& name, GWidget* parent) set_background_color(Color::LightGray); set_greedy_for_hits(true); - auto box1 = VBWidget::create(VBWidgetType::GSpinBox, *this); - box1->set_rect({ 10, 10, 81, 21 }); - m_widgets.append(move(box1)); - - auto box2 = VBWidget::create(VBWidgetType::GTextEditor, *this); - box2->set_rect({ 100, 100, 161, 161 }); - m_widgets.append(move(box2)); - - auto button1 = VBWidget::create(VBWidgetType::GButton, *this); - button1->set_rect({ 200, 50, 81, 21 }); - m_widgets.append(move(button1)); - - auto groupbox1 = VBWidget::create(VBWidgetType::GGroupBox, *this); - groupbox1->set_rect({ 300, 150, 161, 51 }); - m_widgets.append(move(groupbox1)); - m_context_menu = make("Context menu"); m_context_menu->add_action(GAction::create("Move to front", [this](auto&) { if (auto* widget = single_selected_widget()) @@ -305,6 +290,41 @@ void VBForm::mousemove_event(GMouseEvent& event) } } +void VBForm::load_from_file(const String& path) +{ + CFile file(path); + if (!file.open(CIODevice::ReadOnly)) { + GMessageBox::show(String::format("Could not open '%s' for reading", path.characters()), "Error", GMessageBox::Type::Error, window()); + return; + } + + auto file_contents = file.read_all(); + auto form_json = JsonValue::from_string(file_contents); + + if (!form_json.is_object()) { + GMessageBox::show(String::format("Could not parse '%s'", path.characters()), "Error", GMessageBox::Type::Error, window()); + return; + } + + m_name = form_json.as_object().get("name").to_string(); + auto widgets = form_json.as_object().get("widgets").as_array(); + + widgets.for_each([&](const JsonValue& widget_value) { + auto& widget_object = widget_value.as_object(); + auto widget_class = widget_object.get("class").as_string(); + auto widget_type = widget_type_from_class_name(widget_class); + auto vbwidget = VBWidget::create(widget_type, *this); + widget_object.for_each_member([&](auto& property_name, const JsonValue& property_value) { + (void)property_name; + (void)property_value; + VBProperty& property = vbwidget->property(property_name); + dbgprintf("Set property %s.%s to '%s'\n", widget_class.characters(), property_name.characters(), property_value.serialized().characters()); + property.set_value(property_value); + }); + m_widgets.append(vbwidget); + }); +} + void VBForm::write_to_file(const String& path) { CFile file(path); diff --git a/DevTools/VisualBuilder/VBForm.h b/DevTools/VisualBuilder/VBForm.h index 856b4bddd1..1f86c5027a 100644 --- a/DevTools/VisualBuilder/VBForm.h +++ b/DevTools/VisualBuilder/VBForm.h @@ -26,6 +26,7 @@ public: Function on_widget_selected; + void load_from_file(const String& path); void write_to_file(const String& path); void dump(); diff --git a/DevTools/VisualBuilder/VBWidgetRegistry.cpp b/DevTools/VisualBuilder/VBWidgetRegistry.cpp index eaf357af7e..6463c0e875 100644 --- a/DevTools/VisualBuilder/VBWidgetRegistry.cpp +++ b/DevTools/VisualBuilder/VBWidgetRegistry.cpp @@ -11,7 +11,7 @@ #include #include -static String to_class_name(VBWidgetType type) +String to_class_name(VBWidgetType type) { switch (type) { case VBWidgetType::GWidget: @@ -41,6 +41,33 @@ static String to_class_name(VBWidgetType type) } } +VBWidgetType widget_type_from_class_name(const StringView& name) +{ + if (name == "GWidget") + return VBWidgetType::GWidget; + if (name == "GButton") + return VBWidgetType::GButton; + if (name == "GLabel") + return VBWidgetType::GLabel; + if (name == "GSpinBox") + return VBWidgetType::GSpinBox; + if (name == "GTextEditor") + return VBWidgetType::GTextEditor; + if (name == "GProgressBar") + return VBWidgetType::GProgressBar; + if (name == "GCheckBox") + return VBWidgetType::GCheckBox; + if (name == "GRadioButton") + return VBWidgetType::GRadioButton; + if (name == "GScrollBar") + return VBWidgetType::GScrollBar; + if (name == "GGroupBox") + return VBWidgetType::GGroupBox; + if (name == "GSlider") + return VBWidgetType::GSlider; + ASSERT_NOT_REACHED(); +} + static GWidget* build_gwidget(VBWidgetType type, GWidget* parent) { switch (type) { diff --git a/DevTools/VisualBuilder/VBWidgetRegistry.h b/DevTools/VisualBuilder/VBWidgetRegistry.h index bd08a1d574..779cd305fb 100644 --- a/DevTools/VisualBuilder/VBWidgetRegistry.h +++ b/DevTools/VisualBuilder/VBWidgetRegistry.h @@ -20,3 +20,6 @@ public: static GWidget* build_gwidget(VBWidget&, VBWidgetType, GWidget* parent, Vector>&); }; + +String to_class_name(VBWidgetType); +VBWidgetType widget_type_from_class_name(const StringView&); diff --git a/DevTools/VisualBuilder/main.cpp b/DevTools/VisualBuilder/main.cpp index 9401ba3413..e019291082 100644 --- a/DevTools/VisualBuilder/main.cpp +++ b/DevTools/VisualBuilder/main.cpp @@ -68,6 +68,10 @@ int main(int argc, char** argv) propbox->show(); + if (argc == 2) { + form1->load_from_file(argv[1]); + } + return app.exec(); }