-
Notifications
You must be signed in to change notification settings - Fork 0
/
Compositor.pde
196 lines (172 loc) · 5.64 KB
/
Compositor.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
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
// TODO: rename to Window manager and split to WindowManager and Compositor
// for now, assume that the compositor draws what the window manager renders
// however this may be incorrect, so avoid doing this for the time being
// untill more information is available on the difference between a
// compositor and a window manager
// start from https://github.com/mgood7123/AndroidCompositor/blob/5232f327e22df10368c780287822bc2320b22f06/app/src/main/jni/compositor.cpp#L17
//
// my current understanding of all this is that a compositor will render each
// application's frame buffer, and a window manager such as KDE or GNOME or I3,
// will work WITH the compositor retrieving information about windows and their
// position, then draw boarders around those windows and implement either stacking
// or tiling like functionality depending on the windowing system type and assumably
// send information back to the compositor such as updates on window changes.
// for example if the window is minimized or its position changes, the compositor
// will then redraw itself as it sees fit according to the received information
// end from https://github.com/mgood7123/AndroidCompositor/blob/5232f327e22df10368c780287822bc2320b22f06/app/src/main/jni/compositor.cpp#L17
// TODO: optimize focus algorithm
// TODO: implement double/tripple buffering for faster performance
// https://en.wikipedia.org/wiki/Multiple_buffering
// TODO: implement an restrainable PGraphics object
// in which fill(0) will only fill from x1, y2, to x2, y2
// instead of from 0, 0, width, height
class Compositor {
public PGraphics graphics;
ArrayList<WindowObject> windows = new ArrayList<WindowObject>();
WindowObject w;
CursorTools cursorTools = new CursorTools();
int windowFocus = -1;
int lastWindowFocus = -1;
boolean displayFPS = false;
boolean displayWindowFPS = false;
boolean debug = false;
boolean handleInputEvents = true;
Compositor(int width, int height) {
graphics = createGraphics(width, height, P3D);
}
void add(Window window, int width, int height, boolean displayFPS) {
w = new WindowObject(width, height);
w.displayFPS = displayFPS ? true : displayWindowFPS;
w.debug = debug;
windows.add(w);
w.attach(window);
}
void add(Window window, int width, int height) {
add(window, width, height, false);
}
void setLocation(int x, int y) {
w.x = x;
w.y = y;
}
void reorder_array() {
// re order the array based on last item clicked
ArrayList<WindowObject> focusableWindows = new ArrayList<WindowObject>();
boolean found = false;
for (WindowObject window: windows) {
if (window.focusable) {
window.focusable = false;
found = true;
focusableWindows.add(window);
}
}
if (found) {
// we have a list of focusable windows, and we know windows are drawn
// from first to last
// how would we determine what window needs to set to be focused
// so we can then move it to the end of the array...
// locate the top most window
int topMostIndex = 0;
// assume last index is top most //<>// //<>// //<>// //<>//
topMostIndex = focusableWindows.size()-1;
//<>//
WindowObject target = focusableWindows.get(topMostIndex);
windows.remove(windows.indexOf(target));
windows.add(target);
windowFocus = windows.size()-1;
} else windowFocus = -1;
}
void drawGraphics() {
if (displayFPS) {
graphics.beginDraw();
int oldColor = graphics.fillColor;
graphics.fill(255);
graphics.textSize(16);
graphics.text("FPS: " + frameRate, 10, 20);
graphics.fill(oldColor);
graphics.endDraw();
}
image(graphics, 0, 0);
}
void drawGraphics(WindowObject window) {
graphics.image(
window.graphics,
window.x,
window.y,
window.previewWidth,
window.previewHeight
);
}
void setup() {
cursorTools.loadCursor("cursors/aerodrop/right_ptr");
graphics.beginDraw();
for (WindowObject window: windows) {
window.setup();
drawGraphics(window);
}
graphics.endDraw();
drawGraphics();
}
void draw() {
graphics.beginDraw();
graphics.background(0);
for (WindowObject window: windows) {
window.draw();
drawGraphics(window);
}
graphics.endDraw();
drawGraphics();
}
void mousePressed() {
if (handleInputEvents) {
for (WindowObject window: windows) window.canFocus();
if (lastWindowFocus != -1) {
WindowObject win = windows.get(lastWindowFocus);
win.focus = false;
}
reorder_array();
if (windowFocus != -1) {
lastWindowFocus = windowFocus;
WindowObject win = windows.get(windowFocus);
win.focus = true;
win.mousePressed();
graphics.beginDraw();
drawGraphics(win);
graphics.endDraw();
drawGraphics();
}
}
}
void mouseDragged() {
if (handleInputEvents) {
graphics.beginDraw();
for (WindowObject window: windows) {
window.mouseDragged();
//drawGraphics(window);
}
graphics.endDraw();
drawGraphics();
}
}
void mouseReleased() {
if (handleInputEvents) {
graphics.beginDraw();
for (WindowObject window: windows) {
window.mouseReleased();
drawGraphics(window);
}
graphics.endDraw();
drawGraphics();
}
}
void mouseMoved() {
if (handleInputEvents) {
graphics.beginDraw();
for (WindowObject window: windows) {
window.mouseMoved();
drawGraphics(window);
}
graphics.endDraw();
drawGraphics();
}
}
}