-
Notifications
You must be signed in to change notification settings - Fork 89
Expand file tree
/
Copy pathRotateHandle.java
More file actions
124 lines (111 loc) · 3.86 KB
/
RotateHandle.java
File metadata and controls
124 lines (111 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package nodebox.handle;
import nodebox.graphics.*;
import nodebox.node.Node;
import nodebox.util.Geometry;
public class RotateHandle extends AbstractHandle {
public static final int HANDLE_LENGTH = 50;
private enum DragState {
NONE, HANDLE, CIRCLE
}
private String angleName, xName, yName;
private float pa, ca, oa;
private float handleLength = HANDLE_LENGTH;
private DragState dragState = DragState.NONE;
public RotateHandle(Node node) {
this(node, "angle");
}
public RotateHandle(Node node, String angleName) {
this(node, angleName, null, null);
}
public RotateHandle(Node node, String angleName, String xName, String yName) {
super(node);
this.angleName = angleName;
this.xName = xName;
this.yName = yName;
}
private float getCenterX() {
if (xName != null)
return node.asFloat(xName);
else
return 0;
}
private float getCenterY() {
if (yName != null)
return node.asFloat(yName);
else
return 0;
}
public void draw(GraphicsContext ctx) {
float cx = getCenterX();
float cy = getCenterY();
ctx.ellipsemode(GraphicsContext.EllipseMode.CENTER);
ctx.nofill();
ctx.stroke(HANDLE_COLOR);
ctx.ellipse(cx, cy, handleLength * 2, handleLength * 2);
double[] xy;
if (dragState == DragState.NONE || dragState == DragState.HANDLE)
xy = Geometry.coordinates(cx, cy, handleLength, node.asFloat(angleName));
else {
xy = Geometry.coordinates(cx, cy, handleLength, pa);
ctx.line(cx, cy, (float) xy[0], (float) xy[1]);
xy = Geometry.coordinates(cx, cy, handleLength, ca);
}
float x = (float) xy[0];
float y = (float) xy[1];
ctx.line(cx, cy, x, y);
ctx.fill(1);
ctx.ellipse(x, y, 6, 6);
if (dragState == DragState.HANDLE) {
xy = Geometry.coordinates(cx, cy, handleLength, oa);
ctx.line(cx, cy, (float) xy[0], (float) xy[1]);
}
}
@Override
public boolean mousePressed(Point pt) {
float cx = getCenterX();
float cy = getCenterY();
// original angle
oa = node.asFloat(angleName);
double[] xy = Geometry.coordinates(cx, cy, handleLength, oa);
float x = (float) xy[0];
float y = (float) xy[1];
Path p = new Path();
p.ellipse(cx, cy, handleLength * 2, handleLength * 2);
Rect handleRect = createHitRectangle(x, y);
float a = (float) Geometry.angle(cx, cy, pt.x, pt.y);
xy = Geometry.coordinates(cx, cy, handleLength, a);
float x1 = (float) xy[0];
float y1 = (float) xy[1];
Rect circleRect = createHitRectangle(x1, y1);
if (handleRect.contains(pt))
dragState = DragState.HANDLE;
else if (circleRect.contains(pt)) {
pa = a; // pressed angle
dragState = DragState.CIRCLE;
} else
dragState = DragState.NONE;
return (dragState != DragState.NONE);
}
@Override
public boolean mouseDragged(Point pt) {
if (dragState == DragState.NONE) return false;
float cx = getCenterX();
float cy = getCenterY();
float a = (float) Geometry.angle(cx, cy, pt.x, pt.y);
ca = a; // current angle
handleLength = (float) Geometry.distance(cx, cy, pt.x, pt.y);
if (dragState == DragState.HANDLE)
silentSet(angleName, a);
else if (dragState == DragState.CIRCLE)
silentSet(angleName, oa + a - pa);
return true;
}
@Override
public boolean mouseReleased(Point pt) {
if (dragState == DragState.NONE) return false;
dragState = DragState.NONE;
handleLength = HANDLE_LENGTH;
viewer.repaint();
return true;
}
}