Clone in a terminal:
Commit d1cae04
Johan Mattsson - 2012-08-19T00:15:20+00:00
d1cae0405b7e74d4016b27c21b794c44ecb0cf98johan.mattsson.m@gmail.com

select multiple paths

Changed files (8)

Diff

diff --git a/icons/new_point.png b/icons/new_point.pngindex 5ddfcc3..eb66ce6 100644Binary files a/icons/new_point.png and b/icons/new_point.png differdiff --git a/src/ClipTool.vala b/src/ClipTool.valaindex 06c063e..fc5f6e6 100644--- a/src/ClipTool.vala+++ b/src/ClipTool.vala@@ -39,7 +39,7 @@ class ClipTool : Tool {  		if (fd is Glyph) { 			glyph = null;-			path = MainWindow.get_current_glyph ().active_path;+			path = MainWindow.get_current_glyph ().get_active_path (); 			 			if (path == null) { 				glyph = MainWindow.get_current_glyph ();diff --git a/src/CutTool.vala b/src/CutTool.valaindex 26b2432..b965887 100644--- a/src/CutTool.vala+++ b/src/CutTool.vala@@ -43,24 +43,18 @@ class CutTool : Tool {  	public static void force_direction () { 		Glyph g = MainWindow.get_current_glyph ();-		Path p; 		Tool current_tool = MainWindow.get_toolbox ().get_current_tool (); 		-		if (g.active_path == null) {-			return;-		}-		-		p = (!) g.active_path;-			-		if (p.is_editable () && p.is_open ()) {-			-			if (current_tool is PenTool) {-				p.force_direction (Direction.CLOCKWISE);-			} else if (current_tool is CutTool) {-				p.force_direction (Direction.COUNTER_CLOCKWISE);+		foreach (Path p in g.active_paths) {+			if (p.is_editable () && p.is_open ()) {+				+				if (current_tool is PenTool) {+					p.force_direction (Direction.CLOCKWISE);+				} else if (current_tool is CutTool) {+					p.force_direction (Direction.COUNTER_CLOCKWISE);+				}				 			}-			-		}	+		} 	} 	 }diff --git a/src/Glyph.vala b/src/Glyph.valaindex 69d9620..6b4eab7 100644--- a/src/Glyph.vala+++ b/src/Glyph.vala@@ -39,8 +39,8 @@ class Glyph : FontDisplay { 	 	// Paths 	public List<Path> path_list;	// outline // FIXME: private-	public Path? active_path = null;-	Path? union_path = null; 		// add this to active path+	public List<Path> active_paths = new List<Path> ();+	 	bool move_edit_point = false; 	double last_move_offset_x = 0; 	double last_move_offset_y = 0;@@ -117,6 +117,30 @@ class Glyph : FontDisplay { 		path_list.append (new Path ()); 	} 	+	public void clear_active_paths () {+		while (active_paths.length () > 0) {+			active_paths.remove_link (active_paths.first ());+		}+	}+	+	public void add_active_path (Path? p) {+		if (p != null) {+			+			foreach (Path pi in active_paths) {+				if (pi == p) {+					return;+				}+			}+			+			active_paths.append ((!) p);+		}+	}+	+	public Path? get_active_path () {+		return active_paths.last ().data;+	}+	+	 	public void add_kerning (string right_glyph, double val) { 		Kerning? kl = null; @@ -471,11 +495,14 @@ class Glyph : FontDisplay {  	public override void key_press (EventKey e) {	 		if (e.keyval == Key.DEL) {-			if (active_path != null) {-				Path p = (!) active_path;-				close_path ();-				path_list.remove (p);-				redraw_area (0, 0, allocation.width, allocation.height);+			if (active_paths.length () != 0) {+				foreach (Path p in active_paths) {+					close_path ();+					path_list.remove (p);+					redraw_area (0, 0, allocation.width, allocation.height);	+				}+				+				clear_active_paths (); 			} 			 			if (selected_point != null) {@@ -587,7 +614,10 @@ class Glyph : FontDisplay { 	public EditPoint add_new_edit_point (int x, int y) { 		insert_edit_point (x, y); 		move_edit_point = true;-		last_added_edit_point = ((!) active_path).get_last_point ();+		+		return_if_fail (active_paths.length () > 0);+		+		last_added_edit_point = active_paths.last ().data.get_last_point (); 		return (!) last_added_edit_point; 	} @@ -716,48 +746,35 @@ class Glyph : FontDisplay { 		ry = Glyph.reverse_path_coordinate_y (y);		 	}	 -	public void move_selected_path (double x, double y) {	-		if (active_path == null) {-			return;+	public bool select_path (double x, double y) {+		Path? p = null;+		bool found = false;+		+		foreach (Path pt in path_list) {+			if (pt.is_over (x, y)) {+				p = pt;+				found = true;+			} 		}-				-		move_selected_path_freely (path_coordinate_x (x), path_coordinate_y (y));-	}-	-	public void move_selected_path_freely (double coordinate_x, double coordinate_y) -		requires (active_path != null)-	{-		double dx = coordinate_x - path_coordinate_x (pointer_begin_x);-		double dy = coordinate_y - path_coordinate_y (pointer_begin_y);--		Path path = (!) active_path;--		path.move (dx - last_move_offset_x, dy - last_move_offset_y); 		-		last_move_offset_x = dx;-		last_move_offset_y = dy;+		if (!KeyBindings.has_shift ()) {+			clear_active_paths ();+		}+		+		add_active_path (p); 		-		queue_redraw_path (path);+		return found; 	} 	-	public void move_path_begin (double x, double y) {-		Supplement.get_current_font ().touch ();-		Path? p = null;-				-		foreach (var pt in path_list) {+	public bool is_over_selected_path (double x, double y) {+		foreach (Path pt in active_paths) { 			if (pt.is_over (x, y)) {-				p = pt;+				return true; 			} 		}-		-		active_path = p;-		-		last_move_offset_x = 0;-		last_move_offset_y = 0;--		move_selected_path (x, y);+		return false;		 	}-			+		 	public void queue_redraw_path (Path path) { 		redraw_path (path.xmin, path.ymin, path.xmax, path.ymax); 	}@@ -815,38 +832,39 @@ class Glyph : FontDisplay { 		return min_point; 	} 	-	public Path? get_active_path () {-		return active_path;-	}-	 	private void insert_edit_point (double x, double y) { 		unowned List<Path> paths; 		double xt, yt; 		bool added; 		Path np; 		-		if (active_path == null) {+		if (active_paths.length () == 0) {+			print ("ADD empty\n"); 			np = new Path ();-			active_path = np;+			clear_active_paths ();+			active_paths.append (np); 			path_list.append (np); 		} 		 		paths = path_list; 		-		xt = path_coordinate_x (x);-		yt = path_coordinate_y (y);-		+		xt = x - xc () - view_offset_x;+		yt = -y + yc () + view_offset_y;++		xt *= view_zoom;+		yt *= view_zoom;		+			 		added = false;  		if (new_point_on_path != null) {-			return_if_fail (active_path != null);+			print ("ADD np\n");+			return_if_fail (active_paths.length () > 0);  			Path p = new Path (); 			EditPoint e = (!) new_point_on_path;  			return_if_fail (e.prev != null); 			-			union_path = p; 			p.add_point (e); 			e.type = PointType.CURVE; 			@@ -854,27 +872,20 @@ class Glyph : FontDisplay { 			e.left_handle.type = PointType.CURVE; 			 			paths.append (p);-			active_path = p;+			add_active_path (p); 			flipping_point_on_path = new_point_on_path; 			new_point_on_path = null; 			added = true; 			return; 		} 		-		if (!added && union_path != null) {-			Path p = (!) union_path;-			if (p.is_open ()) {-				p.add (xt, yt);-				active_path = p;-				added = true;-			}-		}-		 		if (!added) {+			print ("ADD a\n"); 			foreach (Path p in paths) { 				if (p.is_open ()) { 					p.add (xt, yt);-					active_path = p;+					clear_active_paths ();+					add_active_path (p); 					added = true; 					break; 				}@@ -882,10 +893,11 @@ class Glyph : FontDisplay { 		}  		if (!added) {+			print ("ADD X\n"); 			foreach (Path p in paths) { 				if (p.is_over (xt, yt)) { 					p.add (xt, yt);-					active_path = p;+					paths.append (p); 					added = true; 					queue_draw_area (0, 0, allocation.width, allocation.height); 					break;@@ -894,6 +906,7 @@ class Glyph : FontDisplay { 		} 		 		if (!added) {+			print ("ADD NEW\n"); 			if (paths.length () > 0 && paths.last ().data.is_open ()) { 				paths.last().data.add (xt, yt); 			}@@ -906,13 +919,15 @@ class Glyph : FontDisplay { 			paths.append (np); 			np.add (xt, yt); 			-			active_path = np;+			clear_active_paths ();+			add_active_path (np); 		} 	-		return_if_fail (active_path != null);-	-		selected_point = ((!) active_path).get_last_point ();-	+		assert (active_paths.length () > 0);+		+		selected_point = active_paths.last ().data.get_last_point ();+		assert (selected_point != null);+		 		move_selected_edit_point (x, y); 	} 	@@ -965,37 +980,39 @@ class Glyph : FontDisplay { 	 	private void redraw_last_stroke (double x, double y) { 		// redraw line, if we have more than one new point on path-		double px;-		double py;-		int tw;-		int th;+		double px = 0;+		double py = 0;+		int tw = 0;+		int th = 0;  		double xc = (allocation.width / 2.0); -		if (active_path == null) {+		if (active_paths.length () == 0) { 			return; 		} 		-		EditPoint? pt = ((!) active_path).get_second_last_point ();-		if (pt != null) {-			EditPoint p = (!) pt;-			-			px = p.x + xc;-			py = p.y - xc;-							-			tw = (px > x) ? (int) (px - x) : (int) (x - px);-			th = (py > y) ? (int) (py - y) : (int) (y - py);-			-			if (px > x) px -= tw + 60;-			if (py > y) py -= th + 60;-			-		} else {-			px = x - 60;-			py = y - 60;-			tw = 0;-			th = 0;+		foreach (Path path in active_paths) {+			EditPoint? pt = path.get_second_last_point ();+			if (pt != null) {+				EditPoint p = (!) pt;+				+				px = p.x + xc;+				py = p.y - xc;+								+				tw = (px > x) ? (int) (px - x) : (int) (x - px);+				th = (py > y) ? (int) (py - y) : (int) (y - py);+				+				if (px > x) px -= tw + 60;+				if (py > y) py -= th + 60;+				+			} else {+				px = x - 60;+				py = y - 60;+				tw = 0;+				th = 0;+			} 		}-+		 		queue_draw_area ((int)px - 20, (int)py - 20, tw + 120, th + 120); 		 	} 	@@ -1007,7 +1024,7 @@ class Glyph : FontDisplay { 	} 	 	public bool has_active_path () {-		return (active_path != null);+		return active_paths.length () > 0; 	} 	 	public bool is_editable () {@@ -1030,8 +1047,7 @@ class Glyph : FontDisplay { 		 		editable = false; 		-		active_path = null;-		union_path = null; +		clear_active_paths (); 		new_point_on_path = null; 		flipping_point_on_path = null; 		selected_point = null;@@ -1567,7 +1583,9 @@ class Glyph : FontDisplay { 			g.add_path (p.copy ()); 		} 		-		g.active_path = active_path;+		foreach (Path p in active_paths) {+			g.active_paths.append (p);+		} 		 		return g; 	}@@ -1595,8 +1613,11 @@ class Glyph : FontDisplay { 		}  		add_help_lines ();-				-		active_path = g.active_path;+		+		clear_active_paths ();+		foreach (Path p in g.active_paths) {+			add_path (p);+		} 		 		undo_list.remove_link (undo_list.last ()); 	}diff --git a/src/MoveTool.vala b/src/MoveTool.valaindex 1badbd2..aadd448 100644--- a/src/MoveTool.vala+++ b/src/MoveTool.vala@@ -21,6 +21,9 @@ class MoveTool : Tool {  	bool move_path = false; +	double last_x = 0;+	double last_y = 0;+	 	public MoveTool (string n) { 		base (n, "Move paths", 'm', CTRL); 	@@ -30,6 +33,8 @@ class MoveTool : Tool { 		deselect_action.connect((self) => { 			Glyph glyph = MainWindow.get_current_glyph (); +			glyph.clear_active_paths ();+ 			foreach (Path p in glyph.path_list) { 				p.set_color (0, 0, 0, 1); 				p.set_selected (false);@@ -38,14 +43,13 @@ class MoveTool : Tool { 				 		press_action.connect((self, b, x, y) => { 			Glyph glyph = MainWindow.get_current_glyph ();-			Path path; 			 			glyph.store_undo_state (); 			-			glyph.move_path_begin (x, y);-			-			if (glyph.active_path == null) {-				return;+			if (!glyph.is_over_selected_path (x, y)) {+				if (!glyph.select_path (x, y)) {+					glyph.clear_active_paths ();+				} 			} 			 			move_path = true;@@ -55,36 +59,48 @@ class MoveTool : Tool { 				p.set_selected (false); 			} 			-			return_if_fail (glyph.active_path != null);-			-			path = (!) glyph.active_path;+			return_if_fail (glyph.active_paths.length () != 0); 			-			if (path.is_clockwise ()) {-				path.set_color (0.2, 0.2, 0.4, 0.8);-				path.set_selected (true);-			} else {-				path.set_color (0.5, 0.5, 0.7, 0.8);-				path.set_selected (true);+			foreach (Path path in glyph.active_paths) {+				if (path.is_clockwise ()) {+					path.set_color (0.2, 0.2, 0.4, 0.8);+					path.set_selected (true);+				} else {+					path.set_color (0.5, 0.5, 0.7, 0.8);+					path.set_selected (true);+				} 			}-			+					+			last_x = x;+			last_y = y; 		});  		release_action.connect((self, b, x, y) => { 			Glyph glyph = MainWindow.get_current_glyph (); 			move_path = false;-			-					-			if (GridTool.is_visible () && glyph.active_path != null) {-				tie_path_to_grid ((!) glyph.active_path, x, y);+				+			if (GridTool.is_visible ()) {+				foreach (Path p in glyph.active_paths) {+					tie_path_to_grid (p, x, y);+				} 			}-			 		}); 		 		move_action.connect ((self, x, y)	 => { 			if (move_path) { 				Glyph glyph = MainWindow.get_current_glyph ();-				glyph.move_selected_path (x, y);++				double dx = last_x - x;+				double dy = last_y - y; ++				foreach (Path path in glyph.active_paths) {+					path.move (glyph.ivz () * -dx, glyph.ivz () * dy);+				}+				 				MainWindow.get_glyph_canvas ().redraw ();+				+				last_x = x;+				last_y = y; 			} 		}); 	}diff --git a/src/Path.vala b/src/Path.valaindex b9f98f1..2873885 100644--- a/src/Path.vala+++ b/src/Path.vala@@ -1538,7 +1538,7 @@ class Path { 			if (pl != null) { 				points.delete_link ((!) pl); 				reopen ();-				MainWindow.get_current_glyph ().active_path = this;+				MainWindow.get_current_glyph ().add_active_path (this); 				create_list (); 			} 	}@@ -1582,11 +1582,11 @@ class Path { 		IntersectionList il = IntersectionList.create_intersection_list (this, p); 		Path np = new Path (); 		Intersection s = new Intersection (0, 0, 1);-		EditPoint ex = points.last ().data;-		EditPoint ix = points.last ().data;+		EditPoint ex;+		EditPoint ix; 		uint offset_i = 0; 		uint offset_j;-		uint len_i = points.length ();+		uint len_i; 		int i, j; 		uint len_j; 		@@ -1613,8 +1613,12 @@ class Path { 		} 		 		// create a new path +		ex = points.last ().data;+		ix = points.last ().data;+		len_i = points.length ();+		 		for (i = 0; i < points.length (); i++) {-			ex = points.nth (i).data;+			ex = points.nth ((i + offset_i) % len_i).data;  			if (ex == points.first ().data && i != 0) { 				break;@@ -1687,7 +1691,6 @@ class Path { 				offset_i = 0; 				i = k; 			}-			 		} 		 		return np;diff --git a/src/PenTool.vala b/src/PenTool.valaindex c1c21dc..10f7aeb 100644--- a/src/PenTool.vala+++ b/src/PenTool.vala@@ -218,12 +218,10 @@ class PenTool : Tool { 	} 	 	public void select_active_point (double x, double y) {-		Path cp; 		Glyph? g = MainWindow.get_current_glyph (); 		Glyph glyph = (!) g; 		-		if (glyph.has_active_path ()) {-			cp = (!) glyph.active_path;+		foreach (Path cp in glyph.active_paths) { 			foreach (var e in cp.points) { 				e.set_active (false); 			}@@ -256,11 +254,11 @@ class PenTool : Tool { 				GridTool.tie (ref x, ref y); 			} 			-			return_if_fail (g.active_path != null);+			return_if_fail (g.active_paths.length () > 0); 			return_if_fail (g.new_point_on_path != null); 			 			EditPoint ep = (!) g.new_point_on_path;-			Path p = (!) g.active_path;+			Path p = (!) g.get_active_path (); 			 			double rax, ray; 			double pax, pay;@@ -283,7 +281,8 @@ class PenTool : Tool { 		 		return_if_fail (ap.is_editable ()); 		-		g.active_path = ap;+		g.clear_active_paths ();+		g.add_active_path (ap);  		if (g.new_point_on_path == null) { 			g.new_point_on_path = new EditPoint (0, 0, PointType.FLOATING);@@ -329,7 +328,7 @@ class PenTool : Tool { 				if (d < m && d * g.view_zoom < 14 && !is_over_handle (x, y)) { 					m = d; 					set_active_edit_point (e);-					active_path = current_path;+					g.add_active_path (active_path); 				} 			} @@ -381,7 +380,9 @@ class PenTool : Tool { 	void set_linear_handles_for_last_point () { 		Glyph glyph; 		glyph = MainWindow.get_current_glyph ();-		((!)glyph.active_path).points.last ().data.right_handle.parent.recalculate_linear_handles ();+		return_if_fail (glyph.active_paths.length () > 0);+		return_if_fail (glyph.active_paths.last ().data.points.length () > 0);+		glyph.active_paths.last ().data.points.last ().data.right_handle.parent.recalculate_linear_handles (); 	}  	public static void set_default_handle_positions () {diff --git a/src/Toolbox.vala b/src/Toolbox.valaindex 5d15986..94ae216 100644--- a/src/Toolbox.vala+++ b/src/Toolbox.vala@@ -203,12 +203,11 @@ class Toolbox : DrawingArea { 		Tool reverse_path_tool = new Tool ("reverse_path", "Create counter from outline", 'r'); 		reverse_path_tool.select_action.connect((self) => { 				Glyph g = MainWindow.get_current_glyph ();-				Path? p = g.active_path; 				-				if (p != null) {-					((!)p).reverse ();+				foreach (Path p in g.active_paths) {+					p.reverse (); 				}-				+			 				g.redraw_area (0, 0, g.allocation.width, g.allocation.height); 			}); 		path_tool_modifiers.add_tool (reverse_path_tool);@@ -216,11 +215,8 @@ class Toolbox : DrawingArea { 		Tool move_layer = new Tool ("move_layer", "Move to path to bottom layer", 'd'); 		move_layer.select_action.connect((self) => { 			Glyph g = MainWindow.get_current_glyph ();-			Path p;-			-			if (g.active_path != null) {-				p = (!) g.active_path;-				++			foreach (Path p in g.active_paths) { 				g.path_list.remove (p); 				g.path_list.prepend (p); 			}

Contact

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