3 CLASS(XonoticPlayList, XonoticListBox)
4 METHOD(XonoticPlayList, configureXonoticPlayList, void(entity))
5 ATTRIB(XonoticPlayList, rowsPerItem, float, 1)
6 METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector))
7 METHOD(XonoticPlayList, draw, void(entity))
8 METHOD(XonoticPlayList, drawListBoxItem, void(entity, float, vector, float))
9 METHOD(XonoticPlayList, stopSound, void(entity))
10 METHOD(XonoticPlayList, startSound, void(entity, float))
11 METHOD(XonoticPlayList, resumeSound, void(entity))
12 METHOD(XonoticPlayList, pauseSound, void(entity))
13 METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector))
14 METHOD(XonoticPlayList, keyDown, float(entity, float, float, float))
15 METHOD(XonoticPlayList, mouseDrag, float(entity, vector))
17 METHOD(XonoticPlayList, addToPlayList, void(entity, string))
18 METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity))
19 ATTRIB(XonoticPlayList, playingTrack, float, -1)
21 ATTRIB(XonoticPlayList, realFontSize, vector, '0 0 0')
22 ATTRIB(XonoticPlayList, columnNameOrigin, float, 0)
23 ATTRIB(XonoticPlayList, columnNameSize, float, 0)
24 ATTRIB(XonoticPlayList, columnNumberOrigin, float, 0)
25 ATTRIB(XonoticPlayList, columnNumberSize, float, 0)
26 ATTRIB(XonoticPlayList, realUpperMargin, float, 0)
27 ATTRIB(XonoticPlayList, origin, vector, '0 0 0')
28 ATTRIB(XonoticPlayList, itemAbsSize, vector, '0 0 0')
29 ENDCLASS(XonoticPlayList)
31 entity makeXonoticPlayList();
32 void PlayList_Remove(entity btn, entity me);
33 void PlayList_Remove_All(entity btn, entity me);
34 void StopSound_Click(entity btn, entity me);
35 void StartSound_Click(entity btn, entity me);
36 void PauseSound_Click(entity btn, entity me);
37 void PrevSound_Click(entity btn, entity me);
38 void NextSound_Click(entity btn, entity me);
43 entity makeXonoticPlayList()
46 me = NEW(XonoticPlayList);
47 me.configureXonoticPlayList(me);
51 void XonoticPlayList_configureXonoticPlayList(entity me)
53 me.nItems = tokenize_console(cvar_string("music_playlist_list0"));
54 me.configureXonoticListBox(me);
57 void XonoticPlayList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
59 me.itemAbsSize = '0 0 0';
60 SUPER(XonoticPlayList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
62 me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize.y * me.itemHeight));
63 me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize.x * (1 - me.controlWidth)));
64 me.realUpperMargin = 0.5 * (1 - me.realFontSize.y);
66 me.columnNumberOrigin = 0;
67 me.columnNumberSize = 3 * me.realFontSize.x;
69 me.columnNameOrigin = me.columnNumberSize + me.realFontSize.x;
70 me.columnNameSize = 1 - me.columnNameOrigin - me.realFontSize.x;
73 void XonoticPlayList_addToPlayList(entity me, string track)
75 me.nItems = tokenize_console(cvar_string("music_playlist_list0"));
78 cvar_set("music_playlist_list0", track);
82 for(i = 0; i < me.nItems; ++i)
85 return; // track is already in playlist
87 cvar_set("music_playlist_list0", strcat(cvar_string("music_playlist_list0"), " ", track));
90 void XonoticPlayList_removeSelectedFromPlayList(entity me)
94 me.nItems = tokenize_console(cvar_string("music_playlist_list0"));
97 for(i = 0; i < me.nItems; ++i)
99 if(i == me.selectedItem)
101 if(i == me.nItems - 1)
102 me.setSelected(me, me.selectedItem - 1);
103 if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999)
105 if(cvar("music_playlist_current0") == i)
106 cpt = true; // current playing track (we can't start next track here because startSound calls tokenize_console)
107 else if(cvar("music_playlist_current0") > i)
108 cvar_set("music_playlist_current0", ftos(cvar("music_playlist_current0") - 1));
112 s = strcat(s, " ", argv(i));
114 // we must stop the current playing track if it has been removed
115 // otherwise pause/play button will resume from another track
118 cvar_set("music_playlist_list0", "");
124 cvar_set("music_playlist_list0", substring(s, 1, strlen(s))); // remove initial space
126 me.startSound(me, 0);
130 void PlayList_Remove(entity btn, entity me)
132 me.removeSelectedFromPlayList(me);
135 void PlayList_Remove_All(entity btn, entity me)
137 cvar_set("music_playlist_list0", "");
142 float XonoticPlayList_mouseDrag(entity me, vector pos)
146 f = SUPER(XonoticPlayList).mouseDrag(me, pos);
148 if(me.pressed != 1) // don't change priority if the person is just scrolling
150 if(me.selectedItem != i)
152 cvar_set("music_playlist_list0", swapInPriorityList(cvar_string("music_playlist_list0"), me.selectedItem, i));
153 float c = cvar("music_playlist_current0");
155 cvar_set("music_playlist_current0", ftos(me.selectedItem));
156 else if(c == me.selectedItem)
157 cvar_set("music_playlist_current0", ftos(i));
164 void XonoticPlayList_draw(entity me)
166 me.nItems = tokenize_console(cvar_string("music_playlist_list0"));
167 if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999)
168 me.playingTrack = cvar("music_playlist_current0");
170 me.playingTrack = -1;
171 SUPER(XonoticPlayList).draw(me);
174 void XonoticPlayList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
178 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
180 if(i == me.playingTrack)
182 float f = cvar("music_playlist_sampleposition0");
183 if(f <= 0 || (((time * 2) & 1) && f > 0))
184 draw_Text(me.realUpperMargin * eY + (me.columnNumberOrigin + me.columnNumberSize) * eX, "\xE2\x96\xB6", me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
188 draw_CenterText(me.realUpperMargin * eY + (me.columnNumberOrigin + 0.5 * me.columnNumberSize) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
190 s = draw_TextShortenToWidth(argv(i), me.columnNameSize, 0, me.realFontSize);
191 draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
194 void XonoticPlayList_stopSound(entity me)
196 // STOP: list 0 is disabled by setting the index to -1
197 // we set sampleposition0 to 0 to forget the position that the engine saves in this frame (for this reason we need to wait a frame)
198 if(cvar("music_playlist_index") == 0 || cvar("music_playlist_index") == 999)
200 cvar_set("music_playlist_index", "-1");
201 localcmd("\nwait; music_playlist_sampleposition0 0\n");
202 localcmd("\ndefer 3 \"cd play $menu_cdtrack\"\n");
206 void StopSound_Click(entity btn, entity me)
211 void XonoticPlayList_startSound(entity me, float offset)
214 me.nItems = tokenize_console(cvar_string("music_playlist_list0"));
217 if(cvar("music_playlist_index") == -1)
219 f = bound(0, cvar("music_playlist_current0") + offset, me.nItems - 1);
220 if(f == cvar("music_playlist_current0"))
226 // if it was paused then resume
227 if(f == cvar("music_playlist_current0"))
228 if(cvar("music_playlist_index") == 999)
233 // if it was not paused then proceed with restart
236 // START: list 0 is disabled by setting the index to 999
237 // we set current0 to the selected track and sampleposition0 to 0 to forget the position that the engine saves in this frame (for this reason we need to wait a frame)
238 // then we switch back to list 0
239 cvar_set("music_playlist_index", "999");
240 cvar_set("music_playlist_current0", ftos(f));
241 localcmd("\nwait; music_playlist_sampleposition0 0; wait; music_playlist_index 0\n");
244 void StartSound_Click(entity btn, entity me)
246 me.startSound(me, 0);
249 void PrevSound_Click(entity btn, entity me)
251 me.startSound(me, -1);
254 void NextSound_Click(entity btn, entity me)
256 me.startSound(me, +1);
259 void XonoticPlayList_resumeSound(entity me)
261 // RESUME: list 0 is enabled by setting the index to 0
262 // (we reset sampleposition0 to 0 to mark the track as in playing back state)
263 if(cvar("music_playlist_index") == 999)
264 localcmd("\nmusic_playlist_index 0; wait; music_playlist_sampleposition0 0\n");
266 void XonoticPlayList_pauseSound(entity me)
268 // PAUSE: list 0 is disabled by setting the index to 999
269 // (we know the track is paused because the engine sets sampleposition0 to remember current position)
270 if(cvar("music_playlist_index") == 0)
271 localcmd("\nmusic_playlist_index 999\n");
272 else me.resumeSound(me);
275 void PauseSound_Click(entity btn, entity me)
280 void XonoticPlayList_doubleClickListBoxItem(entity me, float i, vector where)
282 me.startSound(me, 0);
285 float XonoticPlayList_keyDown(entity me, float scan, float ascii, float shift)
287 if(scan == K_ENTER || scan == K_KP_ENTER) {
288 me.startSound(me, 0);
291 else if(scan == K_SPACE) {
295 else if(scan == K_DEL || scan == K_KP_DEL || scan == K_BACKSPACE || scan == K_MOUSE3) {
296 me.removeSelectedFromPlayList(me);
300 return SUPER(XonoticPlayList).keyDown(me, scan, ascii, shift);