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.
This commit is contained in:
Andreas Kling 2019-11-10 22:03:39 +01:00
parent e87756424d
commit f6576c4b7c
4 changed files with 78 additions and 2 deletions

View file

@ -1,10 +1,21 @@
#include "CursorTool.h"
#include "FormEditorWidget.h"
#include "FormWidget.h"
#include <AK/LogStream.h>
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)

View file

@ -18,12 +18,61 @@ public:
void set_tool(NonnullOwnPtr<Tool>);
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<GWidget*> m_widgets;
};
WidgetSelection& selection() { return m_selection; }
private:
virtual void paint_event(GPaintEvent&) override;
explicit FormEditorWidget(GWidget* parent);
RefPtr<FormWidget> m_form_widget;
NonnullOwnPtr<Tool> m_tool;
WidgetSelection m_selection;
};

View file

@ -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);

View file

@ -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;