mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:32:44 +00:00 
			
		
		
		
	PixelPaint: Let the move tool optionally select the active layer
Previously, the move tool would always select the topmost layer before performing a move operation. This commit adds an option for the move tool to always select the active layer, even if it is behind another.
This commit is contained in:
		
							parent
							
								
									16eca649f1
								
							
						
					
					
						commit
						77e15ff4da
					
				
					 3 changed files with 66 additions and 5 deletions
				
			
		|  | @ -372,10 +372,9 @@ void ImageEditor::mousedown_event(GUI::MouseEvent& event) | |||
|     if (!m_active_tool) | ||||
|         return; | ||||
| 
 | ||||
|     if (is<MoveTool>(*m_active_tool)) { | ||||
|         if (auto* other_layer = layer_at_editor_position(event.position())) { | ||||
|             set_active_layer(other_layer); | ||||
|         } | ||||
|     if (auto* tool = dynamic_cast<MoveTool*>(m_active_tool); tool && tool->layer_selection_mode() == MoveTool::LayerSelectionMode::ForegroundLayer) { | ||||
|         if (auto* foreground_layer = layer_at_editor_position(event.position())) | ||||
|             set_active_layer(foreground_layer); | ||||
|     } | ||||
| 
 | ||||
|     auto layer_event = m_active_layer ? event_adjusted_for_layer(event, *m_active_layer) : event; | ||||
|  |  | |||
|  | @ -11,6 +11,8 @@ | |||
| #include "../Layer.h" | ||||
| #include <AK/String.h> | ||||
| #include <LibGUI/Action.h> | ||||
| #include <LibGUI/BoxLayout.h> | ||||
| #include <LibGUI/Label.h> | ||||
| #include <LibGUI/Menu.h> | ||||
| #include <LibGUI/MessageBox.h> | ||||
| #include <LibGUI/Painter.h> | ||||
|  | @ -138,6 +140,9 @@ bool MoveTool::on_keydown(GUI::KeyEvent& event) | |||
|     if (event.key() == Key_Shift) | ||||
|         m_keep_aspect_ratio = true; | ||||
| 
 | ||||
|     if (event.key() == Key_Alt) | ||||
|         toggle_selection_mode(); | ||||
| 
 | ||||
|     if (m_scaling) | ||||
|         return true; | ||||
| 
 | ||||
|  | @ -176,6 +181,9 @@ void MoveTool::on_keyup(GUI::KeyEvent& event) | |||
| { | ||||
|     if (event.key() == Key_Shift) | ||||
|         m_keep_aspect_ratio = false; | ||||
| 
 | ||||
|     if (event.key() == Key_Alt) | ||||
|         toggle_selection_mode(); | ||||
| } | ||||
| 
 | ||||
| void MoveTool::on_second_paint(Layer const* layer, GUI::PaintEvent& event) | ||||
|  | @ -243,4 +251,44 @@ Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> MoveTool::cursor() | |||
|     return Gfx::StandardCursor::Move; | ||||
| } | ||||
| 
 | ||||
| GUI::Widget* MoveTool::get_properties_widget() | ||||
| { | ||||
|     if (!m_properties_widget) { | ||||
|         m_properties_widget = GUI::Widget::construct(); | ||||
|         m_properties_widget->set_layout<GUI::VerticalBoxLayout>(); | ||||
| 
 | ||||
|         auto& selection_mode_container = m_properties_widget->add<GUI::Widget>(); | ||||
|         selection_mode_container.set_layout<GUI::HorizontalBoxLayout>(); | ||||
|         selection_mode_container.set_fixed_height(46); | ||||
|         auto& selection_mode_label = selection_mode_container.add<GUI::Label>("Selection Mode:"); | ||||
|         selection_mode_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); | ||||
|         selection_mode_label.set_fixed_size(80, 40); | ||||
| 
 | ||||
|         auto& mode_radio_container = selection_mode_container.add<GUI::Widget>(); | ||||
|         mode_radio_container.set_layout<GUI::VerticalBoxLayout>(); | ||||
|         m_selection_mode_foreground = mode_radio_container.add<GUI::RadioButton>("Foreground"); | ||||
| 
 | ||||
|         m_selection_mode_active = mode_radio_container.add<GUI::RadioButton>("Active Layer"); | ||||
| 
 | ||||
|         m_selection_mode_foreground->on_checked = [&](bool) { | ||||
|             m_layer_selection_mode = LayerSelectionMode::ForegroundLayer; | ||||
|         }; | ||||
|         m_selection_mode_active->on_checked = [&](bool) { | ||||
|             m_layer_selection_mode = LayerSelectionMode::ActiveLayer; | ||||
|         }; | ||||
| 
 | ||||
|         m_selection_mode_foreground->set_checked(true); | ||||
|     } | ||||
| 
 | ||||
