mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:57:35 +00:00
FontEditor: Make undo/redo compatible with multi-glyph selections
Previously the glyph undo stack saved an array of bytes representing the restore state of an individual glyph when modified. Now the selection undo stack saves a byte buffer of the entire selection, letting us restore changes to multiple glyphs at once.
This commit is contained in:
parent
5c27ce2561
commit
a3956da6dc
5 changed files with 99 additions and 108 deletions
|
@ -348,12 +348,15 @@ FontEditorWidget::FontEditorWidget()
|
|||
};
|
||||
|
||||
m_glyph_editor_widget->on_undo_event = [this] {
|
||||
m_undo_stack->push(make<GlyphUndoCommand>(*m_undo_glyph));
|
||||
m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection));
|
||||
};
|
||||
|
||||
m_glyph_map_widget->on_active_glyph_changed = [this](int glyph) {
|
||||
if (m_undo_glyph)
|
||||
m_undo_glyph->set_code_point(glyph);
|
||||
if (m_undo_selection) {
|
||||
auto selection = m_glyph_map_widget->selection().normalized();
|
||||
m_undo_selection->set_start(selection.start());
|
||||
m_undo_selection->set_size(selection.size());
|
||||
}
|
||||
m_glyph_editor_widget->set_glyph(glyph);
|
||||
auto glyph_width = m_edited_font->raw_glyph_width(glyph);
|
||||
if (m_edited_font->is_fixed_width())
|
||||
|
@ -386,7 +389,7 @@ FontEditorWidget::FontEditorWidget()
|
|||
};
|
||||
|
||||
m_glyph_editor_width_spinbox->on_change = [this](int value) {
|
||||
m_undo_stack->push(make<GlyphUndoCommand>(*m_undo_glyph));
|
||||
m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection));
|
||||
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());
|
||||
|
@ -396,7 +399,7 @@ FontEditorWidget::FontEditorWidget()
|
|||
};
|
||||
|
||||
m_glyph_editor_present_checkbox->on_checked = [this](bool checked) {
|
||||
m_undo_stack->push(make<GlyphUndoCommand>(*m_undo_glyph));
|
||||
m_undo_stack->push(make<SelectionUndoCommand>(*m_undo_selection));
|
||||
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());
|
||||
|
@ -559,7 +562,7 @@ void FontEditorWidget::initialize(String const& path, RefPtr<Gfx::BitmapFont>&&
|
|||
});
|
||||
|
||||
m_undo_stack = make<GUI::UndoStack>();
|
||||
m_undo_glyph = adopt_ref(*new UndoGlyph(m_glyph_map_widget->active_glyph(), *m_edited_font));
|
||||
m_undo_selection = adopt_ref(*new UndoSelection(m_glyph_map_widget->selection().start(), m_glyph_map_widget->selection().size(), *m_edited_font));
|
||||
|
||||
m_undo_stack->on_state_change = [this] {
|
||||
m_undo_action->set_enabled(m_undo_stack->can_undo());
|
||||
|
@ -672,8 +675,8 @@ void FontEditorWidget::undo()
|
|||
if (!m_undo_stack->can_undo())
|
||||
return;
|
||||
m_undo_stack->undo();
|
||||
auto glyph = m_undo_glyph->restored_code_point();
|
||||
auto glyph_width = m_undo_glyph->restored_width();
|
||||
auto glyph = m_undo_selection->previous_active_glyph();
|
||||
auto glyph_width = edited_font().raw_glyph_width(glyph);
|
||||
m_glyph_map_widget->set_active_glyph(glyph);
|
||||
m_glyph_map_widget->scroll_to_glyph(glyph);
|
||||
if (m_edited_font->is_fixed_width()) {
|
||||
|
@ -681,9 +684,8 @@ void FontEditorWidget::undo()
|
|||
} else {
|
||||
m_glyph_editor_width_spinbox->set_value(glyph_width, GUI::AllowCallback::No);
|
||||
}
|
||||
m_edited_font->set_glyph_width(m_glyph_map_widget->active_glyph(), glyph_width);
|
||||
m_glyph_editor_widget->update();
|
||||
m_glyph_map_widget->update_glyph(glyph);
|
||||
m_glyph_map_widget->update();
|
||||
update_preview();
|
||||
update_statusbar();
|
||||
}
|
||||
|
@ -693,8 +695,8 @@ void FontEditorWidget::redo()
|
|||
if (!m_undo_stack->can_redo())
|
||||
return;
|
||||
m_undo_stack->redo();
|
||||
auto glyph = m_undo_glyph->restored_code_point();
|
||||
auto glyph_width = m_undo_glyph->restored_width();
|
||||
auto glyph = m_undo_selection->previous_active_glyph();
|
||||
auto glyph_width = edited_font().raw_glyph_width(glyph);
|
||||
m_glyph_map_widget->set_active_glyph(glyph);
|
||||
m_glyph_map_widget->scroll_to_glyph(glyph);
|
||||
if (m_edited_font->is_fixed_width()) {
|
||||
|
@ -702,9 +704,8 @@ void FontEditorWidget::redo()
|
|||
} else {
|
||||
m_glyph_editor_width_spinbox->set_value(glyph_width, GUI::AllowCallback::No);
|
||||
}
|
||||
m_edited_font->set_glyph_width(m_glyph_map_widget->active_glyph(), glyph_width);
|
||||
m_glyph_editor_widget->update();
|
||||
m_glyph_map_widget->update_glyph(glyph);
|
||||
m_glyph_map_widget->update();
|
||||
update_preview();
|
||||
update_statusbar();
|
||||
}
|
||||
|
@ -857,15 +858,11 @@ void FontEditorWidget::paste_glyphs()
|
|||
if (!height)
|
||||
return;
|
||||
|
||||
// FIXME: This is a hack to avoid regression and still doesn't support
|
||||
// multiple glyphs. It should have done proper undo stack integration.
|
||||
if (glyph_count == 1) {
|
||||
if (m_glyph_editor_widget->on_undo_event)
|
||||
m_glyph_editor_widget->on_undo_event();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
|
@ -893,15 +890,10 @@ void FontEditorWidget::paste_glyphs()
|
|||
|
||||
void FontEditorWidget::delete_selected_glyphs()
|
||||
{
|
||||
if (m_glyph_editor_widget->on_undo_event)
|
||||
m_glyph_editor_widget->on_undo_event();
|
||||
|
||||
auto selection = m_glyph_map_widget->selection().normalized();
|
||||
|
||||
// FIXME: This is a hack to avoid regression and still doesn't support
|
||||
// multiple glyphs. It should have done proper undo stack integration.
|
||||
if (selection.size() == 1) {
|
||||
if (m_glyph_editor_widget->on_undo_event)
|
||||
m_glyph_editor_widget->on_undo_event();
|
||||
}
|
||||
|
||||
size_t bytes_per_glyph = Gfx::GlyphBitmap::bytes_per_row() * m_edited_font->glyph_height();
|
||||
auto* rows = m_edited_font->rows() + selection.start() * bytes_per_glyph;
|
||||
auto* widths = m_edited_font->widths() + selection.start();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue