Commit 8deb179
Redo
Changed files (8)
modifiedNEWSmodifiedbirdfont/GtkWindow.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/FontDisplay.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/KerningDisplay.valamodifiedlibbirdfont/OverView.valamodifiedlibbirdfont/TabContent.vala
Diff
@@ -7,8 +7,9 @@ birdfont (1.0) stable; to another. This feature makes it easier to create fonts with only upper case characters as well as mono spaced fonts. * Copy and paste multiple glyphs in the overview tab.+ * Redo command - -- Johan Mattsson <johan.mattsson.m@gmail.com> Tue Sep 2 14:57:52 CEST 2014+ -- Johan Mattsson <johan.mattsson.m@gmail.com> Wed Sep 3 13:36:00 CEST 2014 birdfont (0.46) stable; @@ -487,7 +487,12 @@ public class GtkWindow : Gtk.Window, NativeWindow { edit_menu.append (undo_item); undo_item.activate.connect (() => { TabContent.undo (); }); undo_item.add_accelerator ("activate", accel_group, 'Z', Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE);- ++ Gtk.MenuItem redo_item = new Gtk.MenuItem.with_mnemonic (t_("_Redo"));+ edit_menu.append (redo_item);+ redo_item.activate.connect (() => { TabContent.redo (); }); + redo_item.add_accelerator ("activate", accel_group, 'Y', Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE);+ Gtk.MenuItem copy_item = new Gtk.MenuItem.with_mnemonic (t_("_Copy")); edit_menu.append (copy_item); copy_item.activate.connect (() => { ClipTool.copy (); }); @@ -413,7 +413,10 @@ public class Font : GLib.Object { public void delete_glyph (GlyphCollection glyph) { glyph_cache.remove (glyph.get_unicode ()); glyph_name.remove (glyph.get_name ());- ligature.remove (glyph.get_current ().get_ligature_string ());+ + if (glyph.length () > 0) {+ ligature.remove (glyph.get_current ().get_ligature_string ());+ } foreach (Glyph g in glyph.get_version_list ().glyphs) { deleted_glyphs.add (g);@@ -145,6 +145,9 @@ public abstract class FontDisplay : GLib.Object { public virtual void undo () { } + public virtual void redo () {+ }+ public static File find_file (string? dir, string name) { return SearchPaths.find_file (dir, name); }@@ -79,7 +79,8 @@ public class Glyph : FontDisplay { bool margin_boundaries_visible = false; Gee.ArrayList<Glyph> undo_list = new Gee.ArrayList<Glyph> ();- + Gee.ArrayList<Glyph> redo_list = new Gee.ArrayList<Glyph> ();+ string glyph_sequence = ""; bool open = true; @@ -138,6 +139,7 @@ public class Glyph : FontDisplay { public override void close () { undo_list.clear ();+ redo_list.clear (); } public string get_ligature_string () {@@ -1616,9 +1618,18 @@ public class Glyph : FontDisplay { redraw_area (0, 0, allocation.width, allocation.height); } - public void store_undo_state () {+ public void store_undo_state (bool clear_redo = false) { Glyph g = copy ();- undo_list.add (g); + undo_list.add (g);+ + if (clear_redo) {+ redo_list.clear ();+ }+ }++ public void store_redo_state () {+ Glyph g = copy ();+ redo_list.add (g); } public Glyph copy () {@@ -1670,6 +1681,8 @@ public class Glyph : FontDisplay { } g = undo_list.get (undo_list.size - 1); + + store_redo_state (); set_glyph_data (g); undo_list.remove_at (undo_list.size - 1);@@ -1678,6 +1691,25 @@ public class Glyph : FontDisplay { clear_active_paths (); }++ public override void redo () {+ Glyph g;+ + if (redo_list.size == 0) {+ return;+ }+ + g = redo_list.get (redo_list.size - 1); + + store_undo_state (false);+ set_glyph_data (g);+ + redo_list.remove_at (redo_list.size - 1);++ PenTool.update_selected_points ();+ + clear_active_paths ();+ } void set_glyph_data (Glyph g) { path_list.clear ();@@ -34,14 +34,16 @@ public class KerningDisplay : FontDisplay { bool parse_error = false; bool text_input = false;- + Gee.ArrayList<UndoItem> undo_items;+ Gee.ArrayList<UndoItem> redo_items; bool first_update = true; public KerningDisplay () { GlyphSequence w = new GlyphSequence (); row = new Gee.ArrayList <GlyphSequence> (); undo_items = new Gee.ArrayList <UndoItem> ();+ redo_items = new Gee.ArrayList <UndoItem> (); row.add (w); } @@ -384,7 +386,9 @@ public class KerningDisplay : FontDisplay { } /** Class based gpos kerning. */- public void set_kerning_pair (string a, string b, ref GlyphRange? gr_left, ref GlyphRange? gr_right, double val) {+ public void set_kerning_pair (string a, string b,+ ref GlyphRange? gr_left, ref GlyphRange? gr_right,+ double val) { double kern; GlyphRange grl, grr; KerningClasses classes = KerningClasses.get_instance ();@@ -419,6 +423,8 @@ public class KerningDisplay : FontDisplay { n = grr.get_all_ranges (); has_kerning = classes.has_kerning (f, n); undo_items.add (new UndoItem (f, n, kern, has_kerning));++ redo_items.clear (); first_update = false; } @@ -836,17 +842,49 @@ public class KerningDisplay : FontDisplay { public override void undo () { UndoItem ui;- KerningClasses classes = KerningClasses.get_instance ();- GlyphRange glyph_range_first, glyph_range_next;- Font font = BirdFont.get_current_font ();- string l, r;-+ UndoItem redo_state;+ + if (MenuTab.suppress_event) {+ return;+ }+ if (undo_items.size == 0) { return; } ui = undo_items.get (undo_items.size - 1);- + + redo_state = apply_undo (ui);+ redo_items.add (redo_state);+ + undo_items.remove_at (undo_items.size - 1);+ }++ public override void redo () {+ UndoItem ui;+ + if (MenuTab.suppress_event) {+ return;+ }+ + if (redo_items.size == 0) {+ return;+ }+ + ui = redo_items.get (redo_items.size - 1);+ apply_undo (ui);+ redo_items.remove_at (redo_items.size - 1);+ }+ + /** @return redo state. */+ public UndoItem apply_undo (UndoItem ui) {+ KerningClasses classes = KerningClasses.get_instance ();+ GlyphRange glyph_range_first, glyph_range_next;+ Font font = BirdFont.get_current_font ();+ string l, r;+ UndoItem redo_state = new UndoItem ("", "", 0, false);+ double? k;+ l = GlyphRange.unserialize (ui.first); r = GlyphRange.unserialize (ui.next); @@ -858,9 +896,26 @@ public class KerningDisplay : FontDisplay { glyph_range_first.parse_ranges (ui.first); glyph_range_next.parse_ranges (ui.next);-+ + redo_state.first = glyph_range_first.get_all_ranges ();+ redo_state.next = glyph_range_next.get_all_ranges ();+ redo_state.has_kerning = true;+ redo_state.kerning = classes.get_kerning_for_range (glyph_range_first, glyph_range_next);+ classes.delete_kerning_for_class (ui.first, ui.next); } else {+ + redo_state.first = ui.first;+ redo_state.next = ui.next;+ redo_state.has_kerning = true;+ k = classes.get_kerning_for_single_glyphs (ui.first, ui.next);+ + if (k != null) {+ redo_state.kerning = (!) k;+ } else {+ warning ("No kerning");+ }+ classes.delete_kerning_for_pair (ui.first, ui.next); } } else if (ui.first.char_count () > 1 || ui.next.char_count () > 1) {@@ -869,22 +924,46 @@ public class KerningDisplay : FontDisplay { glyph_range_first.parse_ranges (ui.first); glyph_range_next.parse_ranges (ui.next);++ redo_state.first = glyph_range_first.get_all_ranges ();+ redo_state.next = glyph_range_next.get_all_ranges ();+ k = classes.get_kerning_for_range (glyph_range_first, glyph_range_next); + if (k != null) {+ redo_state.kerning = (!) k;+ redo_state.has_kerning = true;+ } else {+ redo_state.has_kerning = false;+ }+ classes.set_kerning (glyph_range_first, glyph_range_next, ui.kerning); } else {+ + redo_state.first = ui.first;+ redo_state.next = ui.next;+ redo_state.has_kerning = true;+ k = classes.get_kerning_for_single_glyphs (ui.first, ui.next);+ + if (k != null) {+ redo_state.kerning = (!) k;+ redo_state.has_kerning = true;+ } else {+ redo_state.has_kerning = false;+ }+ classes.set_kerning_for_single_glyphs (ui.first, ui.next, ui.kerning); }- - undo_items.remove_at (undo_items.size - 1); } catch (MarkupError e) { warning (e.message); } font.touch (); GlyphCanvas.redraw ();+ + return redo_state; } - class UndoItem : GLib.Object {+ public class UndoItem : GLib.Object { public string first; public string next; public double kerning;@@ -41,8 +41,9 @@ public class OverView : FontDisplay { Gee.ArrayList<OverViewItem> visible_items = new Gee.ArrayList<OverViewItem> (); - /** List for undo commands. */+ /** List of undo commands. */ Gee.ArrayList<OverViewUndoItem> undo_items = new Gee.ArrayList<OverViewUndoItem> ();+ Gee.ArrayList<OverViewUndoItem> redo_items = new Gee.ArrayList<OverViewUndoItem> (); /** Show all characters that has been drawn. */ bool all_available = true;@@ -702,11 +703,16 @@ public class OverView : FontDisplay { } previous_collection = undo_items.get (undo_items.size - 1);++ redo_items.add (get_current_state (previous_collection)); // remove the old glyph and add the new one foreach (GlyphCollection g in previous_collection.glyphs) { font.delete_glyph (g);- font.add_glyph_collection (g);+ + if (g.length () > 0) {+ font.add_glyph_collection (g);+ } } undo_items.remove_at (undo_items.size - 1);@@ -714,6 +720,47 @@ public class OverView : FontDisplay { redraw_area (0, 0, allocation.width, allocation.height); } + public override void redo () {+ Font font = BirdFont.get_current_font ();+ OverViewUndoItem previous_collection;++ if (redo_items.size == 0) {+ return;+ }+ + previous_collection = redo_items.get (redo_items.size - 1);+ + undo_items.add (get_current_state (previous_collection));++ // remove the old glyph and add the new one+ foreach (GlyphCollection g in previous_collection.glyphs) {+ font.delete_glyph (g);+ font.add_glyph_collection (g);+ }+ + redo_items.remove_at (redo_items.size - 1);+ + redraw_area (0, 0, allocation.width, allocation.height);+ } + + public OverViewUndoItem get_current_state (OverViewUndoItem previous_collection) {+ GlyphCollection? gc;+ OverViewUndoItem ui = new OverViewUndoItem ();+ Font font = BirdFont.get_current_font ();+ + foreach (GlyphCollection g in previous_collection.glyphs) {+ gc = font.get_glyph_collection (g.get_name ());+ + if (gc != null) {+ ui.glyphs.add (((!) gc).copy ());+ } else {+ ui.glyphs.add (new GlyphCollection (g.get_unicode_character (), g.get_name ()));+ }+ }+ + return ui; + }+ public void store_undo_state (GlyphCollection gc) { OverViewUndoItem i = new OverViewUndoItem (); i.glyphs.add (gc);@@ -722,6 +769,7 @@ public class OverView : FontDisplay { public void store_undo_items (OverViewUndoItem i) { undo_items.add (i);+ redo_items.clear (); } bool select_visible_character (unichar c) {@@ -175,7 +175,15 @@ public class TabContent : GLib.Object { GlyphCanvas.current_display.undo (); }- ++ public static void redo () {+ if (MenuTab.suppress_event) {+ return;+ }+ + GlyphCanvas.current_display.redo ();+ }+ public static string path_to_uri (string path) { string uri = path; string wp;