|     return m_properties_widget.ptr(); | ||||
| } | ||||
| 
 | ||||
| void MoveTool::toggle_selection_mode() | ||||
| { | ||||
|     if (m_selection_mode_foreground->is_checked()) | ||||
|         m_selection_mode_active->set_checked(true); | ||||
|     else | ||||
|         m_selection_mode_foreground->set_checked(true); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> | ||||
|  * Copyright (c) 2022, the SerenityOS developers. | ||||
|  * Copyright (c) 2022-2023, the SerenityOS developers. | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
|  | @ -9,6 +9,7 @@ | |||
| 
 | ||||
| #include "../Layer.h" | ||||
| #include "Tool.h" | ||||
| #include <LibGUI/RadioButton.h> | ||||
| 
 | ||||
| namespace PixelPaint { | ||||
| 
 | ||||
|  | @ -23,19 +24,29 @@ public: | |||
|     MoveTool() = default; | ||||
|     virtual ~MoveTool() override = default; | ||||
| 
 | ||||
|     enum class LayerSelectionMode { | ||||
|         ForegroundLayer, | ||||
|         ActiveLayer, | ||||
|     }; | ||||
| 
 | ||||
|     virtual void on_mousedown(Layer*, MouseEvent&) override; | ||||
|     virtual void on_mousemove(Layer*, MouseEvent&) override; | ||||
|     virtual void on_mouseup(Layer*, MouseEvent&) override; | ||||
|     virtual bool on_keydown(GUI::KeyEvent&) override; | ||||
|     virtual void on_keyup(GUI::KeyEvent&) override; | ||||
|     virtual void on_second_paint(Layer const*, GUI::PaintEvent&) override; | ||||
|     virtual GUI::Widget* get_properties_widget() override; | ||||
|     virtual Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> cursor() override; | ||||
|     virtual bool is_overriding_alt() override { return true; } | ||||
|     LayerSelectionMode layer_selection_mode() const { return m_layer_selection_mode; } | ||||
| 
 | ||||
| private: | ||||
|     virtual StringView tool_name() const override { return "Move Tool"sv; } | ||||
|     ErrorOr<void> update_cached_preview_bitmap(Layer const* layer); | ||||
|     Optional<ResizeAnchorLocation const> resize_anchor_location_from_cursor_position(Layer const*, MouseEvent&); | ||||
|     void toggle_selection_mode(); | ||||
| 
 | ||||
|     LayerSelectionMode m_layer_selection_mode { LayerSelectionMode::ForegroundLayer }; | ||||
|     RefPtr<Layer> m_layer_being_moved; | ||||
|     Gfx::IntPoint m_event_origin; | ||||
|     Gfx::IntPoint m_layer_origin; | ||||
|  | @ -43,6 +54,9 @@ private: | |||
|     bool m_scaling { false }; | ||||
|     Optional<ResizeAnchorLocation const> m_resize_anchor_location {}; | ||||
|     bool m_keep_aspect_ratio { false }; | ||||
|     RefPtr<GUI::Widget> m_properties_widget; | ||||
|     RefPtr<GUI::RadioButton> m_selection_mode_foreground; | ||||
|     RefPtr<GUI::RadioButton> m_selection_mode_active; | ||||
| 
 | ||||
|     RefPtr<Gfx::Bitmap> m_cached_preview_bitmap { nullptr }; | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Tim Ledbetter
						Tim Ledbetter