From 410cdba5a949558ac87f7f5b7c9b5e55a132e705 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 13 May 2020 21:46:19 +0200 Subject: [PATCH] PaintBrush: Switch the active layer when clicking one with move tool This feels very intuitive and nice, although maybe we need some way to override this behavior for the scenario where you're intending to move something currently behind something else. --- Applications/PaintBrush/ImageEditor.cpp | 40 +++++++++++++++++++++++-- Applications/PaintBrush/ImageEditor.h | 4 +++ Applications/PaintBrush/MoveTool.h | 1 + Applications/PaintBrush/Tool.h | 2 ++ Applications/PaintBrush/main.cpp | 7 +++++ 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Applications/PaintBrush/ImageEditor.cpp b/Applications/PaintBrush/ImageEditor.cpp index 71d678a11c..c18920d329 100644 --- a/Applications/PaintBrush/ImageEditor.cpp +++ b/Applications/PaintBrush/ImageEditor.cpp @@ -85,8 +85,18 @@ static GUI::MouseEvent event_adjusted_for_layer(const GUI::MouseEvent& original_ void ImageEditor::mousedown_event(GUI::MouseEvent& event) { - if (!m_active_layer || !m_active_tool) + if (!m_active_tool) return; + + if (m_active_tool->is_move_tool()) { + if (auto* other_layer = layer_at(event.position())) { + set_active_layer(other_layer); + } + } + + if (!m_active_layer) + return; + auto layer_event = event_adjusted_for_layer(event, *m_active_layer); m_active_tool->on_mousedown(*m_active_layer, layer_event, event); } @@ -124,7 +134,21 @@ void ImageEditor::set_active_layer(Layer* layer) if (m_active_layer == layer) return; m_active_layer = layer; - update(); + + if (m_active_layer) { + size_t index = 0; + for (; index < m_image->layer_count(); ++index) { + if (&m_image->layer(index) == layer) + break; + } + if (on_active_layer_change) + on_active_layer_change(m_image->layer_model().index(index)); + } else { + if (on_active_layer_change) + on_active_layer_change({}); + } + + layers_did_change(); } void ImageEditor::set_active_tool(Tool* tool) @@ -183,4 +207,16 @@ void ImageEditor::set_secondary_color(Color color) on_secondary_color_change(color); } +Layer* ImageEditor::layer_at(const Gfx::Point& position) +{ + if (!m_image) + return nullptr; + for (ssize_t i = m_image->layer_count() - 1; i >= 0; --i) { + auto& layer = m_image->layer(i); + if (layer.relative_rect().contains(position)) + return const_cast(&layer); + } + return nullptr; +} + } diff --git a/Applications/PaintBrush/ImageEditor.h b/Applications/PaintBrush/ImageEditor.h index 1ce0fd8f13..fa315b65ac 100644 --- a/Applications/PaintBrush/ImageEditor.h +++ b/Applications/PaintBrush/ImageEditor.h @@ -51,6 +51,8 @@ public: void layers_did_change(); + Layer* layer_at(const Gfx::Point&); + Color primary_color() const { return m_primary_color; } void set_primary_color(Color); @@ -63,6 +65,8 @@ public: Function on_primary_color_change; Function on_secondary_color_change; + Function on_active_layer_change; + private: ImageEditor(); diff --git a/Applications/PaintBrush/MoveTool.h b/Applications/PaintBrush/MoveTool.h index 68cc76e90c..ef1e3cf132 100644 --- a/Applications/PaintBrush/MoveTool.h +++ b/Applications/PaintBrush/MoveTool.h @@ -42,6 +42,7 @@ public: private: virtual const char* class_name() const override { return "MoveTool"; } + virtual bool is_move_tool() const override { return true; } RefPtr m_layer_being_moved; Gfx::Point m_event_origin; diff --git a/Applications/PaintBrush/Tool.h b/Applications/PaintBrush/Tool.h index f2061ad269..2058307a42 100644 --- a/Applications/PaintBrush/Tool.h +++ b/Applications/PaintBrush/Tool.h @@ -48,6 +48,8 @@ public: virtual void on_keydown(GUI::KeyEvent&) {} virtual void on_keyup(GUI::KeyEvent&) {} + virtual bool is_move_tool() const { return false; } + void clear() { m_editor = nullptr; } void setup(ImageEditor&); diff --git a/Applications/PaintBrush/main.cpp b/Applications/PaintBrush/main.cpp index b6ca78c5be..19d613c6ff 100644 --- a/Applications/PaintBrush/main.cpp +++ b/Applications/PaintBrush/main.cpp @@ -158,6 +158,13 @@ int main(int argc, char** argv) app.set_menubar(move(menubar)); + image_editor.on_active_layer_change = [&](auto& index) { + if (index.is_valid()) + layer_table_view.selection().set(index); + else + layer_table_view.selection().clear(); + }; + auto image = PaintBrush::Image::create_with_size({ 640, 480 }); auto bg_layer = PaintBrush::Layer::create_with_size({ 640, 480 }, "Background");