-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFilter.pde
More file actions
200 lines (169 loc) · 4.62 KB
/
Filter.pde
File metadata and controls
200 lines (169 loc) · 4.62 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
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
class Filter {
String name;
int flags;
int allFlag;
String[] options;
Checkbox allBox;
Checkbox[] boxes;
int cRad = 5;
float x, y, w, h;
float fullHeight;
float smallHeight;
boolean collapsed = true;
public Filter(String name, String[] options, float x, float y) {
this.name = name;
this.options = options;
this.x = x;
this.y = y;
boxes = new Checkbox[options.length];
for (int i = 0; i < options.length; i++) {
boxes[i] = new Checkbox(this, options[i], x+10, y+70+i*30, false);
}
allBox = new Checkbox(this, "All", x+10, y+40, true);
allFlag = (int)pow(2, options.length);
flags = allFlag;
this.w = 300;
this.fullHeight = 30*options.length+70;
this.smallHeight = 35;
this.h = smallHeight;
}
public void display() {
noStroke();
fill(255, 255, 255, 220);
rect(x, y, w, h, cRad, cRad, cRad, cRad);
textAlign(LEFT, TOP);
textSize(25);
if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h) {
fill(0);
} else fill(80);
text(name, x+10, y);
if (!collapsed) {
allBox.display();
for (Checkbox c : boxes) c.display();
}
}
public boolean filter(String[] l) {
for (String s : l) if (filter(s)) return true;
return false;
}
// returns wether s passes the filter or not
public boolean filter(String s) {
// prioritise flag states w/o calculations
if (flags == allFlag) return true;
if (flags == 0) return false;
// Find if bit is set and value s passes the filter
for (int i = 0; i < options.length; i++) {
if (((flags >> i) & 1) == 1 && s.equals(options[i])) {
return true;
}
}
return false;
}
public void addFilter(String o) {
println("add: ", this.name, o);
// If "All", set flag and uncheck boxes
if (o.equals("All")) {
flags = allFlag;
for (Checkbox c : boxes) c.ensureOff();
return;
}
// reset flags if "All" is already selected
if (flags == allFlag) flags = 0;
// Set flag bit for corresponding filter, if found
for (int i = 0; i < options.length; i++) if (o.equals(options[i])) {
flags |= (int)pow(2, i);
return;
}
println("WARN: Filter not found - ", name, o);
}
public void removeFilter(String o) {
println("rm: ", this.name, o);
// If "All" is unset, reset flags
if (o.equals("All")) {
flags = 0;
return;
}
// Unset flag bit for corresponding filter, if found
for (int i = 0; i < options.length; i++) if (o.equals(options[i])) {
flags ^= (int)pow(2, i);
return;
}
println("WARN: Filter not found - ", name, o);
}
public boolean isInside() {
float x = mouseX;
float y = mouseY;
return x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h;
}
public boolean clicked(float x, float y) {
// Check for collapse toggle
if (collapsed) if (isInside()) {
collapsed = false;
this.h = fullHeight;
return true;
} else {
return false;
}
// if box clicked, toggle and make sure "All" is off
for (Checkbox c : boxes) if (c.checkClick(x, y)) {
allBox.ensureOff();
return true;
}
// No boxes clicked, check "All"
if (allBox.checkClick(x, y)) return true;
// clicked but not in box => collapse
if (isInside()) {
collapsed = true;
this.h = smallHeight;
return true;
}
return false;
}
public boolean collapsed() {
return this.collapsed;
}
}
class Checkbox {
String name;
boolean checked;
int size = 20;
float x, y;
Filter parent;
public Checkbox(Filter f, String name, float x, float y, boolean b) {
this.name = name;
this.x = x;
this.y = y;
this.checked = b;
this.parent = f;
if (b) parent.addFilter(name);
}
public void display() {
stroke(0);
strokeWeight(2);
if (mouseX > this.x && mouseX < this.x+size && mouseY > this.y && mouseY < this.y+size) {
fill(220);
} else fill(255);
rect(x, y, size, size, 2, 2, 2, 2);
fill(0);
if (checked) {
line(x, y, x+size, y+size);
line(x, y+size, x+size, y);
}
textSize(size);
textAlign(LEFT, CENTER);
text(name, x+size+10, y+size/3);
}
public boolean checkClick(float x, float y) {
// if checkbox clicked, toggle and add/remove filter as appropriate
if (x > this.x && x < this.x+size && y > this.y && y < this.y+size) {
this.checked = !this.checked;
if (this.checked) parent.addFilter(this.name);
else parent.removeFilter(this.name);
return true;
}
return false;
}
public void ensureOff() {
this.checked = false;
}
}