From e89c649be1905d62aa7ef4eee0ba7a334528c7e1 Mon Sep 17 00:00:00 2001 From: Baitinq Date: Tue, 20 Dec 2022 17:17:51 +0100 Subject: [PATCH] PixelPaint: Propagate errors in {flip,crop,rotate,resize} functions We now propagate errors when using the {Layer,Image}::flip(), {Layer,Image}::crop(), {Layer,Image}::rotate() and {Layer,Image}::resize() functions. We handle these errors by show an error DialogBox with the error's message. This removes 8 FIXMEs:)) --- Userland/Applications/PixelPaint/Image.cpp | 120 +++++++++++++++--- Userland/Applications/PixelPaint/Image.h | 8 +- Userland/Applications/PixelPaint/Layer.cpp | 64 ++++++---- Userland/Applications/PixelPaint/Layer.h | 19 ++- .../Applications/PixelPaint/MainWidget.cpp | 79 ++++++++++-- .../PixelPaint/Tools/MoveTool.cpp | 9 +- 6 files changed, 232 insertions(+), 67 deletions(-) diff --git a/Userland/Applications/PixelPaint/Image.cpp b/Userland/Applications/PixelPaint/Image.cpp index ac7e472280..6831979c12 100644 --- a/Userland/Applications/PixelPaint/Image.cpp +++ b/Userland/Applications/PixelPaint/Image.cpp @@ -492,40 +492,106 @@ void ImageUndoCommand::redo() undo(); } -void Image::flip(Gfx::Orientation orientation) +ErrorOr Image::flip(Gfx::Orientation orientation) { - for (auto& layer : m_layers) { - layer.flip(orientation); + Vector> flipped_layers; + TRY(flipped_layers.try_ensure_capacity(m_layers.size())); + + VERIFY(m_layers.size() > 0); + + size_t selected_layer_index = 0; + for (size_t i = 0; i < m_layers.size(); ++i) { + auto& layer = m_layers[i]; + auto new_layer = TRY(Layer::try_create_snapshot(*this, layer)); + + if (layer.is_selected()) + selected_layer_index = i; + + TRY(new_layer->flip(orientation, Layer::NotifyClients::NO)); + + flipped_layers.append(new_layer); } + m_layers = move(flipped_layers); + for (auto& layer : m_layers) + layer.did_modify_bitmap({}, Layer::NotifyClients::YES); + + select_layer(&m_layers[selected_layer_index]); + did_change(); + + return {}; } -void Image::rotate(Gfx::RotationDirection direction) +ErrorOr Image::rotate(Gfx::RotationDirection direction) { - for (auto& layer : m_layers) { - layer.rotate(direction); + Vector> rotated_layers; + TRY(rotated_layers.try_ensure_capacity(m_layers.size())); + + VERIFY(m_layers.size() > 0); + + size_t selected_layer_index = 0; + for (size_t i = 0; i < m_layers.size(); ++i) { + auto& layer = m_layers[i]; + auto new_layer = TRY(Layer::try_create_snapshot(*this, layer)); + + if (layer.is_selected()) + selected_layer_index = i; + + TRY(new_layer->rotate(direction, Layer::NotifyClients::NO)); + + rotated_layers.append(new_layer); } + m_layers = move(rotated_layers); + for (auto& layer : m_layers) + layer.did_modify_bitmap({}, Layer::NotifyClients::YES); + + select_layer(&m_layers[selected_layer_index]); + m_size = { m_size.height(), m_size.width() }; did_change_rect(); + + return {}; } -void Image::crop(Gfx::IntRect const& cropped_rect) +ErrorOr Image::crop(Gfx::IntRect const& cropped_rect) { - for (auto& layer : m_layers) { - auto layer_location = layer.location(); - auto layer_local_crop_rect = layer.relative_rect().intersected(cropped_rect).translated(-layer_location.x(), -layer_location.y()); - layer.crop(layer_local_crop_rect); + Vector> cropped_layers; + TRY(cropped_layers.try_ensure_capacity(m_layers.size())); + + VERIFY(m_layers.size() > 0); + + size_t selected_layer_index = 0; + for (size_t i = 0; i < m_layers.size(); ++i) { + auto& layer = m_layers[i]; + auto new_layer = TRY(Layer::try_create_snapshot(*this, layer)); + + if (layer.is_selected()) + selected_layer_index = i; + + auto layer_location = new_layer->location(); + auto layer_local_crop_rect = new_layer->relative_rect().intersected(cropped_rect).translated(-layer_location.x(), -layer_location.y()); + TRY(new_layer->crop(layer_local_crop_rect, Layer::NotifyClients::NO)); auto new_layer_x = max(0, layer_location.x() - cropped_rect.x()); auto new_layer_y = max(0, layer_location.y() - cropped_rect.y()); - layer.set_location({ new_layer_x, new_layer_y }); + new_layer->set_location({ new_layer_x, new_layer_y }); + + cropped_layers.append(new_layer); } + m_layers = move(cropped_layers); + for (auto& layer : m_layers) + layer.did_modify_bitmap({}, Layer::NotifyClients::YES); + + select_layer(&m_layers[selected_layer_index]); + m_size = { cropped_rect.width(), cropped_rect.height() }; did_change_rect(cropped_rect); + + return {}; } Optional Image::nonempty_content_bounding_rect() const @@ -548,7 +614,7 @@ Optional Image::nonempty_content_bounding_rect() const return bounding_rect; } -void Image::resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode) +ErrorOr Image::resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode) { float scale_x = 1.0f; float scale_y = 1.0f; @@ -561,13 +627,35 @@ void Image::resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode scale_y = new_size.height() / static_cast(size().height()); } - for (auto& layer : m_layers) { - Gfx::IntPoint new_location(scale_x * layer.location().x(), scale_y * layer.location().y()); - layer.resize(new_size, new_location, scaling_mode); + Vector> resized_layers; + TRY(resized_layers.try_ensure_capacity(m_layers.size())); + + VERIFY(m_layers.size() > 0); + + size_t selected_layer_index = 0; + for (size_t i = 0; i < m_layers.size(); ++i) { + auto& layer = m_layers[i]; + auto new_layer = TRY(Layer::try_create_snapshot(*this, layer)); + + if (layer.is_selected()) + selected_layer_index = i; + + Gfx::IntPoint new_location(scale_x * new_layer->location().x(), scale_y * new_layer->location().y()); + TRY(new_layer->resize(new_size, new_location, scaling_mode, Layer::NotifyClients::NO)); + + resized_layers.append(new_layer); } + m_layers = move(resized_layers); + for (auto& layer : m_layers) + layer.did_modify_bitmap({}, Layer::NotifyClients::YES); + + select_layer(&m_layers[selected_layer_index]); + m_size = { new_size.width(), new_size.height() }; did_change_rect(); + + return {}; } Color Image::color_at(Gfx::IntPoint point) const diff --git a/Userland/Applications/PixelPaint/Image.h b/Userland/Applications/PixelPaint/Image.h index ef66374698..e6b3ccab9a 100644 --- a/Userland/Applications/PixelPaint/Image.h +++ b/Userland/Applications/PixelPaint/Image.h @@ -97,10 +97,10 @@ public: size_t index_of(Layer const&) const; - void flip(Gfx::Orientation orientation); - void rotate(Gfx::RotationDirection direction); - void crop(Gfx::IntRect const& rect); - void resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode); + ErrorOr flip(Gfx::Orientation orientation); + ErrorOr rotate(Gfx::RotationDirection direction); + ErrorOr crop(Gfx::IntRect const& rect); + ErrorOr resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode); Optional nonempty_content_bounding_rect() const; diff --git a/Userland/Applications/PixelPaint/Layer.cpp b/Userland/Applications/PixelPaint/Layer.cpp index ef784a4308..9e41e7f104 100644 --- a/Userland/Applications/PixelPaint/Layer.cpp +++ b/Userland/Applications/PixelPaint/Layer.cpp @@ -64,7 +64,7 @@ Layer::Layer(Image& image, NonnullRefPtr bitmap, DeprecatedString n { } -void Layer::did_modify_bitmap(Gfx::IntRect const& rect) +void Layer::did_modify_bitmap(Gfx::IntRect const& rect, NotifyClients notify_clients) { if (!m_scratch_edited_bitmap.is_null()) { for (int y = 0; y < rect.height(); ++y) { @@ -81,7 +81,10 @@ void Layer::did_modify_bitmap(Gfx::IntRect const& rect) } } - m_image.layer_did_modify_bitmap({}, *this, rect); + // NOTE: If NotifyClients::NO is passed to this function the caller should handle notifying + // the clients of any bitmap changes. + if (notify_clients == NotifyClients::YES) + m_image.layer_did_modify_bitmap({}, *this, rect); update_cached_bitmap(); } @@ -194,53 +197,60 @@ ErrorOr Layer::try_set_bitmaps(NonnullRefPtr content, RefPtr< return {}; } -void Layer::flip(Gfx::Orientation orientation) +ErrorOr Layer::flip(Gfx::Orientation orientation, NotifyClients notify_clients) { - m_content_bitmap = *m_content_bitmap->flipped(orientation).release_value_but_fixme_should_propagate_errors(); + auto flipped_content_bitmap = TRY(m_content_bitmap->flipped(orientation)); if (m_mask_bitmap) - m_mask_bitmap = *m_mask_bitmap->flipped(orientation).release_value_but_fixme_should_propagate_errors(); + m_mask_bitmap = *TRY(m_mask_bitmap->flipped(orientation)); - did_modify_bitmap(); + m_content_bitmap = move(flipped_content_bitmap); + did_modify_bitmap({}, notify_clients); + + return {}; } -void Layer::rotate(Gfx::RotationDirection direction) +ErrorOr Layer::rotate(Gfx::RotationDirection direction, NotifyClients notify_clients) { - m_content_bitmap = *m_content_bitmap->rotated(direction).release_value_but_fixme_should_propagate_errors(); + auto rotated_content_bitmap = TRY(m_content_bitmap->rotated(direction)); if (m_mask_bitmap) - m_mask_bitmap = *m_mask_bitmap->rotated(direction).release_value_but_fixme_should_propagate_errors(); + m_mask_bitmap = *TRY(m_mask_bitmap->rotated(direction)); - did_modify_bitmap(); + m_content_bitmap = move(rotated_content_bitmap); + did_modify_bitmap({}, notify_clients); + + return {}; } -void Layer::crop(Gfx::IntRect const& rect) +ErrorOr Layer::crop(Gfx::IntRect const& rect, NotifyClients notify_clients) { - m_content_bitmap = *m_content_bitmap->cropped(rect).release_value_but_fixme_should_propagate_errors(); + auto cropped_content_bitmap = TRY(m_content_bitmap->cropped(rect)); if (m_mask_bitmap) - m_mask_bitmap = *m_mask_bitmap->cropped(rect).release_value_but_fixme_should_propagate_errors(); + m_mask_bitmap = *TRY(m_mask_bitmap->cropped(rect)); - did_modify_bitmap(); + m_content_bitmap = move(cropped_content_bitmap); + did_modify_bitmap({}, notify_clients); + + return {}; } -void Layer::resize(Gfx::IntSize new_size, Gfx::IntPoint new_location, Gfx::Painter::ScalingMode scaling_mode) +ErrorOr Layer::resize(Gfx::IntSize new_size, Gfx::IntPoint new_location, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients) { auto src_rect = Gfx::IntRect(Gfx::IntPoint(0, 0), size()); auto dst_rect = Gfx::IntRect(Gfx::IntPoint(0, 0), new_size); + auto resized_content_bitmap = TRY(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size)); { - auto dst = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size).release_value_but_fixme_should_propagate_errors(); - Gfx::Painter painter(dst); + Gfx::Painter painter(resized_content_bitmap); if (scaling_mode == Gfx::Painter::ScalingMode::None) { painter.blit(src_rect.top_left(), *m_content_bitmap, src_rect, 1.0f); } else { painter.draw_scaled_bitmap(dst_rect, *m_content_bitmap, src_rect, 1.0f, scaling_mode); } - - m_content_bitmap = move(dst); } if (m_mask_bitmap) { - auto dst = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size).release_value_but_fixme_should_propagate_errors(); + auto dst = TRY(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size)); Gfx::Painter painter(dst); if (scaling_mode == Gfx::Painter::ScalingMode::None) { @@ -252,18 +262,22 @@ void Layer::resize(Gfx::IntSize new_size, Gfx::IntPoint new_location, Gfx::Paint m_mask_bitmap = move(dst); } + m_content_bitmap = move(resized_content_bitmap); + set_location(new_location); - did_modify_bitmap(); + did_modify_bitmap({}, notify_clients); + + return {}; } -void Layer::resize(Gfx::IntRect const& new_rect, Gfx::Painter::ScalingMode scaling_mode) +ErrorOr Layer::resize(Gfx::IntRect const& new_rect, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients) { - resize(new_rect.size(), new_rect.location(), scaling_mode); + return resize(new_rect.size(), new_rect.location(), scaling_mode, notify_clients); } -void Layer::resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode) +ErrorOr Layer::resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients) { - resize(new_size, location(), scaling_mode); + return resize(new_size, location(), scaling_mode, notify_clients); } void Layer::update_cached_bitmap() diff --git a/Userland/Applications/PixelPaint/Layer.h b/Userland/Applications/PixelPaint/Layer.h index ba5e86d113..f9cae667a2 100644 --- a/Userland/Applications/PixelPaint/Layer.h +++ b/Userland/Applications/PixelPaint/Layer.h @@ -56,18 +56,23 @@ public: DeprecatedString const& name() const { return m_name; } void set_name(DeprecatedString); - void flip(Gfx::Orientation orientation); - void rotate(Gfx::RotationDirection direction); - void crop(Gfx::IntRect const& rect); - void resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode); - void resize(Gfx::IntRect const& new_rect, Gfx::Painter::ScalingMode scaling_mode); - void resize(Gfx::IntSize new_size, Gfx::IntPoint new_location, Gfx::Painter::ScalingMode scaling_mode); + enum NotifyClients { + YES, + NO + }; + + ErrorOr flip(Gfx::Orientation orientation, NotifyClients notify_clients = NotifyClients::YES); + ErrorOr rotate(Gfx::RotationDirection direction, NotifyClients notify_clients = NotifyClients::YES); + ErrorOr crop(Gfx::IntRect const& rect, NotifyClients notify_clients = NotifyClients::YES); + ErrorOr resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients = NotifyClients::YES); + ErrorOr resize(Gfx::IntRect const& new_rect, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients = NotifyClients::YES); + ErrorOr resize(Gfx::IntSize new_size, Gfx::IntPoint new_location, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients = NotifyClients::YES); Optional nonempty_content_bounding_rect() const; ErrorOr try_set_bitmaps(NonnullRefPtr content, RefPtr mask); - void did_modify_bitmap(Gfx::IntRect const& = {}); + void did_modify_bitmap(Gfx::IntRect const& = {}, NotifyClients notify_clients = NotifyClients::YES); void set_selected(bool selected) { m_selected = selected; } bool is_selected() const { return m_selected; } diff --git a/Userland/Applications/PixelPaint/MainWidget.cpp b/Userland/Applications/PixelPaint/MainWidget.cpp index d5394ee513..987f768e9e 100644 --- a/Userland/Applications/PixelPaint/MainWidget.cpp +++ b/Userland/Applications/PixelPaint/MainWidget.cpp @@ -15,6 +15,7 @@ #include "FilterParams.h" #include "LevelsDialog.h" #include "ResizeImageDialog.h" +#include #include #include #include @@ -565,14 +566,22 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) "Flip Image &Vertically", g_icon_bag.edit_flip_vertical, [&](auto&) { auto* editor = current_image_editor(); VERIFY(editor); - editor->image().flip(Gfx::Orientation::Vertical); + auto image_flip_or_error = editor->image().flip(Gfx::Orientation::Vertical); + if (image_flip_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to flip image: {}", image_flip_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Flip Image Vertically"sv); })); m_image_menu->add_action(GUI::Action::create( "Flip Image &Horizontally", g_icon_bag.edit_flip_horizontal, [&](auto&) { auto* editor = current_image_editor(); VERIFY(editor); - editor->image().flip(Gfx::Orientation::Horizontal); + auto image_flip_or_error = editor->image().flip(Gfx::Orientation::Horizontal); + if (image_flip_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to flip image: {}", image_flip_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Flip Image Horizontally"sv); })); m_image_menu->add_separator(); @@ -581,7 +590,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) [&](auto&) { auto* editor = current_image_editor(); VERIFY(editor); - editor->image().rotate(Gfx::RotationDirection::CounterClockwise); + auto image_rotate_or_error = editor->image().rotate(Gfx::RotationDirection::CounterClockwise); + if (image_rotate_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to rotate image: {}", image_rotate_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Rotate Image Counterclockwise"sv); })); @@ -589,7 +602,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) [&](auto&) { auto* editor = current_image_editor(); VERIFY(editor); - editor->image().rotate(Gfx::RotationDirection::Clockwise); + auto image_rotate_or_error = editor->image().rotate(Gfx::RotationDirection::Clockwise); + if (image_rotate_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to rotate image: {}", image_rotate_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Rotate Image Clockwise"sv); })); m_image_menu->add_separator(); @@ -599,7 +616,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) VERIFY(editor); auto dialog = PixelPaint::ResizeImageDialog::construct(editor->image().size(), &window); if (dialog->exec() == GUI::Dialog::ExecResult::OK) { - editor->image().resize(dialog->desired_size(), dialog->scaling_mode()); + auto image_resize_or_error = editor->image().resize(dialog->desired_size(), dialog->scaling_mode()); + if (image_resize_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to resize image: {}", image_resize_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Resize Image"sv); } })); @@ -611,7 +632,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) if (editor->image().selection().is_empty()) return; auto crop_rect = editor->image().rect().intersected(editor->image().selection().bounding_rect()); - editor->image().crop(crop_rect); + auto image_crop_or_error = editor->image().crop(crop_rect); + if (image_crop_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to crop image: {}", image_crop_or_error.error().string_literal()))); + return; + } editor->image().selection().clear(); editor->did_complete_action("Crop Image to Selection"sv); })); @@ -625,7 +650,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) if (!content_bounding_rect.has_value()) return; - editor->image().crop(content_bounding_rect.value()); + auto image_crop_or_error = editor->image().crop(content_bounding_rect.value()); + if (image_crop_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to crop image: {}", image_crop_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Crop Image to Content"sv); })); @@ -833,7 +862,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) auto active_layer = editor->active_layer(); if (!active_layer) return; - active_layer->flip(Gfx::Orientation::Vertical); + auto layer_flip_or_error = active_layer->flip(Gfx::Orientation::Vertical); + if (layer_flip_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to flip layer: {}", layer_flip_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Flip Layer Vertically"sv); })); m_layer_menu->add_action(GUI::Action::create( @@ -843,7 +876,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) auto active_layer = editor->active_layer(); if (!active_layer) return; - active_layer->flip(Gfx::Orientation::Horizontal); + auto layer_flip_or_error = active_layer->flip(Gfx::Orientation::Horizontal); + if (layer_flip_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to flip layer: {}", layer_flip_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Flip Layer Horizontally"sv); })); m_layer_menu->add_separator(); @@ -855,7 +892,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) auto active_layer = editor->active_layer(); if (!active_layer) return; - active_layer->rotate(Gfx::RotationDirection::CounterClockwise); + auto layer_rotate_or_error = active_layer->rotate(Gfx::RotationDirection::CounterClockwise); + if (layer_rotate_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to rotate layer: {}", layer_rotate_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Rotate Layer Counterclockwise"sv); })); @@ -866,7 +907,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) auto active_layer = editor->active_layer(); if (!active_layer) return; - active_layer->rotate(Gfx::RotationDirection::Clockwise); + auto layer_rotate_or_error = active_layer->rotate(Gfx::RotationDirection::Clockwise); + if (layer_rotate_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to rotate layer: {}", layer_rotate_or_error.error().string_literal()))); + return; + } editor->did_complete_action("Rotate Layer Clockwise"sv); })); @@ -881,7 +926,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) return; auto intersection = editor->image().rect().intersected(editor->image().selection().bounding_rect()); auto crop_rect = intersection.translated(-active_layer->location()); - active_layer->crop(crop_rect); + auto layer_crop_or_error = active_layer->crop(crop_rect); + if (layer_crop_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to crop layer: {}", layer_crop_or_error.error().string_literal()))); + return; + } active_layer->set_location(intersection.location()); editor->image().selection().clear(); editor->did_complete_action("Crop Layer to Selection"sv); @@ -896,7 +945,11 @@ ErrorOr MainWidget::initialize_menubar(GUI::Window& window) auto content_bounding_rect = active_layer->nonempty_content_bounding_rect(); if (!content_bounding_rect.has_value()) return; - active_layer->crop(content_bounding_rect.value()); + auto layer_crop_or_error = active_layer->crop(content_bounding_rect.value()); + if (layer_crop_or_error.is_error()) { + GUI::MessageBox::show_error(&window, MUST(String::formatted("Failed to crop layer: {}", layer_crop_or_error.error().string_literal()))); + return; + } active_layer->set_location(content_bounding_rect->location()); editor->did_complete_action("Crop Layer to Content"sv); })); diff --git a/Userland/Applications/PixelPaint/Tools/MoveTool.cpp b/Userland/Applications/PixelPaint/Tools/MoveTool.cpp index 5906c1c001..89a1e8db36 100644 --- a/Userland/Applications/PixelPaint/Tools/MoveTool.cpp +++ b/Userland/Applications/PixelPaint/Tools/MoveTool.cpp @@ -9,8 +9,10 @@ #include "../Image.h" #include "../ImageEditor.h" #include "../Layer.h" +#include #include #include +#include #include #include #include @@ -101,8 +103,11 @@ void MoveTool::on_mouseup(Layer* layer, MouseEvent& event) return; if (m_scaling) { - m_editor->active_layer()->resize(m_new_layer_size, m_new_scaled_layer_location, Gfx::Painter::ScalingMode::BilinearBlend); - m_editor->layers_did_change(); + auto resized_or_error = m_editor->active_layer()->resize(m_new_layer_size, m_new_scaled_layer_location, Gfx::Painter::ScalingMode::BilinearBlend); + if (resized_or_error.is_error()) + GUI::MessageBox::show_error(m_editor->window(), MUST(String::formatted("Failed to resize layer: {}", resized_or_error.error().string_literal()))); + else + m_editor->layers_did_change(); } m_scaling = false;