Clone in a terminal:
Commit 098a15a
Johan Mattsson - 2014-09-01T15:13:29+00:00
098a15a843d19635574b22044ad7791ef3fb50e8johan.mattsson.m@gmail.com

Copy and paste glyphs in overview tab

Changed files (5)

Diff

diff --git a/libbirdfont/ClipTool.vala b/libbirdfont/ClipTool.valaindex e3447f5..bcf5a73 100644--- a/libbirdfont/ClipTool.vala+++ b/libbirdfont/ClipTool.vala@@ -28,7 +28,25 @@ public class ClipTool : Tool { 			data = svg_data + bf_data; 			MainWindow.native_window.set_clipboard (data); 			MainWindow.native_window.set_inkscape_clipboard (data);-		}		+		}+		+		if (fd is OverView) {+			MainWindow.get_overview ().copy ();+		}			+	}++	/** Copy entire glyph. */+	public static void copy_glyph (Glyph glyph) {+		string svg_data;+		string bf_data;+		string data;+			+		svg_data = ExportTool.export_to_inkscape_clipboard (glyph, false);+		bf_data = export_paths_to_birdfont_clipboard (glyph, false);+		+		data = svg_data + bf_data;+		MainWindow.native_window.set_clipboard (data);+		MainWindow.native_window.set_inkscape_clipboard (data);	 	}  	public static void paste_in_place () {@@ -58,6 +76,10 @@ public class ClipTool : Tool { 		if (fd is KerningDisplay) { 			paste_letters_to_kerning_tab (); 		}+		+		if (fd is OverView) {+			MainWindow.get_overview ().paste ();+		}	 	} 	 	static void paste_paths (bool paste_guide_lines) {@@ -95,11 +117,14 @@ public class ClipTool : Tool { 			SvgParser.import_svg_data (data); 		} 		-		((!)destination).update_view ();			+		((!)destination).update_view ();	 	}  	static string export_selected_paths_to_birdfont_clipboard () {-		Glyph glyph = MainWindow.get_current_glyph ();+		return export_paths_to_birdfont_clipboard (MainWindow.get_current_glyph (), true);+	}+	+	static string export_paths_to_birdfont_clipboard (Glyph glyph, bool selected = false) { 		StringBuilder s = new StringBuilder (); 		Path new_path; 		List<Path> paths = new List<Path> ();@@ -115,7 +140,13 @@ public class ClipTool : Tool { 		s.append (@"$(glyph.right_limit)"); 		s.append ("\n"); 								-		if (glyph.path_list.size > 0) {+		if (!selected) {+			foreach (Path path in glyph.path_list) {+				s.append ("BF path: ");+				s.append (BirdFontFile.get_point_data (path));+				s.append ("\n");+			}+		} else if (glyph.path_list.size > 0) { 			foreach (Path path in glyph.active_paths) { 				s.append ("BF path: "); 				s.append (BirdFontFile.get_point_data (path));diff --git a/libbirdfont/ExportTool.vala b/libbirdfont/ExportTool.valaindex 54c5433..ef1fe0a 100644--- a/libbirdfont/ExportTool.vala+++ b/libbirdfont/ExportTool.vala@@ -28,7 +28,10 @@ public class ExportTool : GLib.Object { 	}  	public static string export_current_glyph_to_string (bool only_selected_paths = false) {-		Glyph glyph = MainWindow.get_current_glyph ();+		return export_to_string (MainWindow.get_current_glyph (), only_selected_paths);+	}++	public static string export_to_string (Glyph glyph, bool only_selected_paths) { 		string name; 		StringBuilder s; @@ -49,7 +52,7 @@ public class ExportTool : GLib.Object { 		 		s.append (@"<g id=\"$(name)\">\n"); -		s.append (get_svg_path_elements (only_selected_paths));+		s.append (get_svg_path_elements (glyph, only_selected_paths)); 	 		s.append ("</g>\n"); 		s.append ("</svg>");@@ -58,6 +61,10 @@ public class ExportTool : GLib.Object { 	} 	 	public static string export_current_glyph_to_inkscape_clipboard (bool only_selected_paths = false) {+		return export_to_inkscape_clipboard (MainWindow.get_current_glyph (), only_selected_paths);+	}+	+	public static string export_to_inkscape_clipboard (Glyph glyph, bool only_selected_paths = false) { 		StringBuilder s; 		 		s = new StringBuilder ();@@ -72,14 +79,13 @@ public class ExportTool : GLib.Object { 			max="0,0" />      """); -		s.append (get_svg_path_elements (only_selected_paths));+		s.append (get_svg_path_elements (glyph, only_selected_paths)); 		s.append ("</svg>"); 		 		return s.str; 	} -	private static string get_svg_path_elements (bool only_selected_paths) {-		Glyph glyph = MainWindow.get_current_glyph ();+	private static string get_svg_path_elements (Glyph glyph, bool only_selected_paths) { 		string glyph_svg; 		StringBuilder s; 		string name;diff --git a/libbirdfont/GlyphCollection.vala b/libbirdfont/GlyphCollection.valaindex 062cb63..0d7a549 100644--- a/libbirdfont/GlyphCollection.vala+++ b/libbirdfont/GlyphCollection.vala@@ -51,6 +51,10 @@ public class GlyphCollection : GLib.Object { 		return unicode.str; 	} +	public void set_unicode_character (unichar c) {+		unicode_character = c;+	}+ 	public unichar get_unicode_character () { 		return unicode_character; 	}diff --git a/libbirdfont/OverView.vala b/libbirdfont/OverView.valaindex b862f45..2d2d799 100644--- a/libbirdfont/OverView.vala+++ b/libbirdfont/OverView.vala@@ -1,5 +1,5 @@ /*-    Copyright (C) 2012 Johan Mattsson+    Copyright (C) 2012 2014 Johan Mattsson      This library is free software; you can redistribute it and/or modify      it under the terms of the GNU Lesser General Public License as @@ -21,6 +21,10 @@ public class OverView : FontDisplay { 	public WidgetAllocation allocation = new WidgetAllocation (); 	 	OverViewItem selected_item = new OverViewItem (null, '\0', 0, 0);++	Gee.ArrayList<GlyphCollection> copied_glyphs = new Gee.ArrayList<GlyphCollection> ();+	Gee.ArrayList<GlyphCollection> selected_items = new Gee.ArrayList<GlyphCollection> ();	+	 	int selected = 0; 	int first_visible = 0; 	int rows = 0;@@ -38,7 +42,7 @@ public class OverView : FontDisplay { 	Gee.ArrayList<OverViewItem> visible_items = new Gee.ArrayList<OverViewItem> (); 	 	/** List for undo commands. */-	Gee.ArrayList<GlyphCollection> deleted_glyphs = new Gee.ArrayList<GlyphCollection> ();+	Gee.ArrayList<OverViewUndoItem> undo_items = new Gee.ArrayList<OverViewUndoItem> (); 	 	/** Show all characters that has been drawn. */ 	bool all_available = true;@@ -87,24 +91,13 @@ public class OverView : FontDisplay { 			selected = tabs.select_char (name.str); 					 			if (!selected) {-				if (all_available) {-					fg = font.get_glyph_collection_by_name (name.str);-				} else {-					fg = font.get_glyph_collection (name.str);-				}--				if (fg != null) {-					glyph_collection = (!) fg;-					glyph = glyph_collection.get_current ();-				} else {-					glyph_collection = new GlyphCollection (character, name.str);-					glyph = new Glyph (name.str, character);-					glyph_collection.insert_glyph (glyph, true);-					font.add_glyph_collection (glyph_collection);-				}+				glyph_collection = add_character_to_font (character); 				+				glyph = glyph_collection.get_current (); 				tabs.add_tab (glyph); 				+				selected_items.add (glyph_collection);+				 				canvas = MainWindow.get_glyph_canvas (); 				canvas.set_current_glyph (glyph_collection.get_current ()); 				@@ -115,6 +108,43 @@ public class OverView : FontDisplay { 		update_scrollbar (); 	} 	+	public GlyphCollection add_empty_character_to_font (unichar character) {+		return add_character_to_font (character, true);+	}+	+	public GlyphCollection add_character_to_font (unichar character, bool empty = false) {+		StringBuilder name = new StringBuilder ();+		TabBar tabs = MainWindow.get_tab_bar ();+		Font font = BirdFont.get_current_font ();+		GlyphCollection? fg;+		Glyph glyph;+		GlyphCollection glyph_collection;+		GlyphCanvas canvas;+			+		name.append_unichar (character);++		if (all_available) {+			fg = font.get_glyph_collection_by_name (name.str);+		} else {+			fg = font.get_glyph_collection (name.str);+		}++		if (fg != null) {+			glyph_collection = (!) fg;+		} else {+			glyph_collection = new GlyphCollection (character, name.str);+			+			if (!empty) {+				glyph = new Glyph (name.str, character);+				glyph_collection.insert_glyph (glyph, true);+			}+			+			font.add_glyph_collection (glyph_collection);+		}+		+		return glyph_collection;+	}+	 	public static void search () { 		OverView ow = MainWindow.get_overview (); 		TextListener listener = new TextListener (t_("Search"), ow.search_query, t_("Filter"));@@ -284,7 +314,7 @@ public class OverView : FontDisplay { 		return i - 1; 	} 		-	void update_item_list () {+	void update_item_list (int item_list_length = -1) { 		string character_string; 		Font f = BirdFont.get_current_font (); 		GlyphCollection? glyphs = null;@@ -298,15 +328,18 @@ public class OverView : FontDisplay { 		items_per_row = get_items_per_row (); 		rows = (int) (allocation.height /  OverViewItem.full_height ()) + 2; 		-		visible_items.clear ();+		if (item_list_length == -1) {+			item_list_length = items_per_row * rows;+		} 		+		visible_items.clear (); 		visible_items = new Gee.ArrayList<OverViewItem> (); 		 		// update item list 		index = (uint32) first_visible; 		x = OverViewItem.margin; 		y = OverViewItem.margin;-		for (int i = 0; i < items_per_row * rows; i++) {+		for (int i = 0; i < item_list_length; i++) { 			if (all_available) { 				if (! (0 <= index < f.length ())) { 					break;@@ -338,6 +371,10 @@ public class OverView : FontDisplay { 			 			item.selected = (i == selected); 			+			if (glyphs != null) {+				item.selected |= selected_items.index_of ((!) glyphs) != -1;+			}+			 			visible_items.add (item); 			index++; 		}@@ -658,27 +695,35 @@ public class OverView : FontDisplay { 	 	public override void undo () { 		Font font = BirdFont.get_current_font ();-		GlyphCollection previous_collection;+		OverViewUndoItem previous_collection; 		-		if (deleted_glyphs.size == 0) {+		if (undo_items.size == 0) { 			return; 		} 		-		previous_collection = deleted_glyphs.get (deleted_glyphs.size - 1);+		previous_collection = undo_items.get (undo_items.size - 1); 		 		// remove the old glyph and add the new one-		font.delete_glyph (previous_collection);-		font.add_glyph_collection (previous_collection);+		foreach (GlyphCollection g in previous_collection.glyphs) {+			font.delete_glyph (g);+			font.add_glyph_collection (g);+		} 		-		deleted_glyphs.remove_at (deleted_glyphs.size - 1);+		undo_items.remove_at (undo_items.size - 1); 		 		redraw_area (0, 0, allocation.width, allocation.height); 	} 	 	public void store_undo_state (GlyphCollection gc) {-		deleted_glyphs.add (gc);+		OverViewUndoItem i = new OverViewUndoItem ();+		i.glyphs.add (gc);+		store_undo_items (i); 	} +	public void store_undo_items (OverViewUndoItem i) {+		undo_items.add (i);+	}+	 	bool select_visible_character (unichar c) { 		int i = 0; 		@@ -787,8 +832,31 @@ public class OverView : FontDisplay { 		character_info = i; 	} +	public int get_selected_index () {+		GlyphCollection gc;+		int index = 0;+		+		if (selected_items.size == 0) {+			return 0;+		}+		+		gc = selected_items.get (0);+		+		foreach (OverViewItem i in visible_items) {+			+			if (i.glyphs != null && gc == ((!) i.glyphs)) {+				break;+			}+			+			index++;+		}+		+		return index;+	}+ 	public override void button_press (uint button, double x, double y) { 		int index = 0;+		int selected_index = -1; 		 		if (character_info != null) { 			character_info = null;@@ -800,11 +868,31 @@ public class OverView : FontDisplay { 			if (i.click (button, x, y)) { 				selected = index; 				selected_item = get_selected_item ();+				+				if (KeyBindings.has_shift ()) {+					if (selected_item.glyphs != null) {+						+						selected_index = selected_items.index_of ((!) selected_item.glyphs);+						if (selected_index == -1) {+							selected_items.add ((!) selected_item.glyphs);+						} else {+							return_if_fail (0 <= selected_index < selected_items.size);+							selected_items.remove_at (selected_index);+							selected = get_selected_index ();+							selected_item = get_selected_item ();+						}+					}+				} else {+					selected_items.clear ();+					if (selected_item.glyphs != null) {+						selected_items.add ((!) selected_item.glyphs);+					}+				} 			}-			 			index++; 		} 	+		update_item_list (); 		redraw_area (0, 0, allocation.width, allocation.height); 	} @@ -975,6 +1063,100 @@ public class OverView : FontDisplay { 		cr.show_text (line); 		cr.restore ();		 	}+	+	public void copy () {+		copied_glyphs.clear ();+		+		foreach (GlyphCollection gc in selected_items) {+			copied_glyphs.add (gc.copy ());+		}+		+		if (copied_glyphs.size != 0) {+			ClipTool.copy_glyph (selected_items.get (copied_glyphs.size - 1).get_current ());+		}+	}+	+	public void paste () {+		GlyphCollection gc = new GlyphCollection ('\0', "");+		GlyphCollection? c;+		Glyph glyph;+		uint32 index;+		int i;+		int skip = 0;+		string character_string;+		Gee.ArrayList<GlyphCollection> glyps = new Gee.ArrayList<GlyphCollection> ();+		Font f = BirdFont.get_current_font ();+		OverViewUndoItem undo_item;+		+		copied_glyphs.sort ((a, b) => {+			return (int) ((GlyphCollection) a).get_unicode_character () +				- (int) ((GlyphCollection) b).get_unicode_character ();+		});+		+		// FIXME: copy and paste to unicode character + 1 +		+		index = (uint32) first_visible + selected;+		for (i = 0; i < copied_glyphs.size; i++) {+			if (all_available) {+				if (f.length () == 0) {+					c = add_empty_character_to_font (+						glyps.get (i).get_unicode_character ());					+				} else if (index >= f.length ()) {+					c = add_empty_character_to_font (+						((!)f.get_glyph_collection_indice (f.length () - 1)).get_unicode_character () + i);+				} else {+					c = f.get_glyph_collection_indice ((uint32) index);+				}+				+				if (c == null) {+					c = add_empty_character_to_font (copied_glyphs.get (i).get_unicode_character ());+				}+				+				return_if_fail (c != null);+				gc = (!) c; +			} else {				+				if (i != 0) {+					skip = (int) copied_glyphs.get (i).get_unicode_character ();+					skip -= (int) copied_glyphs.get (i - 1).get_unicode_character ();+					skip -= 1;+				}+				+				character_string = glyph_range.get_char ((uint32) (index + skip));+				c = f.get_glyph_collection_by_name (character_string);+				+				if (c == null) {+					gc = add_empty_character_to_font (character_string.get_char ());+				} else {+					gc = (!) c;+				}+			}+			+			glyps.add (gc);+			index++;+		}++		undo_item = new OverViewUndoItem ();+		foreach (GlyphCollection g in glyps) {+			undo_item.glyphs.add (g.copy ());+		}+		store_undo_items (undo_item);+		+		i = 0;+		foreach (GlyphCollection g in glyps) {+			glyph = copied_glyphs.get (i).get_current ().copy ();+			glyph.version_id = (glyph.version_id == -1 || g.length () == 0) ? 1 : g.get_last_id () + 1;+			glyph.unichar_code =  g.get_unicode_character ();+			glyph.name = (!) glyph.unichar_code.to_string ();+			g.insert_glyph (glyph, true);+			i++;+		}+		+		f.touch ();+	}+	+	public class OverViewUndoItem {+		public Gee.ArrayList<GlyphCollection> glyphs = new Gee.ArrayList<GlyphCollection> ();+	} }  }diff --git a/libbirdfont/OverViewItem.vala b/libbirdfont/OverViewItem.valaindex afa1f01..2a52e35 100644--- a/libbirdfont/OverViewItem.vala+++ b/libbirdfont/OverViewItem.vala@@ -18,7 +18,7 @@ using Math; namespace BirdFont { 	 public class OverViewItem : GLib.Object {-	public unichar character = 'A'; // FIXME: +	public unichar character = 'A'; 	public GlyphCollection? glyphs; 	public double x; 	public double y;@@ -41,6 +41,10 @@ public class OverViewItem : GLib.Object { 		this.info = new CharacterInfo (character); 	} 	+	public void set_selected (bool s) {+		selected = s;+	}+	 	public static double full_width () { 		return width + margin; 	}@@ -52,13 +56,13 @@ public class OverViewItem : GLib.Object { 	public bool click (uint button, double px, double py) { 		bool a; 		GlyphCollection g;-		selected = (x <= px <= x + width) && (y <= py <= y + height);+		bool s = (x <= px <= x + width) && (y <= py <= y + height); 		 		if (has_icons () && glyphs != null) { 			g = (!) glyphs; 			a = g.get_version_list ().menu_item_action (px, py); // select one item on the menu 			if (a) {-				return selected;+				return s; 			} 			 			g.get_version_list ().menu_icon_action (px, py); // click in the open menu@@ -68,7 +72,7 @@ public class OverViewItem : GLib.Object { 			MainWindow.get_overview ().set_character_info (info); 		} 				-		return selected;+		return s; 	}  	public void double_click (uint button, double px, double py) {

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112