summaryrefslogtreecommitdiff
path: root/Userland/Applications
diff options
context:
space:
mode:
authorthankyouverycool <66646555+thankyouverycool@users.noreply.github.com>2022-03-19 08:52:26 -0400
committerAndreas Kling <kling@serenityos.org>2022-03-20 20:00:25 +0100
commit212817ea2023e64ee808589c1ca7d1a061870f6a (patch)
tree15dcdc2dac3a4a2bed3c861acb0665ac846d78a8 /Userland/Applications
parentdf443863bdca014660c26f65d9a3ad4d9831cb83 (diff)
downloadserenity-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.cpp58
-rw-r--r--Userland/Applications/FontEditor/FontEditor.h2
-rw-r--r--Userland/Applications/FontEditor/UndoSelection.h19
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 {