diff --git a/DevTools/HackStudio/FormEditorWidget.h b/DevTools/HackStudio/FormEditorWidget.h index 04758ab263..bfe557be33 100644 --- a/DevTools/HackStudio/FormEditorWidget.h +++ b/DevTools/HackStudio/FormEditorWidget.h @@ -23,6 +23,13 @@ public: class WidgetSelection { public: + Function on_remove; + Function on_add; + Function on_clear; + + void enable_hooks() { m_hooks_enabled = true; } + void disable_hooks() { m_hooks_enabled = false; } + bool is_empty() const { return m_widgets.is_empty(); @@ -51,16 +58,22 @@ public: { ASSERT(m_widgets.contains(&widget)); m_widgets.remove(&widget); + if (m_hooks_enabled && on_remove) + on_remove(widget); } void add(GWidget& widget) { m_widgets.set(&widget); + if (m_hooks_enabled && on_add) + on_add(widget); } void clear() { m_widgets.clear(); + if (m_hooks_enabled && on_clear) + on_clear(); } template @@ -76,6 +89,7 @@ public: private: HashTable m_widgets; + bool m_hooks_enabled { true }; }; WidgetSelection& selection() { return m_selection; } diff --git a/DevTools/HackStudio/WidgetTreeModel.cpp b/DevTools/HackStudio/WidgetTreeModel.cpp index a2740da185..130c666226 100644 --- a/DevTools/HackStudio/WidgetTreeModel.cpp +++ b/DevTools/HackStudio/WidgetTreeModel.cpp @@ -75,3 +75,14 @@ void WidgetTreeModel::update() { did_update(); } + +GModelIndex WidgetTreeModel::index_for_widget(GWidget& widget) const +{ + int parent_child_index = 0; + for (auto& parent_child : widget.parent_widget()->child_widgets()) { + if (parent_child == &widget) + return create_index(parent_child_index, 0, &widget); + ++parent_child_index; + } + return {}; +} diff --git a/DevTools/HackStudio/WidgetTreeModel.h b/DevTools/HackStudio/WidgetTreeModel.h index 10a81da3fa..f7e784b9b6 100644 --- a/DevTools/HackStudio/WidgetTreeModel.h +++ b/DevTools/HackStudio/WidgetTreeModel.h @@ -15,6 +15,8 @@ public: virtual GModelIndex parent_index(const GModelIndex&) const override; virtual void update() override; + GModelIndex index_for_widget(GWidget&) const; + private: explicit WidgetTreeModel(GWidget&); diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index e3f870d7d4..c18a7abcb1 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -100,7 +100,7 @@ int main(int argc, char** argv) Function update_actions; g_window = GWindow::construct(); - g_window->set_rect(100, 100, 800, 600); + g_window->set_rect(90, 90, 840, 600); g_window->set_title("HackStudio"); auto widget = GWidget::construct(); @@ -164,7 +164,7 @@ int main(int argc, char** argv) auto form_editing_pane_container = GSplitter::construct(Orientation::Vertical, form_editor_inner_splitter); form_editing_pane_container->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill); - form_editing_pane_container->set_preferred_size(170, 0); + form_editing_pane_container->set_preferred_size(190, 0); form_editing_pane_container->set_layout(make(Orientation::Vertical)); auto add_properties_pane = [&](auto& text, auto pane_widget) { @@ -181,6 +181,28 @@ int main(int argc, char** argv) auto form_widget_tree_view = GTreeView::construct(nullptr); form_widget_tree_view->set_model(g_form_editor_widget->model()); + form_widget_tree_view->on_selection_change = [&] { + g_form_editor_widget->selection().disable_hooks(); + g_form_editor_widget->selection().clear(); + form_widget_tree_view->selection().for_each_index([&](auto& index) { + // NOTE: Make sure we don't add the FormWidget itself to the selection, + // since that would allow you to drag-move the FormWidget. + if (index.internal_data() != &g_form_editor_widget->form_widget()) + g_form_editor_widget->selection().add(*(GWidget*)index.internal_data()); + }); + g_form_editor_widget->update(); + g_form_editor_widget->selection().enable_hooks(); + }; + + g_form_editor_widget->selection().on_add = [&](auto& widget) { + form_widget_tree_view->selection().add(g_form_editor_widget->model().index_for_widget(widget)); + }; + g_form_editor_widget->selection().on_remove = [&](auto& widget) { + form_widget_tree_view->selection().remove(g_form_editor_widget->model().index_for_widget(widget)); + }; + g_form_editor_widget->selection().on_clear = [&] { + form_widget_tree_view->selection().clear(); + }; add_properties_pane("Form widget tree:", form_widget_tree_view); add_properties_pane("Widget properties:", GTableView::construct(nullptr));