1#include "demolist.qh" 2 3#include "inputbox.qh" 4 5entity makeXonoticDemoList() 6{ 7 entity me; 8 me = NEW(XonoticDemoList); 9 me.configureXonoticDemoList(me); 10 return me; 11} 12 13void XonoticDemoList_configureXonoticDemoList(entity me) 14{ 15 me.configureXonoticListBox(me); 16 me.nItems = 0; 17} 18 19string XonoticDemoList_demoName(entity me, float i) 20{ 21 string s; 22 s = bufstr_get(me.listDemo, i); 23 24 if(substring(s, 0, 1) == "/") 25 s = substring(s, 1, strlen(s) - 1); // remove the first forward slash 26 27 return s; 28} 29 30// if subdir is true look in subdirectories too (1 level) 31void getDemos_for_ext(entity me, string ext, float subdir) 32{ 33 string s; 34 if (subdir) 35 s="demos/*/"; 36 else 37 s="demos/"; 38 if(me.filterString) 39 s=strcat(s, me.filterString, ext); 40 else 41 s=strcat(s, "*", ext); 42 43 float list, i, n; 44 list = search_begin(s, false, true); 45 if(list >= 0) 46 { 47 n = search_getsize(list); 48 for(i = 0; i < n; ++i) 49 { 50 s = search_getfilename(list, i); // get initial full file name 51 s = substring(s, 6, (strlen(s) - 6 - 4)); // remove "demos/" prefix and ".dem" suffix 52 s = strdecolorize(s); // remove any pre-existing colors 53 if(subdir) 54 { 55 s = strreplace("/", "^7/", s); // clear colors at the forward slash 56 s = strcat("/", rgb_to_hexcolor(SKINCOLOR_DEMOLIST_SUBDIR), s); // add a forward slash for sorting, then color 57 bufstr_add(me.listDemo, s, true); 58 } 59 else { bufstr_add(me.listDemo, s, true); } 60 } 61 search_end(list); 62 } 63 64 if (subdir) 65 getDemos_for_ext(me, ext, false); 66} 67 68void XonoticDemoList_getDemos(entity me) 69{ 70 if (me.listDemo >= 0) 71 buf_del(me.listDemo); 72 me.listDemo = buf_create(); 73 if (me.listDemo < 0) 74 { 75 me.nItems = 0; 76 return; 77 } 78 getDemos_for_ext(me, ".dem", true); 79 me.nItems = buf_getsize(me.listDemo); 80 if(me.nItems > 0) 81 buf_sort(me.listDemo, 128, false); 82} 83 84void XonoticDemoList_destroy(entity me) 85{ 86 if(me.nItems > 0) 87 buf_del(me.listDemo); 88} 89 90void XonoticDemoList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) 91{ 92 me.itemAbsSize = '0 0 0'; 93 SUPER(XonoticDemoList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); 94 95 me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize.y * me.itemHeight)); 96 me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize.x * (1 - me.controlWidth))); 97 me.realUpperMargin = 0.5 * (1 - me.realFontSize.y); 98 99 me.columnNameOrigin = me.realFontSize.x; 100 me.columnNameSize = 1 - 2 * me.realFontSize.x; 101} 102 103void XonoticDemoList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused) 104{ 105 string s; 106 if(isSelected) 107 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); 108 else if(isFocused) 109 { 110 me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED); 111 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha); 112 } 113 114 s = me.demoName(me,i); 115 s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); 116 draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 1); 117} 118 119void XonoticDemoList_showNotify(entity me) 120{ 121 me.getDemos(me); 122} 123 124void DemoList_Refresh_Click(entity btn, entity me) 125{ 126 me.getDemos(me); 127 me.setSelected(me, 0); //always select the first element after a list update 128} 129 130void DemoList_Filter_Change(entity box, entity me) 131{ 132 if(me.filterString) 133 strunzone(me.filterString); 134 135 if(box.text != "") 136 { 137 if (strstrofs(box.text, "*", 0) >= 0 || strstrofs(box.text, "?", 0) >= 0) 138 me.filterString = strzone(box.text); 139 else 140 me.filterString = strzone(strcat("*", box.text, "*")); 141 } 142 else 143 me.filterString = string_null; 144 145 me.getDemos(me); 146} 147 148void XonoticDemoList_startDemo(entity me) 149{ 150 string s; 151 s = me.demoName(me, me.selectedItem); 152 s = strdecolorize(s); 153 154 localcmd("playdemo \"demos/", s, ".dem\" \nwait \ntogglemenu\n"); 155} 156 157void XonoticDemoList_timeDemo(entity me) 158{ 159 string s; 160 s = me.demoName(me, me.selectedItem); 161 s = strdecolorize(s); 162 163 localcmd("timedemo \"demos/", s, ".dem\" \nwait \ntogglemenu\n"); 164} 165 166void DemoConfirm_ListClick_Check_Gamestatus(entity me) 167{ 168 if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, lets watch the demo 169 { 170 me.startDemo(me); 171 } 172 else // already in a match, player has to confirm 173 { 174 DialogOpenButton_Click_withCoords( 175 me, 176 main.demostartconfirmDialog, 177 boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size), 178 boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size) 179 ); 180 } 181} 182 183void XonoticDemoList_doubleClickListBoxItem(entity me, float i, vector where) 184{ 185 DemoConfirm_ListClick_Check_Gamestatus(me); 186} 187 188float XonoticDemoList_keyDown(entity me, float scan, float ascii, float shift) 189{ 190 if(scan == K_ENTER || scan == K_KP_ENTER) 191 { 192 DemoConfirm_ListClick_Check_Gamestatus(me); 193 return 1; 194 } 195 else 196 { 197 return SUPER(XonoticDemoList).keyDown(me, scan, ascii, shift); 198 } 199} 200