-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtablet.pde
169 lines (140 loc) · 4.6 KB
/
tablet.pde
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import codeanticode.tablet.*;
import java.util.*;
Tablet tablet;
Event currentEvent = new Event();
List<Line> lines = new ArrayList<Line>();
List<Event> events = new ArrayList<Event>();
Tool selectedTool = Tool.PEN;
Tool toolModes[] = {Tool.MOVE, Tool.PEN, Tool.ERASER};
PImage penIcon, eraserIcon;
enum Tool {
PEN, ERASER, MOVE;
}
void setup() {
size(640,640);
surface.setResizable(true);
frameRate(120); //Framerate limit. 120 seems sufficient for smooth lines without making the list too long. May change in future...
noCursor();
stroke(0);
textSize(32);
tablet = new Tablet(this);
penIcon = loadImage("pen.png");
eraserIcon = loadImage("eraser.png");
}
boolean pMousePressed = false;
void draw() {
background(255);
selectedTool = toolModes[tablet.getPenKind() - 1];
if (mousePressed) {
if (!pMousePressed) { //Determines if the pen has just been pressed.
currentEvent.start = lines.size(); //Records the size of the list before the stroke.
currentEvent.tool = selectedTool;
}
pMousePressed = true;
switch(selectedTool) {
case PEN:
pen();
break;
case ERASER:
eraser();
break;
}
}
if (pMousePressed && !mousePressed) { //Determines if the pen has been lifted.
currentEvent.end = lines.size(); //Records the size of the list after the stroke.
events.add(currentEvent);
currentEvent = new Event();
pMousePressed = false;
}
drawSketch();
UI();
}
void keyPressed() {
if(key == 0x1A) { //^Z
undo();
}
}
void pen() {
float thickness = 30 * (map(tablet.getPressure(),0,1,0.1,0.2));
lines.add(new Line(pmouseX, pmouseY, mouseX, mouseY, thickness));
}
void eraser() {
for (int i = 0; i < lines.size(); i++) {
if (!lines.get(i).visible) { //Saves time and memory, no need to erase invisible lines.
continue;
}
PVector mp = new PVector((lines.get(i).start.x + lines.get(i).end.x)/2,(lines.get(i).start.y + lines.get(i).end.y)/2);
PVector mousePos = new PVector(mouseX,mouseY);
if (mousePos.dist(mp) < map(tablet.getPressure(),0,1,5,15)) { //Checks if the mouse is close enough to the line to be erased.
lines.get(i).visible = false;
currentEvent.erased.add(i);
}
}
}
void drawSketch() {
for (Line l : lines) {
l.draw();
}
}
void UI() {
//TODO: Dynamically change toolbar positions based on number of tools to make it easier to add tools.
push();
fill(180);
rect(0,0,width,64);
fill(200);
if (selectedTool == Tool.PEN) {
rect(width/2 - 64,0,64,64);
}
else if (selectedTool == Tool.ERASER) {
rect(width/2,0,64,64);
}
image(penIcon, width/2 - 64,0,64,64);
image(eraserIcon, width/2,0,64,64);
pop();
text("mode " + tablet.getPenKind(),width - (new String("mode " + tablet.getPenKind()).length())*20,54); //Displays the current pen mode.
if (mouseY > 64) { //Checks if the cursor is below the toolbar.
if (tablet.getPenKind() == 1) { //If using mouse, change the cursor to a HAND
cursor(HAND);
}
else { //Hide the cursor for the modes 2 & 3
noCursor();
}
//Draw a circular cursor
push();
noFill();
stroke(150); //TODO: Change colors to give better contrast.
if (selectedTool == Tool.PEN) {
circle(mouseX, mouseY, 5);
}
else if (selectedTool == Tool.ERASER) {
circle(mouseX, mouseY, map(tablet.getPressure(),0,1,5,15)); //TODO: The cursor size does not match the erasing radius.
}
pop();
}
else {
cursor(ARROW);
if (mousePressed && tablet.getPenKind() != 3) { //Mode 3 is locked to the eraser. Modes 1 & 2 can be changed.
if (mouseX > width/2 - 64 && mouseX < width/2) {
toolModes[tablet.getPenKind() - 1] = Tool.PEN;
}
else if (mouseX > width/2 && mouseX < width/2 + 64) {
toolModes[tablet.getPenKind() - 1] = Tool.ERASER;
}
}
}
}
void undo() {
if (events.size() < 1) { //Prevents undo if there is nothing to undo.
return;
}
Event event = events.get(events.size() - 1);
if (event.tool == Tool.PEN) {
lines.subList(event.start, event.end).clear();
}
else if (event.tool == Tool.ERASER) {
for (Integer i : event.erased) {
lines.get(i).visible = true;
}
}
events.remove(events.size() - 1);
}