mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
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:))
This commit is contained in:
parent
65b420f996
commit
e89c649be1
6 changed files with 232 additions and 67 deletions
|
@ -492,40 +492,106 @@ void ImageUndoCommand::redo()
|
|||
undo();
|
||||
}
|
||||
|
||||
void Image::flip(Gfx::Orientation orientation)
|
||||
ErrorOr<void> Image::flip(Gfx::Orientation orientation)
|
||||
{
|
||||
for (auto& layer : m_layers) {
|
||||
layer.flip(orientation);
|
||||
Vector<NonnullRefPtr<Layer>> 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<void> Image::rotate(Gfx::RotationDirection direction)
|
||||
{
|
||||
for (auto& layer : m_layers) {
|
||||
layer.rotate(direction);
|
||||
Vector<NonnullRefPtr<Layer>> 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<void> 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<NonnullRefPtr<Layer>> 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<Gfx::IntRect> Image::nonempty_content_bounding_rect() const
|
||||
|
@ -548,7 +614,7 @@ Optional<Gfx::IntRect> Image::nonempty_content_bounding_rect() const
|
|||
return bounding_rect;
|
||||
}
|
||||
|
||||
void Image::resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode)
|
||||
ErrorOr<void> 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<float>(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<NonnullRefPtr<Layer>> 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
|
||||
|
|
|
@ -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<void> flip(Gfx::Orientation orientation);
|
||||
ErrorOr<void> rotate(Gfx::RotationDirection direction);
|
||||
ErrorOr<void> crop(Gfx::IntRect const& rect);
|
||||
ErrorOr<void> resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode);
|
||||
|
||||
Optional<Gfx::IntRect> nonempty_content_bounding_rect() const;
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ Layer::Layer(Image& image, NonnullRefPtr<Gfx::Bitmap> 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,6 +81,9 @@ void Layer::did_modify_bitmap(Gfx::IntRect const& 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<void> Layer::try_set_bitmaps(NonnullRefPtr<Gfx::Bitmap> content, RefPtr<
|
|||
return {};
|
||||
}
|
||||
|
||||
void Layer::flip(Gfx::Orientation orientation)
|
||||
ErrorOr<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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()
|
||||
|
|
|
@ -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<void> flip(Gfx::Orientation orientation, NotifyClients notify_clients = NotifyClients::YES);
|
||||
ErrorOr<void> rotate(Gfx::RotationDirection direction, NotifyClients notify_clients = NotifyClients::YES);
|
||||
ErrorOr<void> crop(Gfx::IntRect const& rect, NotifyClients notify_clients = NotifyClients::YES);
|
||||
ErrorOr<void> resize(Gfx::IntSize new_size, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients = NotifyClients::YES);
|
||||
ErrorOr<void> resize(Gfx::IntRect const& new_rect, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients = NotifyClients::YES);
|
||||
ErrorOr<void> resize(Gfx::IntSize new_size, Gfx::IntPoint new_location, Gfx::Painter::ScalingMode scaling_mode, NotifyClients notify_clients = NotifyClients::YES);
|
||||
|
||||
Optional<Gfx::IntRect> nonempty_content_bounding_rect() const;
|
||||
|
||||
ErrorOr<void> try_set_bitmaps(NonnullRefPtr<Gfx::Bitmap> content, RefPtr<Gfx::Bitmap> 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; }
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "FilterParams.h"
|
||||
#include "LevelsDialog.h"
|
||||
#include "ResizeImageDialog.h"
|
||||
#include <AK/String.h>
|
||||
#include <Applications/PixelPaint/PixelPaintWindowGML.h>
|
||||
#include <LibConfig/Client.h>
|
||||
#include <LibCore/Debounce.h>
|
||||
|
@ -565,14 +566,22 @@ ErrorOr<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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);
|
||||
}));
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
#include "../Image.h"
|
||||
#include "../ImageEditor.h"
|
||||
#include "../Layer.h"
|
||||
#include <AK/String.h>
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/MessageBox.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibGfx/Filters/ContrastFilter.h>
|
||||
|
@ -101,7 +103,10 @@ 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);
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue