From 720ebee1beafe7b8d2a3f579aed624d442175b83 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 13 May 2020 22:03:29 +0200 Subject: [PATCH] PaintBrush: Add move tool context menu with "move to back/front" Tools can now have an in-image context menu which you get when right- clicking inside the image editing area. Our first use of this is to provide the ability to move layers to the back/front. :^) --- Applications/PaintBrush/Image.cpp | 25 +++++++++++++++++++++++++ Applications/PaintBrush/Image.h | 5 +++++ Applications/PaintBrush/ImageEditor.cpp | 7 +++++++ Applications/PaintBrush/ImageEditor.h | 1 + Applications/PaintBrush/MoveTool.cpp | 20 ++++++++++++++++++++ Applications/PaintBrush/MoveTool.h | 3 +++ Applications/PaintBrush/Tool.h | 1 + 7 files changed, 62 insertions(+) diff --git a/Applications/PaintBrush/Image.cpp b/Applications/PaintBrush/Image.cpp index 4110a5612e..a2739c1ada 100644 --- a/Applications/PaintBrush/Image.cpp +++ b/Applications/PaintBrush/Image.cpp @@ -79,4 +79,29 @@ GUI::Model& Image::layer_model() return *m_layer_model; } +size_t Image::index_of(const Layer& layer) const +{ + for (size_t i = 0; i < m_layers.size(); ++i) { + if (&m_layers.at(i) == &layer) + return i; + } + ASSERT_NOT_REACHED(); +} + +void Image::move_layer_to_back(Layer& layer) +{ + NonnullRefPtr protector(layer); + auto index = index_of(layer); + m_layers.remove(index); + m_layers.prepend(layer); +} + +void Image::move_layer_to_front(Layer& layer) +{ + NonnullRefPtr protector(layer); + auto index = index_of(layer); + m_layers.remove(index); + m_layers.append(layer); +} + } diff --git a/Applications/PaintBrush/Image.h b/Applications/PaintBrush/Image.h index 47950796dd..6b832df594 100644 --- a/Applications/PaintBrush/Image.h +++ b/Applications/PaintBrush/Image.h @@ -55,9 +55,14 @@ public: GUI::Model& layer_model(); + void move_layer_to_front(Layer&); + void move_layer_to_back(Layer&); + private: explicit Image(const Gfx::Size&); + size_t index_of(const Layer&) const; + Gfx::Size m_size; NonnullRefPtrVector m_layers; RefPtr m_layer_model; diff --git a/Applications/PaintBrush/ImageEditor.cpp b/Applications/PaintBrush/ImageEditor.cpp index c18920d329..0a35989a9a 100644 --- a/Applications/PaintBrush/ImageEditor.cpp +++ b/Applications/PaintBrush/ImageEditor.cpp @@ -117,6 +117,13 @@ void ImageEditor::mouseup_event(GUI::MouseEvent& event) m_active_tool->on_mouseup(*m_active_layer, layer_event, event); } +void ImageEditor::context_menu_event(GUI::ContextMenuEvent& event) +{ + if (!m_active_layer || !m_active_tool) + return; + m_active_tool->on_context_menu(*m_active_layer, event); +} + void ImageEditor::keydown_event(GUI::KeyEvent& event) { if (m_active_tool) diff --git a/Applications/PaintBrush/ImageEditor.h b/Applications/PaintBrush/ImageEditor.h index fa315b65ac..6945b42a49 100644 --- a/Applications/PaintBrush/ImageEditor.h +++ b/Applications/PaintBrush/ImageEditor.h @@ -79,6 +79,7 @@ private: virtual void mouseup_event(GUI::MouseEvent&) override; virtual void keydown_event(GUI::KeyEvent&) override; virtual void keyup_event(GUI::KeyEvent&) override; + virtual void context_menu_event(GUI::ContextMenuEvent&) override; RefPtr m_image; RefPtr m_active_layer; diff --git a/Applications/PaintBrush/MoveTool.cpp b/Applications/PaintBrush/MoveTool.cpp index 9981024351..1c87e3e79d 100644 --- a/Applications/PaintBrush/MoveTool.cpp +++ b/Applications/PaintBrush/MoveTool.cpp @@ -25,8 +25,11 @@ */ #include "MoveTool.h" +#include "Image.h" #include "ImageEditor.h" #include "Layer.h" +#include +#include #include #include @@ -101,4 +104,21 @@ void MoveTool::on_keydown(GUI::KeyEvent& event) m_editor->layers_did_change(); } +void MoveTool::on_context_menu(Layer& layer, GUI::ContextMenuEvent& event) +{ + if (!m_context_menu) { + m_context_menu = GUI::Menu::construct(); + m_context_menu->add_action(GUI::CommonActions::make_move_to_front_action([this](auto&) { + m_editor->image()->move_layer_to_front(*m_context_menu_layer); + m_editor->layers_did_change(); + })); + m_context_menu->add_action(GUI::CommonActions::make_move_to_back_action([this](auto&) { + m_editor->image()->move_layer_to_back(*m_context_menu_layer); + m_editor->layers_did_change(); + })); + } + m_context_menu_layer = layer; + m_context_menu->popup(event.screen_position()); +} + } diff --git a/Applications/PaintBrush/MoveTool.h b/Applications/PaintBrush/MoveTool.h index ef1e3cf132..0c363ebd97 100644 --- a/Applications/PaintBrush/MoveTool.h +++ b/Applications/PaintBrush/MoveTool.h @@ -39,6 +39,7 @@ public: virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& original_event) override; virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& original_event) override; virtual void on_keydown(GUI::KeyEvent&) override; + virtual void on_context_menu(Layer&, GUI::ContextMenuEvent&) override; private: virtual const char* class_name() const override { return "MoveTool"; } @@ -47,6 +48,8 @@ private: RefPtr m_layer_being_moved; Gfx::Point m_event_origin; Gfx::Point m_layer_origin; + RefPtr m_context_menu; + RefPtr m_context_menu_layer; }; } diff --git a/Applications/PaintBrush/Tool.h b/Applications/PaintBrush/Tool.h index 9bfa12d084..954e0cc51d 100644 --- a/Applications/PaintBrush/Tool.h +++ b/Applications/PaintBrush/Tool.h @@ -43,6 +43,7 @@ public: virtual void on_mousedown(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) {} virtual void on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) {} virtual void on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) {} + virtual void on_context_menu(Layer&, GUI::ContextMenuEvent&) {} virtual void on_tool_button_contextmenu(GUI::ContextMenuEvent&) {} virtual void on_second_paint(const Layer&, GUI::PaintEvent&) {} virtual void on_keydown(GUI::KeyEvent&) {}