diff options
author | thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> | 2022-03-19 08:52:26 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-20 20:00:25 +0100 |
commit | 212817ea2023e64ee808589c1ca7d1a061870f6a (patch) | |
tree | 15dcdc2dac3a4a2bed3c861acb0665ac846d78a8 /Userland/Applications | |
parent | df443863bdca014660c26f65d9a3ad4d9831cb83 (diff) | |
download | serenity-212817ea2023e64ee808589c1ca7d1a061870f6a.zip |
FontEditor: Restore selections on undo/redo actions
This makes navigating undo history a lot easier to follow.
Individual glyph alterations now reset selection size if necessary
to save space.
Diffstat (limited to 'Userland/Applications')
-rw-r--r-- | Userland/Applications/FontEditor/FontEditor.cpp | 58 | ||||
-rw-r--r-- | Userland/Applications/FontEditor/FontEditor.h | 2 | ||||
-rw-r--r-- | Userland/Applications/FontEditor/UndoSelection.h | 19 |
3 files changed, 60 insertions, 19 deletions
diff --git a/Userland/Applications/FontEditor/FontEditor.cpp b/Userland/Applications/FontEditor/FontEditor.cpp index 71f0f6c20e..b69057b8be 100644 --- a/Userland/Applications/FontEditor/FontEditor.cpp +++ b/Userland/Applications/FontEditor/FontEditor.cpp @@ -348,7 +348,7 @@ FontEditorWidget::FontEditorWidget() }; m_glyph_editor_widget->on_undo_event = [this] { - m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection)); + reset_selection_and_push_undo(); }; m_glyph_map_widget->on_active_glyph_changed = [this](int glyph) { @@ -356,6 +356,7 @@ FontEditorWidget::FontEditorWidget() auto selection = m_glyph_map_widget->selection().normalized(); m_undo_selection->set_start(selection.start()); m_undo_selection->set_size(selection.size()); + m_undo_selection->set_active_glyph(glyph); } m_glyph_editor_widget->set_glyph(glyph); auto glyph_width = m_edited_font->raw_glyph_width(glyph); @@ -389,7 +390,7 @@ FontEditorWidget::FontEditorWidget() }; m_glyph_editor_width_spinbox->on_change = [this](int value) { - m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection)); + reset_selection_and_push_undo(); m_edited_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()); @@ -399,7 +400,7 @@ FontEditorWidget::FontEditorWidget() }; m_glyph_editor_present_checkbox->on_checked = [this](bool checked) { - m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection)); + reset_selection_and_push_undo(); m_edited_font->set_glyph_width(m_glyph_map_widget->active_glyph(), checked ? m_edited_font->glyph_fixed_width() : 0); m_glyph_editor_widget->update(); m_glyph_map_widget->update_glyph(m_glyph_map_widget->active_glyph()); @@ -562,7 +563,7 @@ void FontEditorWidget::initialize(String const& path, RefPtr<Gfx::BitmapFont>&& }); m_undo_stack = make<GUI::UndoStack>(); - m_undo_selection = adopt_ref(*new UndoSelection(m_glyph_map_widget->selection().start(), m_glyph_map_widget->selection().size(), *m_edited_font)); + m_undo_selection = adopt_ref(*new UndoSelection(m_glyph_map_widget->selection().start(), m_glyph_map_widget->selection().size(), m_glyph_map_widget->active_glyph(), *m_edited_font)); m_undo_stack->on_state_change = [this] { m_undo_action->set_enabled(m_undo_stack->can_undo()); @@ -670,17 +671,38 @@ bool FontEditorWidget::open_file(String const& path) return true; } +void FontEditorWidget::reset_selection_and_push_undo() +{ + 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(); + } + m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection)); +} + void FontEditorWidget::undo() { if (!m_undo_stack->can_undo()) return; m_undo_stack->undo(); - auto glyph = m_undo_selection->previous_active_glyph(); + + auto glyph = m_undo_selection->restored_active_glyph(); auto glyph_width = edited_font().raw_glyph_width(glyph); if (glyph < m_range.first || glyph > m_range.last) m_search_textbox->set_text(""); - m_glyph_map_widget->set_active_glyph(glyph); - m_glyph_map_widget->scroll_to_glyph(glyph); + + deferred_invoke([this, glyph] { + auto start = m_undo_selection->restored_start(); + auto size = m_undo_selection->restored_size(); + m_glyph_map_widget->set_selection(start, size, glyph); + m_glyph_map_widget->scroll_to_glyph(glyph); + m_glyph_map_widget->set_focus(true); + }); + if (m_edited_font->is_fixed_width()) { m_glyph_editor_present_checkbox->set_checked(glyph_width > 0, GUI::AllowCallback::No); } else { @@ -697,12 +719,20 @@ void FontEditorWidget::redo() if (!m_undo_stack->can_redo()) return; m_undo_stack->redo(); - auto glyph = m_undo_selection->previous_active_glyph(); + + auto glyph = m_undo_selection->restored_active_glyph(); auto glyph_width = edited_font().raw_glyph_width(glyph); if (glyph < m_range.first || glyph > m_range.last) m_search_textbox->set_text(""); - m_glyph_map_widget->set_active_glyph(glyph); - m_glyph_map_widget->scroll_to_glyph(glyph); + + deferred_invoke([this, glyph] { + auto start = m_undo_selection->restored_start(); + auto size = m_undo_selection->restored_size(); + m_glyph_map_widget->set_selection(start, size, glyph); + m_glyph_map_widget->scroll_to_glyph(glyph); + m_glyph_map_widget->set_focus(true); + }); + if (m_edited_font->is_fixed_width()) { m_glyph_editor_present_checkbox->set_checked(glyph_width > 0, GUI::AllowCallback::No); } else { @@ -865,8 +895,7 @@ void FontEditorWidget::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); - if (m_glyph_editor_widget->on_undo_event) - m_glyph_editor_widget->on_undo_event(); + m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection)); size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * edited_font().glyph_height(); size_t bytes_per_copied_glyph = Gfx::GlyphBitmap::bytes_per_row() * height; @@ -882,6 +911,8 @@ void FontEditorWidget::paste_glyphs() memset(&widths[i], copyable_width, sizeof(u8)); } + m_glyph_map_widget->set_selection(selection.start() + range_bound_glyph_count - 1, -range_bound_glyph_count + 1); + if (m_edited_font->is_fixed_width()) m_glyph_editor_present_checkbox->set_checked(m_edited_font->contains_raw_glyph(m_glyph_map_widget->active_glyph()), GUI::AllowCallback::No); else @@ -894,8 +925,7 @@ void FontEditorWidget::paste_glyphs() void FontEditorWidget::delete_selected_glyphs() { - if (m_glyph_editor_widget->on_undo_event) - m_glyph_editor_widget->on_undo_event(); + m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection)); auto selection = m_glyph_map_widget->selection().normalized(); size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * m_edited_font->glyph_height(); diff --git a/Userland/Applications/FontEditor/FontEditor.h b/Userland/Applications/FontEditor/FontEditor.h index b63d9f6f98..d55b2f0980 100644 --- a/Userland/Applications/FontEditor/FontEditor.h +++ b/Userland/Applications/FontEditor/FontEditor.h @@ -60,6 +60,8 @@ private: void paste_glyphs(); void delete_selected_glyphs(); + void reset_selection_and_push_undo(); + RefPtr<Gfx::BitmapFont> m_edited_font; RefPtr<GUI::GlyphMapWidget> m_glyph_map_widget; diff --git a/Userland/Applications/FontEditor/UndoSelection.h b/Userland/Applications/FontEditor/UndoSelection.h index 57082ca4b7..dfb5384656 100644 --- a/Userland/Applications/FontEditor/UndoSelection.h +++ b/Userland/Applications/FontEditor/UndoSelection.h @@ -12,15 +12,16 @@ class UndoSelection : public RefCounted<UndoSelection> { public: - explicit UndoSelection(int const start, int const size, Gfx::BitmapFont const& font) + explicit UndoSelection(int const start, int const size, u32 const active_glyph, Gfx::BitmapFont const& font) : m_start(start) , m_size(size) + , m_active_glyph(active_glyph) , m_font(font) { } NonnullRefPtr<UndoSelection> save_state() { - auto state = adopt_ref(*new UndoSelection(m_start, m_size, *m_font)); + auto state = adopt_ref(*new UndoSelection(m_start, m_size, m_active_glyph, *m_font)); size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * font().glyph_height(); auto* rows = font().rows() + m_start * bytes_per_glyph; auto* widths = font().widths() + m_start; @@ -35,19 +36,27 @@ public: auto* widths = font().widths() + state.m_start; memcpy(rows, &state.m_data[0], bytes_per_glyph * state.m_size); memcpy(widths, &state.m_data[bytes_per_glyph * state.m_size], state.m_size); - m_previous_active_glyph = state.m_start; + m_restored_active_glyph = state.m_active_glyph; + m_restored_start = state.m_start; + m_restored_size = state.m_size; } void set_start(int start) { m_start = start; } void set_size(int size) { m_size = size; } + void set_active_glyph(u32 code_point) { m_active_glyph = code_point; } Gfx::BitmapFont& font() { return *m_font; } - u32 previous_active_glyph() const { return m_previous_active_glyph; } + u32 restored_active_glyph() const { return m_restored_active_glyph; } + int restored_start() const { return m_restored_start; } + int restored_size() const { return m_restored_size; } private: int m_start { 0 }; int m_size { 0 }; + u32 m_active_glyph { 0 }; + int m_restored_start { 0 }; + int m_restored_size { 0 }; + u32 m_restored_active_glyph { 0 }; RefPtr<Gfx::BitmapFont> m_font; ByteBuffer m_data; - u32 m_previous_active_glyph { 0 }; }; class SelectionUndoCommand : public GUI::Command { |