Skip to content

Commit

Permalink
Use transform for editing
Browse files Browse the repository at this point in the history
  • Loading branch information
sapoturge committed Oct 23, 2024
1 parent 1138c2e commit 607e2a4
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/data/Container.vala
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ public interface Container : Undoable, Updatable, Transformed {
}
}

public virtual bool clicked_handle (double x, double y, double tolerance, out Handle? handle) {
public bool clicked_handle (double x, double y, double tolerance, out Handle? handle) {
if (selected_child != null) {
if (selected_child.transform_enabled) {
if (selected_child.transform.check_controls (x, y, tolerance, out handle)) {
Expand Down
43 changes: 37 additions & 6 deletions src/data/Image.vala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class Image : Object, Undoable, Updatable, Transformed, Container {
public override Gtk.TreeListModel tree { get; set; }
public override Element? selected_child { get; set; }
public Transform transform { get; set; }
private Cairo.Matrix applied_transform;
private Transform applied_transform;
private Element? applied_element;

protected Gee.Map<Element, Container.ElementSignalManager> signal_managers { get; set; }
Expand Down Expand Up @@ -53,7 +53,7 @@ public class Image : Object, Undoable, Updatable, Transformed, Container {

construct {
transform = new Transform.identity ();
applied_transform = Cairo.Matrix.identity ();
applied_transform = new Transform.identity ();
stack = new CommandStack ();
var model = new ListStore (typeof (Element));
this.tree = new Gtk.TreeListModel (model, false, false, get_children);
Expand Down Expand Up @@ -132,15 +132,13 @@ public class Image : Object, Undoable, Updatable, Transformed, Container {
}

public void draw (Cairo.Context cr) {
cr.save ();
cr.transform (applied_transform);
applied_transform.apply (cr);
draw_children (cr);
cr.restore ();
}

public void draw_selection (Cairo.Context cr, double zoom) {
cr.save ();
cr.transform (applied_transform);
applied_transform.apply (cr);
draw_selected_child (cr, zoom);
cr.restore ();
}
Expand Down Expand Up @@ -259,4 +257,37 @@ public class Image : Object, Undoable, Updatable, Transformed, Container {

public void cancel (string prop) {
}

public bool clicked_element (double x, double y, double tolerance, out Element? element, out Segment? segment, out Handle? handle) {
double new_x, new_y, new_tolerance;
applied_transform.update_point (x, y, out new_x, out new_y);
applied_transform.update_distance (tolerance, out new_tolerance);
Handle inner_handle;
if (clicked_child (new_x, new_y, Math.sqrt ((tolerance * tolerance + new_tolerance * new_tolerance) / 2), out element, out segment, out inner_handle)) {
if (inner_handle != null) {
handle = new TransformedHandle ("Applied Transform", inner_handle, applied_transform);
} else {
handle = null;
}

return true;
}

handle = null;
return false;
}

public bool clicked_control (double x, double y, double tolerance, out Handle? handle) {
double new_x, new_y, new_tolerance;
applied_transform.update_point (x, y, out new_x, out new_y);
applied_transform.update_distance (tolerance, out new_tolerance);
Handle inner_handle;
if (clicked_handle (new_x, new_y, new_tolerance, out inner_handle)) {
handle = new TransformedHandle ("Applied Transform", inner_handle, applied_transform);
return true;
}

handle = null;
return false;
}
}
2 changes: 1 addition & 1 deletion src/data/Path.vala
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ public class Path : Element {
});
if (transform_enabled && transform_applied) {
opts.add (new ContextOption.action (_("Revert View"), () => {
apply_transform (Cairo.Matrix.identity(), null);
apply_transform (new Transform.identity(), null);
}));
} else if (transform_enabled) {
opts.add (new ContextOption.action (_("Apply Transformation"), () => {
Expand Down
73 changes: 52 additions & 21 deletions src/data/Transform.vala
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public class Transform : Object, Undoable {
}

var new_scale_y = scale_y - ae / height;

var aa = a.dist (left);

side = (bottom.x - left.x) * (value.y - left.y) - (bottom.y - left.y) * (value.x - left.x);
Expand All @@ -80,7 +80,7 @@ public class Transform : Object, Undoable {
if (scale_y < 0) {
aa = -aa;
}

var new_scale_x = scale_x - (aa - ae * skew) / width;

if (new_scale_x == 0 || new_scale_y == 0) {
Expand Down Expand Up @@ -134,7 +134,7 @@ public class Transform : Object, Undoable {
}

var new_scale_y = scale_y - ae / height;

var aa = a.dist (right);

side = (bottom.x - right.x) * (value.y - right.y) - (bottom.y - right.y) * (value.x - right.x);
Expand All @@ -146,7 +146,7 @@ public class Transform : Object, Undoable {
if (scale_y < 0) {
aa = -aa;
}

var new_scale_x = scale_x - (aa + ae * skew) / width;

if (new_scale_x == 0 || new_scale_y == 0) {
Expand Down Expand Up @@ -205,7 +205,7 @@ public class Transform : Object, Undoable {
}

var new_scale_y = scale_y - ae / height;

var aa = a.dist (left);

side = (top.x - left.x) * (value.y - left.y) - (top.y - left.y) * (value.x - left.x);
Expand All @@ -217,7 +217,7 @@ public class Transform : Object, Undoable {
if (scale_y < 0) {
aa = -aa;
}

var new_scale_x = scale_x - (aa + ae * skew) / width;

if (new_scale_x == 0 || new_scale_y == 0) {
Expand Down Expand Up @@ -272,7 +272,7 @@ public class Transform : Object, Undoable {
}

var new_scale_y = scale_y - ae / height;

var aa = a.dist (right);

side = (top.x - right.x) * (value.y - right.y) - (top.y - right.y) * (value.x - right.x);
Expand All @@ -284,7 +284,7 @@ public class Transform : Object, Undoable {
if (scale_y < 0) {
aa = -aa;
}

var new_scale_x = scale_x - (aa - ae * skew) / width;

if (new_scale_x == 0 || new_scale_y == 0) {
Expand Down Expand Up @@ -347,6 +347,37 @@ public class Transform : Object, Undoable {
});
}

public Transform.from_matrix (Cairo.Matrix matrix) {
translate_x = matrix.x0;
translate_y = matrix.y0;

// The remaining matrix values are as follows:
//
// +- -+
// | C*S C*S*K-N*s |
// | N*S N*S*K+C*s |
// +- -+
//
// Where
// C = cos(angle)
// N = sin(angle)
// S = scale in X direction
// s = scale in Y direction
// K = skew on X axis

scale_x = Math.sqrt (matrix.xx * matrix.xx + matrix.yx * matrix.yx);
this.angle = Math.atan2 (matrix.yx, matrix.xx);
// I really hope my math is right on these.
skew = (matrix.xy + matrix.yx * matrix.yy / matrix.xx) / (matrix.xx + matrix.yx * matrix.yx / matrix.xx);
scale_y = (matrix.yy - matrix.yx * matrix.xy / matrix.xx) / (matrix.yx * matrix.yx / (scale_x * matrix.xx) + matrix.xx / scale_x);
this.matrix = matrix;

notify.connect (() => {
update_matrix ();
update ();
});
}

public Transform.from_string (string? description) {
translate_x = 0;
translate_y = 0;
Expand Down Expand Up @@ -401,7 +432,7 @@ public class Transform : Object, Undoable {
parser.get_double (out cy);
parser.match (")");
}

matrix.translate (cx, cy);
matrix.rotate (local_angle * Math.PI / 180.0);
matrix.translate (-cx, -cy);
Expand All @@ -416,7 +447,7 @@ public class Transform : Object, Undoable {
parser.get_double (out sy);
parser.match (")");
}

if (sx == 0) { sx = 1; }
if (sy == 0) { sy = 1; }
matrix.scale (sx, sy);
Expand Down Expand Up @@ -449,21 +480,21 @@ public class Transform : Object, Undoable {

translate_x = matrix.x0;
translate_y = matrix.y0;

// The remaining matrix values are as follows:
//
//
// +- -+
// | C*S C*S*K-N*s |
// | N*S N*S*K+C*s |
// +- -+
//
//
// Where
// C = cos(angle)
// N = sin(angle)
// S = scale in X direction
// s = scale in Y direction
// K = skew on X axis

scale_x = Math.sqrt (matrix.xx * matrix.xx + matrix.yx * matrix.yx);
this.angle = Math.atan2 (matrix.yx, matrix.xx);
// I really hope my math is right on these.
Expand Down Expand Up @@ -669,16 +700,16 @@ public class Transform : Object, Undoable {
new_dist = Math.sqrt ((dist * dist + new_dist * new_dist) / 2);
}

public Cairo.Matrix invert () {
var inverted = matrix;
inverted.invert ();
return inverted;
public Transform invert () {
var mat = matrix;
mat.invert ();
return new Transform.from_matrix (mat);
}

public Cairo.Matrix invert_with (Cairo.Matrix base_matrix) {
public Transform invert_with (Transform base_transform) {
var new_matrix = matrix;
new_matrix.invert ();
new_matrix.multiply(new_matrix, base_matrix);
return new_matrix;
new_matrix.multiply(new_matrix, base_transform.matrix);
return new Transform.from_matrix(new_matrix);
}
}
2 changes: 1 addition & 1 deletion src/data/Transformed.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public interface Transformed: Object {
transform.height = height;
}

public signal void apply_transform (Cairo.Matrix inner, Element? element);
public signal void apply_transform (Transform inner, Element? element);
}
2 changes: 1 addition & 1 deletion src/widgets/EditorView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public class EditorView : Gtk.Box {
transform_label = new Gtk.Label (_("Viewing with no transform applied."));
transform_bar.add_child (transform_label);
transform_bar.add_button (_("Revert view"), 0);
transform_bar.response.connect ((response) => image.apply_transform (Cairo.Matrix.identity(), null));
transform_bar.response.connect ((response) => image.apply_transform (new Transform.identity(), null));

viewport = new Viewport ();
var scrolled = new Gtk.ScrolledWindow ();
Expand Down
9 changes: 6 additions & 3 deletions src/widgets/Viewport.vala
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public class Viewport : Gtk.DrawingArea, Gtk.Scrollable {
image.path_selected.connect (() => {
current_handle = null;
});
image.apply_transform.connect ((t, e) => {
current_handle = null;
});
scroll_x = -_image.width / 2;
scroll_y = -_image.height / 2;
}
Expand Down Expand Up @@ -221,7 +224,7 @@ public class Viewport : Gtk.DrawingArea, Gtk.Scrollable {
Element path;
Segment segment;
Handle handle;
if (image.clicked_child (scale_x (x), scale_y (y), 6 / zoom, out path, out segment, out handle)) {
if (image.clicked_element (scale_x (x), scale_y (y), 6 / zoom, out path, out segment, out handle)) {
if (tutorial != null && tutorial.step == CLICK) {
tutorial.next_step ();
}
Expand All @@ -242,7 +245,7 @@ public class Viewport : Gtk.DrawingArea, Gtk.Scrollable {
Element path;
Segment segment;
Handle handle;
if (image.clicked_child (scale_x (x), scale_y (y), 6 / zoom, out path, out segment, out handle)) {
if (image.clicked_element (scale_x (x), scale_y (y), 6 / zoom, out path, out segment, out handle)) {
path.select (true);
current_handle = handle;
show_context_menu (path, segment, handle, x, y);
Expand All @@ -267,7 +270,7 @@ public class Viewport : Gtk.DrawingArea, Gtk.Scrollable {
// Check for clicking on a control handle
if (image.has_selected ()) {
Handle obj;
if (image.clicked_handle (sx, sy, 6 / zoom, out obj)) {
if (image.clicked_control (sx, sy, 6 / zoom, out obj)) {
current_handle = obj;
bind_point (obj, "point");
return;
Expand Down

0 comments on commit 607e2a4

Please sign in to comment.