1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 07:27:45 +00:00

PixelPaint: Add "Delete Mask" action

This commit adds a "Delete Mask" action which deletes the active layer
mask. The option is only displayed if the active layer is masked.
This commit is contained in:
Tim Ledbetter 2023-02-25 06:45:55 +00:00 committed by Andreas Kling
parent d66f143fb7
commit 062c9efa88
4 changed files with 55 additions and 8 deletions

View file

@ -317,6 +317,13 @@ ErrorOr<void> Layer::create_mask()
return {}; return {};
} }
void Layer::delete_mask()
{
m_mask_bitmap = nullptr;
set_edit_mode(EditMode::Content);
update_cached_bitmap();
}
Gfx::Bitmap& Layer::currently_edited_bitmap() Gfx::Bitmap& Layer::currently_edited_bitmap()
{ {
switch (edit_mode()) { switch (edit_mode()) {

View file

@ -46,6 +46,7 @@ public:
Gfx::Bitmap* mask_bitmap() { return m_mask_bitmap; } Gfx::Bitmap* mask_bitmap() { return m_mask_bitmap; }
ErrorOr<void> create_mask(); ErrorOr<void> create_mask();
void delete_mask();
Gfx::Bitmap& get_scratch_edited_bitmap(); Gfx::Bitmap& get_scratch_edited_bitmap();
Gfx::IntSize size() const { return content_bitmap().size(); } Gfx::IntSize size() const { return content_bitmap().size(); }

View file

@ -82,6 +82,7 @@ MainWidget::MainWidget()
m_palette_widget->set_image_editor(nullptr); m_palette_widget->set_image_editor(nullptr);
m_tool_properties_widget->set_enabled(false); m_tool_properties_widget->set_enabled(false);
set_actions_enabled(false); set_actions_enabled(false);
set_mask_actions_for_layer(nullptr);
} }
update_window_modified(); update_window_modified();
}); });
@ -106,6 +107,7 @@ MainWidget::MainWidget()
}; };
// Ensure that our undo/redo actions are in sync with the current editor. // Ensure that our undo/redo actions are in sync with the current editor.
image_editor_did_update_undo_stack(); image_editor_did_update_undo_stack();
set_mask_actions_for_layer(image_editor.active_layer());
}; };
} }
@ -739,23 +741,38 @@ ErrorOr<void> MainWidget::initialize_menubar(GUI::Window& window)
m_layer_menu->add_action(*m_layer_via_cut); m_layer_menu->add_action(*m_layer_via_cut);
m_layer_menu->add_separator(); m_layer_menu->add_separator();
m_layer_menu->add_action(GUI::Action::create(
"Add M&ask", { Mod_Ctrl | Mod_Shift, Key_M }, g_icon_bag.add_mask, [&](auto&) { auto create_layer_mask_callback = [&](auto const& action_name, Function<void(Layer*)> mask_function) {
return [&, mask_function = move(mask_function)](GUI::Action&) {
auto* editor = current_image_editor(); auto* editor = current_image_editor();
VERIFY(editor); VERIFY(editor);
auto active_layer = editor->active_layer(); auto* active_layer = editor->active_layer();
if (!active_layer) if (!active_layer)
return; return;
if (auto maybe_error = active_layer->create_mask(); maybe_error.is_error()) { mask_function(active_layer);
GUI::MessageBox::show_error(&window, DeprecatedString::formatted("Failed to create layer mask: {}", maybe_error.release_error()));
return;
}
editor->did_complete_action("Add Mask"); editor->did_complete_action(action_name);
editor->update(); editor->update();
m_layer_list_widget->repaint(); m_layer_list_widget->repaint();
set_mask_actions_for_layer(active_layer);
};
};
m_add_mask_action = GUI::Action::create(
"Add M&ask", { Mod_Ctrl | Mod_Shift, Key_M }, g_icon_bag.add_mask, create_layer_mask_callback("Add Mask", [&](Layer* active_layer) {
VERIFY(!active_layer->is_masked());
if (auto maybe_error = active_layer->create_mask(); maybe_error.is_error())
GUI::MessageBox::show_error(&window, DeprecatedString::formatted("Failed to create layer mask: {}", maybe_error.release_error()));
})); }));
m_layer_menu->add_action(*m_add_mask_action);
m_delete_mask_action = GUI::Action::create(
"Delete Mask", create_layer_mask_callback("Delete Mask", [&](Layer* active_layer) {
VERIFY(active_layer->is_masked());
active_layer->delete_mask();
}));
m_layer_menu->add_action(*m_delete_mask_action);
m_layer_menu->add_separator(); m_layer_menu->add_separator();
@ -1115,6 +1132,22 @@ void MainWidget::set_actions_enabled(bool enabled)
m_zoom_combobox->set_enabled(enabled); m_zoom_combobox->set_enabled(enabled);
} }
void MainWidget::set_mask_actions_for_layer(Layer* layer)
{
if (!layer) {
m_add_mask_action->set_visible(true);
m_delete_mask_action->set_visible(false);
m_add_mask_action->set_enabled(false);
return;
}
m_add_mask_action->set_enabled(true);
auto masked = layer->is_masked();
m_add_mask_action->set_visible(!masked);
m_delete_mask_action->set_visible(masked);
}
void MainWidget::open_image(FileSystemAccessClient::File file) void MainWidget::open_image(FileSystemAccessClient::File file)
{ {
auto try_load = m_loader.load_from_file(file.release_stream()); auto try_load = m_loader.load_from_file(file.release_stream());
@ -1165,6 +1198,7 @@ ErrorOr<void> MainWidget::create_image_from_clipboard()
m_layer_list_widget->set_image(image); m_layer_list_widget->set_image(image);
m_layer_list_widget->set_selected_layer(layer); m_layer_list_widget->set_selected_layer(layer);
set_mask_actions_for_layer(layer);
return {}; return {};
} }
@ -1196,6 +1230,7 @@ ImageEditor& MainWidget::create_new_editor(NonnullRefPtr<Image> image)
return; return;
m_layer_list_widget->set_selected_layer(layer); m_layer_list_widget->set_selected_layer(layer);
m_layer_properties_widget->set_layer(layer); m_layer_properties_widget->set_layer(layer);
set_mask_actions_for_layer(layer);
}; };
image_editor.on_title_change = [&](auto const& title) { image_editor.on_title_change = [&](auto const& title) {

View file

@ -56,6 +56,7 @@ private:
void image_editor_did_update_undo_stack(); void image_editor_did_update_undo_stack();
void set_actions_enabled(bool enabled); void set_actions_enabled(bool enabled);
void set_mask_actions_for_layer(Layer* active_layer);
virtual void drag_enter_event(GUI::DragEvent&) override; virtual void drag_enter_event(GUI::DragEvent&) override;
virtual void drop_event(GUI::DropEvent&) override; virtual void drop_event(GUI::DropEvent&) override;
@ -110,6 +111,9 @@ private:
RefPtr<GUI::Action> m_layer_via_copy; RefPtr<GUI::Action> m_layer_via_copy;
RefPtr<GUI::Action> m_layer_via_cut; RefPtr<GUI::Action> m_layer_via_cut;
RefPtr<GUI::Action> m_add_mask_action;
RefPtr<GUI::Action> m_delete_mask_action;
Gfx::IntPoint m_last_image_editor_mouse_position; Gfx::IntPoint m_last_image_editor_mouse_position;
}; };