diff options
author | thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> | 2023-05-16 08:39:02 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-05-17 06:47:57 +0200 |
commit | c10b1e3aea997d84703d5e2641a371628ca5ca4e (patch) | |
tree | 7066371a068c470a571bf70dd97cfa5d9400d756 | |
parent | e6935cbaafe5736fa1c196dedecb13a8f8293aba (diff) | |
download | serenity-c10b1e3aea997d84703d5e2641a371628ca5ca4e.zip |
FontEditor: Add action text to Undo and Redo
5 files changed, 63 insertions, 28 deletions
diff --git a/Userland/Applications/FontEditor/GlyphEditorWidget.cpp b/Userland/Applications/FontEditor/GlyphEditorWidget.cpp index 4af38bee3a..0afa466be5 100644 --- a/Userland/Applications/FontEditor/GlyphEditorWidget.cpp +++ b/Userland/Applications/FontEditor/GlyphEditorWidget.cpp @@ -84,8 +84,6 @@ void GlyphEditorWidget::mousedown_event(GUI::MouseEvent& event) if (mode() == Move && is_glyph_empty()) return; m_is_clicking_valid_cell = true; - if (on_undo_event) - on_undo_event(); if (mode() == Paint) { draw_at_mouse(event); } else { @@ -146,6 +144,8 @@ void GlyphEditorWidget::draw_at_mouse(GUI::MouseEvent const& event) return; if (bitmap.bit_at(x, y) == set) return; + if (on_undo_event && event.type() == GUI::MouseEvent::MouseDown) + on_undo_event("Paint Glyph"sv); bitmap.set_bit_at(x, y, set); if (on_glyph_altered) on_glyph_altered(m_glyph); @@ -154,6 +154,9 @@ void GlyphEditorWidget::draw_at_mouse(GUI::MouseEvent const& event) void GlyphEditorWidget::move_at_mouse(GUI::MouseEvent const& event) { + if (on_undo_event && event.type() == GUI::MouseEvent::MouseDown) + on_undo_event("Move Glyph"sv); + int x_delta = ((event.x() - 1) / m_scale) - m_scaled_offset_x; int y_delta = ((event.y() - 1) / m_scale) - m_scaled_offset_y; auto bitmap = m_font->raw_glyph(m_glyph).glyph_bitmap(); @@ -190,12 +193,13 @@ static Vector<Vector<u8>> glyph_as_matrix(Gfx::GlyphBitmap const& bitmap) void GlyphEditorWidget::rotate_90(Gfx::RotationDirection direction) { + auto clockwise = direction == Gfx::RotationDirection::Clockwise; + auto action_text = clockwise ? "Rotate Glyph Clockwise"sv : "Rotate Glyph Counterclockwise"sv; if (on_undo_event) - on_undo_event(); + on_undo_event(action_text); auto bitmap = m_font->raw_glyph(m_glyph).glyph_bitmap(); auto matrix = glyph_as_matrix(bitmap); - auto clockwise = direction == Gfx::RotationDirection::Clockwise; for (int y = 0; y < bitmap.height(); y++) { for (int x = 0; x < bitmap.width(); x++) { @@ -216,12 +220,13 @@ void GlyphEditorWidget::rotate_90(Gfx::RotationDirection direction) void GlyphEditorWidget::flip(Gfx::Orientation orientation) { + auto vertical = orientation == Gfx::Orientation::Vertical; + auto action_text = vertical ? "Flip Glyph Vertically"sv : "Flip Glyph Horizontally"sv; if (on_undo_event) - on_undo_event(); + on_undo_event(action_text); auto bitmap = m_font->raw_glyph(m_glyph).glyph_bitmap(); auto matrix = glyph_as_matrix(bitmap); - auto vertical = orientation == Gfx::Orientation::Vertical; for (int y = 0; y < bitmap.height(); y++) { for (int x = 0; x < bitmap.width(); x++) { diff --git a/Userland/Applications/FontEditor/GlyphEditorWidget.h b/Userland/Applications/FontEditor/GlyphEditorWidget.h index eac3225ec7..802cb9e91c 100644 --- a/Userland/Applications/FontEditor/GlyphEditorWidget.h +++ b/Userland/Applications/FontEditor/GlyphEditorWidget.h @@ -42,7 +42,7 @@ public: void set_mode(Mode mode) { m_mode = mode; } Function<void(int)> on_glyph_altered; - Function<void()> on_undo_event; + Function<void(StringView action_text)> on_undo_event; private: GlyphEditorWidget() = default; diff --git a/Userland/Applications/FontEditor/MainWidget.cpp b/Userland/Applications/FontEditor/MainWidget.cpp index 7e4124645f..6a3347a5be 100644 --- a/Userland/Applications/FontEditor/MainWidget.cpp +++ b/Userland/Applications/FontEditor/MainWidget.cpp @@ -450,6 +450,7 @@ ErrorOr<void> MainWidget::create_undo_stack() m_undo_stack->on_state_change = [this] { m_undo_action->set_enabled(m_undo_stack->can_undo()); m_redo_action->set_enabled(m_undo_stack->can_redo()); + update_action_text(); if (m_undo_stack->is_current_modified()) did_modify_font(); }; @@ -457,6 +458,24 @@ ErrorOr<void> MainWidget::create_undo_stack() return {}; } +void MainWidget::update_action_text() +{ + auto text_or_error = [](auto prefix, auto suffix) -> ErrorOr<String> { + StringBuilder builder; + TRY(builder.try_append(prefix)); + if (suffix.has_value()) { + TRY(builder.try_append(' ')); + TRY(builder.try_append(suffix.value())); + } + return builder.to_string(); + }; + + if (auto maybe_text = text_or_error("&Undo"sv, m_undo_stack->undo_action_text()); !maybe_text.is_error()) + m_undo_action->set_text(maybe_text.release_value().to_deprecated_string()); + if (auto maybe_text = text_or_error("&Redo"sv, m_undo_stack->redo_action_text()); !maybe_text.is_error()) + m_redo_action->set_text(maybe_text.release_value().to_deprecated_string()); +} + ErrorOr<void> MainWidget::create_widgets() { TRY(load_from_gml(font_editor_window_gml)); @@ -474,8 +493,9 @@ ErrorOr<void> MainWidget::create_widgets() did_modify_font(); }; - m_glyph_editor_widget->on_undo_event = [this] { - reset_selection_and_push_undo(); + m_glyph_editor_widget->on_undo_event = [this](auto action_text) { + reset_selection(); + push_undo(action_text); }; m_glyph_editor_width_spinbox = find_descendant_of_type_named<GUI::SpinBox>("glyph_editor_width_spinbox"); @@ -530,7 +550,8 @@ ErrorOr<void> MainWidget::create_widgets() }; m_glyph_editor_width_spinbox->on_change = [this](int value) { - reset_selection_and_push_undo(); + reset_selection(); + push_undo("Resize Glyph"sv); m_font->set_glyph_width(m_glyph_map_widget->active_glyph(), value); m_glyph_editor_widget->update(); m_glyph_map_widget->update_glyph(m_glyph_map_widget->active_glyph()); @@ -540,7 +561,8 @@ ErrorOr<void> MainWidget::create_widgets() }; m_glyph_editor_present_checkbox->on_checked = [this](bool checked) { - reset_selection_and_push_undo(); + reset_selection(); + push_undo("Resize Glyph"sv); m_font->set_glyph_width(m_glyph_map_widget->active_glyph(), checked ? m_font->glyph_fixed_width() : 0); m_glyph_editor_widget->update(); m_glyph_map_widget->update_glyph(m_glyph_map_widget->active_glyph()); @@ -788,29 +810,31 @@ ErrorOr<void> MainWidget::open_file(StringView path, NonnullOwnPtr<Core::File> f return {}; } -void MainWidget::push_undo() +void MainWidget::push_undo(StringView action_text) { auto maybe_state = m_undo_selection->save_state(); if (maybe_state.is_error()) return show_error(maybe_state.release_error(), "Saving undo state failed"sv); - auto maybe_command = try_make<SelectionUndoCommand>(*m_undo_selection, move(maybe_state.value())); + auto maybe_text = String::from_utf8(action_text); + if (maybe_text.is_error()) + return show_error(maybe_text.release_error(), "Creating action text failed"sv); + auto maybe_command = try_make<SelectionUndoCommand>(*m_undo_selection, move(maybe_state.value()), move(maybe_text.value())); if (maybe_command.is_error()) return show_error(maybe_command.release_error(), "Making undo command failed"sv); if (auto maybe_push = m_undo_stack->try_push(move(maybe_command.value())); maybe_push.is_error()) show_error(maybe_push.release_error(), "Pushing undo stack failed"sv); } -void MainWidget::reset_selection_and_push_undo() +void MainWidget::reset_selection() { auto selection = m_glyph_map_widget->selection().normalized(); - if (selection.size() != 1) { - auto start = m_glyph_map_widget->active_glyph(); - m_undo_selection->set_start(start); - m_undo_selection->set_size(1); - m_glyph_map_widget->set_selection(start, 1); - m_glyph_map_widget->update(); - } - push_undo(); + if (selection.size() == 1) + return; + auto start = m_glyph_map_widget->active_glyph(); + m_undo_selection->set_start(start); + m_undo_selection->set_size(1); + m_glyph_map_widget->set_selection(start, 1); + m_glyph_map_widget->update(); } void MainWidget::restore_state() @@ -1023,7 +1047,8 @@ void MainWidget::paste_glyphs() auto selection = m_glyph_map_widget->selection().normalized(); auto range_bound_glyph_count = min(glyph_count, 1 + m_range.last - selection.start()); m_undo_selection->set_size(range_bound_glyph_count); - push_undo(); + auto action_text = range_bound_glyph_count == 1 ? "Paste Glyph"sv : "Paste Glyphs"sv; + push_undo(action_text); size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * m_font->glyph_height(); size_t bytes_per_copied_glyph = Gfx::GlyphBitmap::bytes_per_row() * height; @@ -1055,9 +1080,10 @@ void MainWidget::paste_glyphs() void MainWidget::delete_selected_glyphs() { - push_undo(); - auto selection = m_glyph_map_widget->selection().normalized(); + auto action_text = selection.size() == 1 ? "Delete Glyph"sv : "Delete Glyphs"sv; + push_undo(action_text); + size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * m_font->glyph_height(); auto* rows = m_font->rows() + selection.start() * bytes_per_glyph; auto* widths = m_font->widths() + selection.start(); diff --git a/Userland/Applications/FontEditor/MainWidget.h b/Userland/Applications/FontEditor/MainWidget.h index 3e76f9e360..5fd679d1b7 100644 --- a/Userland/Applications/FontEditor/MainWidget.h +++ b/Userland/Applications/FontEditor/MainWidget.h @@ -59,6 +59,7 @@ private: void restore_state(); void did_modify_font(); + void update_action_text(); void update_statusbar(); void update_preview(); void update_title(); @@ -72,8 +73,8 @@ private: void paste_glyphs(); void delete_selected_glyphs(); - void push_undo(); - void reset_selection_and_push_undo(); + void push_undo(StringView action_text); + void reset_selection(); RefPtr<GUI::GlyphMapWidget> m_glyph_map_widget; RefPtr<GlyphEditorWidget> m_glyph_editor_widget; diff --git a/Userland/Applications/FontEditor/UndoSelection.h b/Userland/Applications/FontEditor/UndoSelection.h index 69d97b8a26..f73e478e29 100644 --- a/Userland/Applications/FontEditor/UndoSelection.h +++ b/Userland/Applications/FontEditor/UndoSelection.h @@ -74,9 +74,10 @@ private: class SelectionUndoCommand : public GUI::Command { public: - SelectionUndoCommand(UndoSelection& selection, NonnullRefPtr<UndoSelection> undo_state) + SelectionUndoCommand(UndoSelection& selection, NonnullRefPtr<UndoSelection> undo_state, String action_text) : m_undo_state(undo_state) , m_undo_selection(selection) + , m_action_text(move(action_text)) { } virtual void undo() override @@ -96,9 +97,11 @@ public: else warnln("Restoring state failed"); } + virtual DeprecatedString action_text() const override { return m_action_text.to_deprecated_string(); } private: NonnullRefPtr<UndoSelection> m_undo_state; RefPtr<UndoSelection> m_redo_state; UndoSelection& m_undo_selection; + String m_action_text; }; |