From f6576c4b7c6834e038c1518574ce2c5fcf5c976d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 10 Nov 2019 22:03:39 +0100 Subject: [PATCH] HackStudio: Start implementing basic widget selection in CursorTool You can now select widgets by clicking on them with the CursorTool, and toggle the selection state of a widget by Ctrl+clicking it. --- DevTools/HackStudio/CursorTool.cpp | 13 ++++++- DevTools/HackStudio/FormEditorWidget.h | 51 +++++++++++++++++++++++++- DevTools/HackStudio/FormWidget.cpp | 15 ++++++++ DevTools/HackStudio/FormWidget.h | 1 + 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/DevTools/HackStudio/CursorTool.cpp b/DevTools/HackStudio/CursorTool.cpp index 9eff4102de..77f0476703 100644 --- a/DevTools/HackStudio/CursorTool.cpp +++ b/DevTools/HackStudio/CursorTool.cpp @@ -1,10 +1,21 @@ #include "CursorTool.h" +#include "FormEditorWidget.h" +#include "FormWidget.h" #include void CursorTool::on_mousedown(GMouseEvent& event) { - (void)event; dbg() << "CursorTool::on_mousedown"; + auto& form_widget = m_editor.form_widget(); + auto result = form_widget.hit_test(event.position(), GWidget::ShouldRespectGreediness::No); + if (result.widget && result.widget != &form_widget) { + if (event.modifiers() & Mod_Ctrl) + m_editor.selection().toggle(*result.widget); + else + m_editor.selection().set(*result.widget); + // FIXME: Do we need to update any part of the FormEditorWidget outside the FormWidget? + form_widget.update(); + } } void CursorTool::on_mouseup(GMouseEvent& event) diff --git a/DevTools/HackStudio/FormEditorWidget.h b/DevTools/HackStudio/FormEditorWidget.h index f760031da7..ef0bbed234 100644 --- a/DevTools/HackStudio/FormEditorWidget.h +++ b/DevTools/HackStudio/FormEditorWidget.h @@ -18,12 +18,61 @@ public: void set_tool(NonnullOwnPtr); + class WidgetSelection { + public: + bool is_empty() const + { + return m_widgets.is_empty(); + } + + bool contains(GWidget& widget) const + { + return m_widgets.contains(&widget); + } + + void toggle(GWidget& widget) + { + if (contains(widget)) + remove(widget); + else + add(widget); + } + + void set(GWidget& widget) + { + clear(); + add(widget); + } + + void remove(GWidget& widget) + { + ASSERT(m_widgets.contains(&widget)); + m_widgets.remove(&widget); + } + + void add(GWidget& widget) + { + m_widgets.set(&widget); + } + + void clear() + { + m_widgets.clear(); + } + + WidgetSelection() {} + private: + HashTable m_widgets; + }; + + WidgetSelection& selection() { return m_selection; } + private: virtual void paint_event(GPaintEvent&) override; explicit FormEditorWidget(GWidget* parent); RefPtr m_form_widget; - NonnullOwnPtr m_tool; + WidgetSelection m_selection; }; diff --git a/DevTools/HackStudio/FormWidget.cpp b/DevTools/HackStudio/FormWidget.cpp index a798680909..985e758dec 100644 --- a/DevTools/HackStudio/FormWidget.cpp +++ b/DevTools/HackStudio/FormWidget.cpp @@ -39,6 +39,21 @@ void FormWidget::paint_event(GPaintEvent& event) } } +void FormWidget::second_paint_event(GPaintEvent& event) +{ + if (editor().selection().is_empty()) + return; + + GPainter painter(*this); + painter.add_clip_rect(event.rect()); + for_each_child_widget([&](auto& child) { + if (editor().selection().contains(child)) { + painter.draw_rect(child.relative_rect(), Color::Blue); + } + return IterationDecision::Continue; + }); +} + void FormWidget::mousedown_event(GMouseEvent& event) { editor().tool().on_mousedown(event); diff --git a/DevTools/HackStudio/FormWidget.h b/DevTools/HackStudio/FormWidget.h index cb60006fc5..6ac2eb3df9 100644 --- a/DevTools/HackStudio/FormWidget.h +++ b/DevTools/HackStudio/FormWidget.h @@ -14,6 +14,7 @@ public: private: virtual void paint_event(GPaintEvent&) override; + virtual void second_paint_event(GPaintEvent&) override; virtual void mousedown_event(GMouseEvent&) override; virtual void mouseup_event(GMouseEvent&) override; virtual void mousemove_event(GMouseEvent&) override;