Commit 11b4dd9
move multiple edit points
Changed files (7)
modifiedsrc/ClipTool.valamodifiedsrc/EditPoint.valamodifiedsrc/Glyph.valamodifiedsrc/MoveTool.valamodifiedsrc/Path.valamodifiedsrc/PenTool.valamodifiedsrc/Toolbox.vala
Diff
@@ -87,6 +87,7 @@ class ClipTool : Tool { ((!)destination).add_path (((!)path).copy ()); } + ((!)destination).update_view (); } }@@ -44,8 +44,8 @@ class EditPoint { public unowned List<EditPoint>? next = null; public bool active = false;- bool active_handle = false;- + public bool selected = false;+ public int selected_handle = 0; public EditPointHandle right_handle;@@ -220,14 +220,6 @@ class EditPoint { return new_point; } - public bool get_active_handle () {- return active_handle; - }- - public void set_active_handle (bool a) {- active_handle = a; - }- public bool is_close (double x, double y) { return get_close_distance (x, y) < double.MAX; }@@ -325,6 +317,14 @@ class EditPoint { y = yt; } + public bool is_selected () {+ return selected;+ }+ + public void set_selected (bool s) {+ selected = s;+ }+ public bool set_active (bool active) { bool update = (this.active != active); @@ -46,8 +46,6 @@ class Glyph : FontDisplay { double last_move_offset_y = 0; // Control points- public EditPoint? active_point = null;- public EditPoint? selected_point = null; public EditPoint? new_point_on_path = null; public EditPoint? flipping_point_on_path = null; public EditPoint? last_added_edit_point = null;@@ -504,25 +502,7 @@ class Glyph : FontDisplay { } public override void key_press (uint keyval) { - Tool t;- - if (keyval == Key.DEL) {- if (active_paths.length () != 0) {- - foreach (Path p in active_paths) {- path_list.remove (p);- redraw_area (0, 0, allocation.width, allocation.height);- }- - clear_active_paths ();- }- - if (selected_point != null) {- delete_edit_point ((!) selected_point);- }- }- - t = MainWindow.get_toolbox ().get_current_tool ();+ Tool t = MainWindow.get_toolbox ().get_current_tool (); t.key_press_action (t, keyval); } @@ -831,11 +811,12 @@ class Glyph : FontDisplay { return min_point; } - private void insert_edit_point (double x, double y) {+ private EditPoint insert_edit_point (double x, double y) { unowned List<Path> paths; double xt, yt; bool added; Path np;+ EditPoint inserted; if (active_paths.length () == 0) { np = new Path ();@@ -846,12 +827,9 @@ class Glyph : FontDisplay { paths = path_list; - xt = x - xc () - view_offset_x;- yt = -y + yc () + view_offset_y;-- xt *= view_zoom;- yt *= view_zoom; - + xt = path_coordinate_x (x);+ yt = path_coordinate_y (y);+ added = false; if (new_point_on_path != null) {@@ -873,7 +851,7 @@ class Glyph : FontDisplay { flipping_point_on_path = new_point_on_path; new_point_on_path = null; added = true;- return;+ return e; } if (!added) {@@ -918,26 +896,24 @@ class Glyph : FontDisplay { } assert (active_paths.length () > 0);+ assert (active_paths.last ().data.points.length () > 0); - selected_point = active_paths.last ().data.get_last_point ();- assert (selected_point != null);+ inserted = active_paths.last ().data.points.data; - move_selected_edit_point (x, y);+ return inserted; } - public void move_selected_edit_point_delta (double dx, double dy) - requires (selected_point != null)- {- double px = ((!) selected_point).x + xc () - view_offset_x;- double py = -1 * (((!) selected_point).y - yc () + view_offset_y);+ public void move_selected_edit_point_delta (EditPoint selected_point, double dx, double dy) {+ double px = selected_point.x + xc () - view_offset_x;+ double py = -1 * (selected_point.y - yc () + view_offset_y); px *= view_zoom; py *= view_zoom; - move_selected_edit_point (dx + px, dy + py);+ move_selected_edit_point (selected_point, dx + px, dy + py); } - public void move_selected_edit_point (double x, double y) { + public void move_selected_edit_point (EditPoint selected_point, double x, double y) { double xc, yc, xt, yt; double ivz = 1 / view_zoom; EditPoint p;@@ -957,7 +933,7 @@ class Glyph : FontDisplay { redraw_area ((int)(x - 4*view_zoom), (int)(y - 4*view_zoom), (int)(x + 3*view_zoom), (int)(y + 3*view_zoom)); // update position of selected point- ((!) selected_point).set_position (xt, yt);+ selected_point.set_position (xt, yt); if (view_zoom >= 2) { redraw_area (0, 0, allocation.width, allocation.height);@@ -1037,7 +1013,6 @@ class Glyph : FontDisplay { clear_active_paths (); new_point_on_path = null; flipping_point_on_path = null;- selected_point = null; delete_invisible_paths (); @@ -101,6 +101,17 @@ class MoveTool : Tool { last_y = y; } });+ + key_press_action.connect ((self, keyval) => {+ Glyph g = MainWindow.get_current_glyph ();+ + if (keyval == Key.DEL) {+ foreach (Path p in g.active_paths) {+ g.path_list.remove (p);+ g.update_view ();+ }+ }+ }); } void tie_path_to_grid (Path p, double x, double y) {@@ -57,8 +57,12 @@ class Path { private static ImageSurface? edit_point_image = null; private static ImageSurface? active_edit_point_image = null;+ private static ImageSurface? edit_point_handle_image = null; private static ImageSurface? active_edit_point_handle_image = null;++ private static ImageSurface? selected_edit_point_image = null;+ private static ImageSurface? active_selected_edit_point_image = null; Path quadratic_path; // quadratic points for ttf export @@ -68,6 +72,8 @@ class Path { active_edit_point_image = Icons.get_icon ("active_edit_point.png"); edit_point_handle_image = Icons.get_icon ("edit_point_handle.png"); active_edit_point_handle_image = Icons.get_icon ("active_edit_point_handle.png");+ selected_edit_point_image = Icons.get_icon ("selected_edit_point.png");+ active_selected_edit_point_image = Icons.get_icon ("active_selected_edit_point.png"); } } @@ -130,7 +136,7 @@ class Path { if (is_editable ()) { // control points for curvature foreach (EditPoint e in ep) {- if (e.get_active_handle () || e.selected_handle > 0)+ if (e.selected || e.selected_handle > 0) draw_edit_point_handles (e, cr); } @@ -287,7 +293,14 @@ class Path { public static void draw_edit_point_center (EditPoint e, Context cr) requires (active_edit_point_image != null && edit_point_image != null) { - ImageSurface img = (e.active) ? (!) active_edit_point_image : (!) edit_point_image;+ ImageSurface img;+ + if (e.is_selected ()) {+ img = (e.active) ? (!) active_selected_edit_point_image : (!) selected_edit_point_image;+ } else {+ img = (e.active) ? (!) active_edit_point_image : (!) edit_point_image;+ }+ draw_img_center (cr, img, e.x, e.y); } @@ -855,19 +868,16 @@ class Path { second_last_point = last_point; last_point = p;-- return np; + PenTool.set_default_handle_positions ();+ + return np; } public void close () { open = false; edit = false;- - foreach (EditPoint ep in points) {- ep.set_active_handle (false);- }- + create_list (); if (points.length () > 2) {@@ -25,8 +25,8 @@ class PenTool : Tool { public static bool edit_active_corner = false; public static EditPoint active_corner = new EditPoint ();- public static EditPoint selected_corner = new EditPoint (); public static Path active_path = new Path ();+ public static List<EditPoint> selected_points = new List<EditPoint> (); public static EditPointHandle active_handle = new EditPointHandle.empty (); public static EditPointHandle selected_handle = new EditPointHandle.empty ();@@ -41,9 +41,6 @@ class PenTool : Tool { private static double last_point_x = 0; private static double last_point_y = 0; - private static bool adjust_precision = false;- private static double adjust_precision_begin_x = 0;- private static double adjust_precision_begin_y = 0; public static double precision = 1; public PenTool (string name) {@@ -76,18 +73,21 @@ class PenTool : Tool { double x = ix; double y = iy; Glyph g = MainWindow.get_current_glyph ();+ EditPoint selected_corner; - if (move_selected && GridTool.is_visible ()) {+ if (move_selected && GridTool.is_visible () && selected_points.length () > 0) {+ selected_corner = selected_points.last ().data; GridTool.tie (ref x, ref y);- g.move_selected_edit_point (x, y);+ g.move_selected_edit_point (selected_corner, x, y); } move_selected = false; move_selected_handle = false; edit_active_corner = false; - selected_handle = new EditPointHandle.empty (); active_handle = new EditPointHandle.empty ();+ + move (x, y); }); move_action.connect ((self, x, y) => {@@ -95,25 +95,18 @@ class PenTool : Tool { }); key_press_action.connect ((self, keyval) => {- if (keyval == Key.SHIFT_LEFT) {- adjust_precision = true;+ Glyph g = MainWindow.get_current_glyph ();+ + if (keyval == Key.DEL) {+ foreach (EditPoint p in selected_points) {+ g.delete_edit_point (p);+ } - adjust_precision_begin_x = last_point_x;- adjust_precision_begin_y = last_point_y;+ g.update_view (); } }); key_release_action.connect ((self, keyval) => {- if (keyval == Key.SHIFT_LEFT) {- adjust_precision = false;- set_precision (1.0 / Path.distance (adjust_precision_begin_x, last_point_x, adjust_precision_begin_y, last_point_y));- - precision *= 30;- - if (precision > 1) {- set_precision (precision);- } - } }); } @@ -130,29 +123,15 @@ class PenTool : Tool { Glyph glyph = MainWindow.get_current_glyph (); EditPoint ep; - if (adjust_precision) {- last_point_x = x;- last_point_y = y;- return;- }- control_point_event (x, y); curve_active_corner_event (x, y); set_default_handle_positions ();- + // show new point on path if (glyph.new_point_on_path != null) { move_current_point_on_path (x, y); } - // show curve handles- active_corner.set_active_handle (false);- selected_corner.set_active_handle (true);- if (active_edit_point != null) {- active_corner = (!) active_edit_point;- active_corner.set_active_handle (true);- }- // move curve handles if (move_selected_handle) { if (GridTool.is_visible ()) {@@ -177,24 +156,15 @@ class PenTool : Tool { // move edit point if (move_selected) {- glyph.move_selected_edit_point_delta ((x - last_point_x) * precision, (y - last_point_y) * precision);- ep = (!) glyph.selected_point;- - if (tie_x_or_y_coordinates) {- return_if_fail (glyph.selected_point != null);- GridTool.tie_to_prev (ep, x, y);- }- - if (active_corner != selected_corner) {- active_corner.set_active_handle (false);- }- - if (!is_over_handle (x, y) && active_edit_point != null) { - active_corner = (!) active_edit_point;- active_corner.set_active_handle (true);+ foreach (EditPoint p in selected_points) {+ glyph.move_selected_edit_point_delta (p, (x - last_point_x) * precision, (y - last_point_y) * precision);+ + if (tie_x_or_y_coordinates) {+ GridTool.tie_to_prev (p, x, y);+ }+ + p.recalculate_linear_handles (); }- - ep.recalculate_linear_handles (); } last_point_x = x;@@ -207,6 +177,9 @@ class PenTool : Tool { return_if_fail (g != null); + // make path transparent and show edit points+ glyph.open_path ();+ // select or deselect a path if (button == 3) { if (glyph.has_active_path ()) {@@ -220,9 +193,6 @@ class PenTool : Tool { return; } - // make path transparent and show edit points- glyph.open_path ();- if (insert_new_point_on_path_selected ()) { glyph.insert_new_point_on_path (x, y); return;@@ -237,7 +207,6 @@ class PenTool : Tool { if (is_new_point_on_path_selected ()) { move_selected = true; move_point_on_path = true;- glyph.selected_point = active_edit_point; glyph.new_point_on_path = null; return; }@@ -250,8 +219,12 @@ class PenTool : Tool { } control_point_event (x, y);- select_active_point (x, y); curve_corner_event (x, y);+ + if (!move_selected_handle) {+ select_active_point (x, y);+ }+ glyph.store_undo_state (); if (is_erase_selected () && active_edit_point != null) {@@ -263,24 +236,27 @@ class PenTool : Tool { Glyph? g = MainWindow.get_current_glyph (); Glyph glyph = (!) g; - foreach (Path cp in glyph.active_paths) {- foreach (var e in cp.points) {- e.set_active (false);+ if (KeyBindings.modifier != SHIFT) {+ if (active_edit_point != null) {+ ((!)active_edit_point).set_active (false); }++ remove_all_selected_points (); } move_selected = true; move_point_on_path = true;- - glyph.selected_point = active_edit_point;++ if (active_edit_point != null) {+ ((!)active_edit_point).set_selected (true);+ } if (!is_over_handle (x, y)) {- selected_corner.set_active_handle (false); edit_active_corner = true; set_default_handle_positions (); if (active_edit_point != null) {- selected_corner = (!) active_edit_point;+ add_selected_point ((!) active_edit_point); } } @@ -420,11 +396,18 @@ class PenTool : Tool { public void new_point_action (int x, int y) { Glyph glyph;+ EditPoint new_point; glyph = MainWindow.get_current_glyph (); glyph.open_path ();- glyph.add_new_edit_point (x, y); - set_linear_handles_for_last_point ();+ new_point = glyph.add_new_edit_point (x, y);+ new_point.set_selected (true);+ + if (KeyBindings.modifier != SHIFT) {+ remove_all_selected_points ();+ }+ + add_selected_point (new_point); move_selected = true; }@@ -496,10 +479,12 @@ class PenTool : Tool { begin_new_point_on_path = false; } + /* // DELETE if (glyph.active_point != null) { move_selected = true; return false; }+ */ return true; }@@ -527,11 +512,19 @@ class PenTool : Tool { } private bool is_over_handle (double x, double y) {- double dp = selected_corner.get_close_distance (x, y);- double dl = selected_corner.get_left_handle ().get_point ().get_close_distance (x, y);- double dr = selected_corner.get_right_handle ().get_point ().get_close_distance (x, y);+ double dp, dl, dr; - return (dl < dp || dr < dp);+ foreach (EditPoint selected_corner in selected_points) {+ dp = selected_corner.get_close_distance (x, y);+ dl = selected_corner.get_left_handle ().get_point ().get_close_distance (x, y);+ dr = selected_corner.get_right_handle ().get_point ().get_close_distance (x, y);+ + if (dl < dp || dr < dp) {+ return true;+ }+ }+ + return false; } private void curve_active_corner_event (double x, double y) {@@ -542,19 +535,19 @@ class PenTool : Tool { if (!is_over_handle (x, y)) { return; } --- eh = selected_corner.get_left_handle ();- if (eh.get_point ().is_close (x, y)) {- eh.active = true;- active_handle = eh;- } - - eh = selected_corner.get_right_handle ();- if (eh.get_point ().is_close (x, y)) {- eh.active = true;- active_handle = eh; + foreach (EditPoint selected_corner in selected_points) {+ eh = selected_corner.get_left_handle ();+ if (eh.get_point ().is_close (x, y)) {+ eh.active = true;+ active_handle = eh;+ }+ + eh = selected_corner.get_right_handle ();+ if (eh.get_point ().is_close (x, y)) {+ eh.active = true;+ active_handle = eh; + } } } @@ -563,24 +556,42 @@ class PenTool : Tool { open_closest_path (x, y); - if (!is_over_handle (x, y)) {- return;+ foreach (EditPoint selected_corner in selected_points) {+ eh = selected_corner.get_left_handle ();+ + if (eh.get_point ().is_close (x, y)) {+ selected_handle = eh;+ move_selected_handle = true;+ }++ eh = selected_corner.get_right_handle ();+ + if (eh.get_point ().is_close (x, y)) {+ selected_handle = eh;+ move_selected_handle = true;+ }+ } + }++ void add_selected_point (EditPoint p) {+ foreach (EditPoint ep in selected_points) {+ if (p == ep) {+ return;+ } } - eh = selected_corner.get_left_handle ();- - if (eh.get_point ().is_close (x, y)) {- selected_handle = eh;- move_selected_handle = true;+ selected_points.append (p);+ }+ + void remove_all_selected_points () {+ foreach (EditPoint e in selected_points) {+ e.set_active (false);+ e.set_selected (false); }-- eh = selected_corner.get_right_handle ();- - if (eh.get_point ().is_close (x, y)) {- selected_handle = eh;- move_selected_handle = true;+ + while (selected_points.length () > 0) {+ selected_points.remove_link (selected_points.first ()); }- } /** Draw a test glyph. */@@ -113,19 +113,21 @@ class Toolbox : GLib.Object { Tool tie_editpoint_tool = new Tool ("tie_point", "Tie curve handles for selected edit point", 'w'); tie_editpoint_tool.select_action.connect ((self) => {- EditPoint ep; bool tie; select_draw_tool (); - ep = pen_tool.selected_corner;- tie = !ep.tie_handles;+ foreach (EditPoint ep in pen_tool.selected_points) {+ tie = !ep.tie_handles; - if (tie) {- ep.process_tied_handle ();+ if (tie) {+ ep.process_tied_handle ();+ }++ ep.set_tie_handle (tie);+ + MainWindow.get_current_glyph ().update_view (); }- - ep.set_tie_handle (tie); }); draw_tool_modifiers.add_tool (tie_editpoint_tool);