more playlist code
[amper.git] / amper.d
blobbdc8f35634f058cbb760ddab7c2454e321e5922d
1 module amper is aliced;
3 import arsd.bmp;
4 import arsd.color;
5 import arsd.image;
6 import arsd.simpledisplay;
8 import iv.cmdcon;
9 import iv.cmdcongl;
10 import iv.sdpyutil;
11 import iv.strex;
12 import iv.vfs;
14 import egfx;
16 import amperskin;
19 // ////////////////////////////////////////////////////////////////////////// //
20 extern(C) nothrow @nogc {
21 Bool XTranslateCoordinates(Display *display, Window src_w, Window dest_w, int src_x, int src_y, int *dest_x_return, int *dest_y_return, Window *child_return);
25 // ////////////////////////////////////////////////////////////////////////// //
26 __gshared ubyte vbNewScale = 1;
29 // ////////////////////////////////////////////////////////////////////////// //
31 public __gshared void delegate () gxRebuildScreenCB;
33 public void gxRebuildScreen () {
34 if (gxRebuildScreenCB !is null) {
35 gxClipReset();
36 try {
37 gxRebuildScreenCB();
38 } catch (Exception e) {
39 conwriteln("SCREEN REBUILD ERROR: ", e.msg);
41 vglUpdateTexture();
47 // ////////////////////////////////////////////////////////////////////////// //
48 class ScrollTitleEvent {}
49 __gshared ScrollTitleEvent evScrollTitle;
51 shared static this () {
52 evScrollTitle = new ScrollTitleEvent();
56 // ////////////////////////////////////////////////////////////////////////// //
57 __gshared SimpleWindow sdampwin;
58 __gshared SimpleWindow sdplwin;
59 __gshared bool mainDrag = false;
60 __gshared int mainDrawPrevX, mainDrawPrevY;
63 // ////////////////////////////////////////////////////////////////////////// //
64 void closeAllIfMainIsClosed () {
65 if (sdampwin !is null && !sdampwin.closed) return;
66 if (sdplwin !is null && !sdplwin.closed) sdplwin.close();
70 // ////////////////////////////////////////////////////////////////////////// //
71 void createAmpWindow () {
72 sdpyWindowClass = "AMPER_PLAYER";
74 sdampwin = new SimpleWindow(skinImgMain.width*vbufEffScale, skinImgMain.height*vbufEffScale, "Amper", OpenGlOptions.yes, Resizablity.fixedSize, WindowTypes.undecorated);
75 glconMainWindow = sdampwin;
76 sdampwin.setMinSize(skinImgMain.width*vbufEffScale, skinImgMain.height*vbufEffScale);
77 sdampwin.setMaxSize(skinImgMain.width*vbufEffScale, skinImgMain.height*vbufEffScale);
78 //sdwin.hideCursor();
80 static if (is(typeof(&sdampwin.closeQuery))) {
81 sdampwin.closeQuery = delegate () { concmd("quit"); glconPostDoConCommands(); };
84 sdampwin.addEventListener((QuitEvent evt) {
85 scope(exit) if (!conQueueEmpty()) glconPostDoConCommands();
86 if (sdampwin.closed) { closeAllIfMainIsClosed(); return; }
87 if (isQuitRequested) { sdampwin.close(); closeAllIfMainIsClosed(); return; }
88 concmd("quit");
89 });
91 sdampwin.addEventListener((GLConScreenRebuildEvent evt) {
92 scope(exit) if (!conQueueEmpty()) glconPostDoConCommands();
93 if (sdampwin.closed) { closeAllIfMainIsClosed(); return; }
94 if (isQuitRequested) { sdampwin.close(); closeAllIfMainIsClosed(); return; }
95 //conwriteln("rebuilding screen");
96 sdampwin.redrawOpenGlSceneNow();
97 });
99 sdampwin.addEventListener((GLConScreenRepaintEvent evt) {
100 scope(exit) if (!conQueueEmpty()) glconPostDoConCommands();
101 if (sdampwin.closed) { closeAllIfMainIsClosed(); return; }
102 if (isQuitRequested) { sdampwin.close(); closeAllIfMainIsClosed(); return; }
103 sdampwin.redrawOpenGlSceneNow();
106 sdampwin.addEventListener((GLConDoConsoleCommandsEvent evt) {
107 scope(exit) if (!conQueueEmpty()) glconPostDoConCommands();
108 bool sendAnother = false;
109 bool prevVisible = isConsoleVisible;
111 consoleLock();
112 scope(exit) consoleUnlock();
113 conProcessQueue();
114 sendAnother = !conQueueEmpty();
116 if (sdampwin.closed) { closeAllIfMainIsClosed(); return; }
117 if (isQuitRequested) { sdampwin.close(); closeAllIfMainIsClosed(); return; }
118 if (sendAnother) glconPostDoConCommands();
120 if (prevVisible || isConsoleVisible) glconPostScreenRepaintDelayed();
121 if (vbNewScale != vbufEffScale) glconPostScreenRepaint();
123 if (vbNewScale != vglWindowScale(sdampwin)) {
124 vbNewScale = vglScaleWindow(sdampwin, vbNewScale);
125 vglScaleWindow(sdplwin, vbNewScale);
126 } else {
127 glconPostScreenRebuild();
131 sdampwin.addEventListener((ScrollTitleEvent evt) {
132 scope(exit) if (!conQueueEmpty()) glconPostDoConCommands();
133 if (sdampwin.closed) { closeAllIfMainIsClosed(); return; }
134 if (isQuitRequested) { sdampwin.close(); closeAllIfMainIsClosed(); return; }
135 //conwriteln("scrolling title");
136 ampMain.scrollTitle();
137 if (!sdampwin.eventQueued!ScrollTitleEvent) sdampwin.postTimeout(evScrollTitle, 100);
138 glconPostScreenRebuild();
141 sdampwin.windowResized = delegate (int wdt, int hgt) {
142 sdampwin.setMinSize(wdt, hgt);
143 sdampwin.setMaxSize(wdt, hgt);
146 sdampwin.redrawOpenGlScene = delegate () {
147 ampMain.onPaint();
148 //conwriteln("PAINT!");
149 if (sdplwin !is null && !sdplwin.closed) sdplwin.redrawOpenGlSceneNow();
152 sdampwin.visibleForTheFirstTime = delegate () {
153 vglRegisterWindow(sdampwin);
157 sdampwin.handlePulse = delegate () {
161 sdampwin.handleKeyEvent = delegate (KeyEvent event) {
162 if (event.pressed && event == "Escape") { concmd("quit"); return; }
163 //if (event.pressed && event == "Plus") { concmd("v_scale 2"); return; }
164 //if (event.pressed && event == "Minus") { concmd("v_scale 1"); return; }
165 //conwriteln(event.toStr);
166 ampMain.onKey(event);
167 glconPostScreenRebuild();
168 //sdwin.redrawOpenGlSceneNow();
171 sdampwin.handleMouseEvent = delegate (MouseEvent event) {
172 if (mainDrag) {
173 if (event.type == MouseEventType.motion /*&& event.modifierState&ModifierState.leftButtonDown*/) {
174 flushGui();
175 Window dummyw;
177 int nx = event.x*vbufEffScale;
178 int ny = event.y*vbufEffScale;
179 XTranslateCoordinates(sdampwin.display, sdampwin.window, RootWindow(sdampwin.display, DefaultScreen(sdampwin.display)), nx, ny, &nx, &ny, &dummyw);
180 int dx = nx-mainDrawPrevX;
181 int dy = ny-mainDrawPrevY;
182 mainDrawPrevX = nx;
183 mainDrawPrevY = ny;
185 XWindowAttributes xwa;
186 XGetWindowAttributes(sdampwin.display, sdampwin.window, &xwa);
187 XTranslateCoordinates(sdampwin.display, sdampwin.window, RootWindow(sdampwin.display, DefaultScreen(sdampwin.display)), xwa.x, xwa.y, &xwa.x, &xwa.y, &dummyw);
188 sdampwin.move(xwa.x+dx, xwa.y+dy);
190 if (sdplwin !is null && !sdplwin.closed) {
191 XGetWindowAttributes(sdplwin.display, sdplwin.window, &xwa);
192 XTranslateCoordinates(sdplwin.display, sdplwin.window, RootWindow(sdplwin.display, DefaultScreen(sdplwin.display)), xwa.x, xwa.y, &xwa.x, &xwa.y, &dummyw);
193 sdplwin.move(xwa.x+dx, xwa.y+dy);
196 flushGui();
198 if (event.type == MouseEventType.buttonReleased && event.button == MouseButton.left) mainDrag = false;
199 return;
201 if (!ampMain.onMouse(event)) {
203 if (event.type == MouseEventType.buttonPressed && event.button == MouseButton.left) {
204 if (ampMain.widgetAt(event.x, event.y) is null) {
205 flushGui();
206 Window dummyw;
207 mainDrag = true;
208 mainDrawPrevX = event.x*vbufEffScale;
209 mainDrawPrevY = event.y*vbufEffScale;
210 XTranslateCoordinates(sdampwin.display, sdampwin.window, RootWindow(sdampwin.display, DefaultScreen(sdampwin.display)), mainDrawPrevX, mainDrawPrevY, &mainDrawPrevX, &mainDrawPrevY, &dummyw);
215 glconPostScreenRebuild();
216 //sdwin.redrawOpenGlSceneNow();
220 sdampwin.handleCharEvent = delegate (dchar ch) {
224 if (!sdampwin.eventQueued!ScrollTitleEvent) sdampwin.postEvent(evScrollTitle);
228 // ////////////////////////////////////////////////////////////////////////// //
229 void createPListWindow () {
230 sdpyWindowClass = "AMPER_PLAYLIST";
232 sdplwin = new SimpleWindow(skinImgMain.width*vbufEffScale, skinImgMain.height*vbufEffScale, "Amper Playlist", OpenGlOptions.yes, Resizablity.allowResizing, WindowTypes.undecorated);
233 sdplwin.setMinSize(skinImgMain.width*vbufEffScale, skinImgMain.height*vbufEffScale);
234 sdplwin.setMaxSize(4096, 4096);
235 sdplwin.setResizeGranularity(5, 4);
237 static if (is(typeof(&sdplwin.closeQuery))) {
238 sdplwin.closeQuery = delegate () { /*concmd("quit"); glconPostDoConCommands();*/ };
241 sdplwin.redrawOpenGlScene = delegate () {
242 ampPList.onPaint();
245 sdplwin.visibleForTheFirstTime = delegate () {
246 vglRegisterWindow(sdplwin);
248 if (sdampwin !is null && !sdampwin.closed) {
249 switchToWindow(sdampwin);
250 flushGui();
251 Window dummyw;
252 XWindowAttributes xwa;
253 XGetWindowAttributes(sdampwin.display, sdampwin.window, &xwa);
254 XTranslateCoordinates(sdampwin.display, sdampwin.window, RootWindow(sdampwin.display, DefaultScreen(sdampwin.display)), xwa.x, xwa.y, &xwa.x, &xwa.y, &dummyw);
255 sdplwin.move(xwa.x, xwa.y+sdampwin.height);
256 flushGui();
262 // ////////////////////////////////////////////////////////////////////////// //
263 void main (string[] args) {
264 //vbNewScale = 2;
265 //vbufEffScale = 2;
266 glconShowKey = "M-Grave";
268 conRegVar!vbNewScale(1, 8, "v_scale", "window scale");
270 conProcessQueue(); // load config
271 conProcessArgs!true(args);
273 loadSkin();
275 ampPList.appendListItem(PListItem("Sonata Arctica -- Replica", "/mnt/muzax/wtf", 142));
276 ampPList.appendListItem(PListItem("Zonata -- Geronimo", "/mnt/muzax/wtf", 242));
278 foreach (immutable int idx; 3..42) {
279 import std.format : format;
280 ampPList.appendListItem(PListItem("song #%d".format(idx), "/mnt/muzax/wtf", 100+idx));
283 createAmpWindow();
284 createPListWindow();
285 flushGui();
287 sdampwin.eventLoop(0);
288 flushGui();
289 conProcessQueue(int.max/4);