]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/xonotic/hudskinlist.qc
Header police
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / hudskinlist.qc
1 #include "hudskinlist.qh"
2 #ifndef HUDSKINLIST_H
3 #define HUDSKINLIST_H
4 #include "listbox.qc"
5 CLASS(XonoticHUDSkinList, XonoticListBox)
6         METHOD(XonoticHUDSkinList, configureXonoticHUDSkinList, void(entity));
7         ATTRIB(XonoticHUDSkinList, rowsPerItem, float, 1)
8         METHOD(XonoticHUDSkinList, resizeNotify, void(entity, vector, vector, vector, vector));
9         METHOD(XonoticHUDSkinList, draw, void(entity));
10         METHOD(XonoticHUDSkinList, drawListBoxItem, void(entity, int, vector, bool, bool));
11         METHOD(XonoticHUDSkinList, getHUDSkins, void(entity));
12         METHOD(XonoticHUDSkinList, setHUDSkin, void(entity));
13         METHOD(XonoticHUDSkinList, hudskinName, string(entity, float));
14         METHOD(XonoticHUDSkinList, hudskinPath, string(entity, float));
15         METHOD(XonoticHUDSkinList, hudskinTitle, string(entity, float));
16         METHOD(XonoticHUDSkinList, hudskinAuthor, string(entity, float));
17         METHOD(XonoticHUDSkinList, doubleClickListBoxItem, void(entity, float, vector));
18         METHOD(XonoticHUDSkinList, keyDown, float(entity, float, float, float));
19         METHOD(XonoticHUDSkinList, destroy, void(entity));
20         METHOD(XonoticHUDSkinList, showNotify, void(entity));
21
22         ATTRIB(XonoticHUDSkinList, listHUDSkin, float, -1)
23         ATTRIB(XonoticHUDSkinList, realFontSize, vector, '0 0 0')
24         ATTRIB(XonoticHUDSkinList, columnNameOrigin, float, 0)
25         ATTRIB(XonoticHUDSkinList, columnNameSize, float, 0)
26         ATTRIB(XonoticHUDSkinList, realUpperMargin, float, 0)
27         ATTRIB(XonoticHUDSkinList, origin, vector, '0 0 0')
28         ATTRIB(XonoticHUDSkinList, itemAbsSize, vector, '0 0 0')
29
30         ATTRIB(XonoticHUDSkinList, filterString, string, string_null)
31         ATTRIB(XonoticHUDSkinList, delayedRefreshTime, float, 0)
32         ATTRIB(XonoticHUDSkinList, savedName, string, string_null)
33 ENDCLASS(XonoticHUDSkinList)
34
35 #ifndef IMPLEMENTATION
36 // public:
37 entity hudskinlist;
38 entity makeXonoticHUDSkinList();
39 void SaveHUDSkin_Click(entity btn, entity me);
40 void SetHUDSkin_Click(entity btn, entity me);
41 #endif
42 void HUDSkinList_Refresh_Click(entity btn, entity me);
43 void HUDSkinList_Filter_Change(entity box, entity me);
44 void HUDSkinList_SavedName_Change(entity box, entity me);
45 #endif
46
47 #ifdef IMPLEMENTATION
48
49 entity makeXonoticHUDSkinList()
50 {
51         entity me;
52         me = NEW(XonoticHUDSkinList);
53         me.configureXonoticHUDSkinList(me);
54         return me;
55 }
56
57 void XonoticHUDSkinList_configureXonoticHUDSkinList(entity me)
58 {
59         me.configureXonoticListBox(me);
60         me.nItems = 0;
61 }
62
63 const float HUDSKINPARM_NAME = 0;
64 const float HUDSKINPARM_PATH = 1;
65 const float HUDSKINPARM_TITLE = 2;
66 const float HUDSKINPARM_AUTHOR = 3;
67 const float HUDSKINPARM_COUNT = 4;
68 string XonoticHUDSkinList_hudskinName(entity me, float i)
69 {
70         return bufstr_get(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_NAME);
71 }
72 string XonoticHUDSkinList_hudskinPath(entity me, float i)
73 {
74         return bufstr_get(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_PATH);
75 }
76 string XonoticHUDSkinList_hudskinTitle(entity me, float i)
77 {
78         return bufstr_get(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_TITLE);
79 }
80 string XonoticHUDSkinList_hudskinAuthor(entity me, float i)
81 {
82         return bufstr_get(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_AUTHOR);
83 }
84
85 // subdir can be a regular expression
86 void getHUDSkinFiles(entity me, int sortbuf, string subdir)
87 {
88         string s;
89         if(me.filterString)
90                 s = me.filterString;
91         else
92                 s = "*";
93         s = strcat(subdir, "hud_", s, ".cfg");
94
95         int list = search_begin(s, false, true);
96         if(list >= 0)
97         {
98                 int n = search_getsize(list);
99                 for(int i = 0; i < n; ++i)
100                 {
101                         string s = search_getfilename(list, i);
102                         int subdir_ofs = strstrofs(s, "/", 0);
103                         if(subdir_ofs >= 0)
104                         {
105                                 int ofs = subdir_ofs;
106                                 while(ofs != -1)
107                                 {
108                                         subdir_ofs = ofs;
109                                         ofs = strstrofs(s, "/", subdir_ofs + 1);
110                                 }
111                         }
112
113                         if(subdir_ofs == -1)
114                                 bufstr_add(sortbuf, s, true);
115                         else
116                         {
117                                 subdir = substring(s, 0, subdir_ofs);
118                                 string filename = substring(s, subdir_ofs + 1, -1);
119                                 // invert path and filename position so we can sort sortbuf by filename
120                                 bufstr_add(sortbuf, strcat(filename, "/", subdir), true);
121                         }
122                 }
123                 search_end(list);
124         }
125 }
126
127 void getAllHUDSkins(entity me, int sortbuf)
128 {
129         int n = buf_getsize(sortbuf);
130         for(int i = 0; i < n; ++i)
131         {
132                 string entry = bufstr_get(sortbuf, i);
133                 int ofs = strstrofs(entry, "/", 0);
134                 string s = "";
135                 string filename = entry;
136                 if(ofs >= 0)
137                 {
138                         s = substring(entry, ofs + 1, -1); // skip initial "/"
139                         s = strcat(s, "/");
140                         bufstr_set(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_PATH, s);
141                         filename = strcat(s, substring(entry, 0, ofs));
142                 }
143                 else
144                         ofs = strlen(entry);
145                 s = substring(entry, 4, ofs - 4 - 4); // remove "hud_" prefix and ".cfg" suffix
146                 bufstr_set(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_NAME, s);
147
148                 int fh = fopen(filename, FILE_READ);
149                 if(fh < 0)
150                         continue;
151                 while((s = fgets(fh)) && substring(s, 0, 2) == "//")
152                 {
153                         tokenize_console(substring(s, 2, -1));
154                         if(argv(0) == "title")
155                                 bufstr_set(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_TITLE, argv(1));
156                         else if(argv(0) == "author")
157                                 bufstr_set(me.listHUDSkin, i * HUDSKINPARM_COUNT + HUDSKINPARM_AUTHOR, argv(1));
158                 }
159                 fclose(fh);
160         }
161 }
162
163 void XonoticHUDSkinList_getHUDSkins(entity me)
164 {
165         if (me.listHUDSkin >= 0)
166                 buf_del(me.listHUDSkin);
167         me.listHUDSkin = buf_create();
168         if (me.listHUDSkin < 0)
169         {
170                 me.nItems = 0;
171                 return;
172         }
173         int sortbuf = buf_create();
174         getHUDSkinFiles(me, sortbuf, "");
175         getHUDSkinFiles(me, sortbuf, "data/");
176         buf_sort(sortbuf, 128, 0);
177         getAllHUDSkins(me, sortbuf);
178         buf_del(sortbuf);
179         me.nItems = buf_getsize(me.listHUDSkin) / HUDSKINPARM_COUNT;
180 }
181
182 void XonoticHUDSkinList_destroy(entity me)
183 {
184         if(me.nItems > 0)
185                 buf_del(me.listHUDSkin);
186 }
187
188 void XonoticHUDSkinList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
189 {
190         me.itemAbsSize = '0 0 0';
191         SUPER(XonoticHUDSkinList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
192
193         me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize.y * me.itemHeight));
194         me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize.x * (1 - me.controlWidth)));
195         me.realUpperMargin = 0.5 * (1 - me.realFontSize.y);
196
197         me.columnNameOrigin = me.realFontSize.x;
198         me.columnNameSize = 1 - 2 * me.realFontSize.x;
199 }
200
201 void XonoticHUDSkinList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
202 {
203         string s, s2;
204         if(isSelected)
205                 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
206         else if(isFocused)
207         {
208                 me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
209                 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
210         }
211
212         s = me.hudskinTitle(me, i);
213         if(s == "")
214                 s = me.hudskinName(me, i);
215         s2 = me.hudskinAuthor(me, i);
216         if(s2 != "")
217                 s = strcat(s, " (", s2, ")");
218         s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
219         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);
220 }
221
222 void XonoticHUDSkinList_showNotify(entity me)
223 {
224         me.getHUDSkins(me);
225 }
226
227 void HUDSkinList_Refresh_Click(entity btn, entity me)
228 {
229         me.getHUDSkins(me);
230         me.setSelected(me, 0); //always select the first element after a list update
231 }
232
233 void HUDSkinList_SavedName_Change(entity box, entity me)
234 {
235         if(me.savedName)
236                 strunzone(me.savedName);
237
238         if(box.text != "")
239                 me.savedName = strzone(box.text);
240         else
241                 me.savedName = string_null;
242 }
243
244 void HUDSkinList_Filter_Change(entity box, entity me)
245 {
246         if(me.filterString)
247                 strunzone(me.filterString);
248
249         if(box.text != "")
250         {
251                 if (strstrofs(box.text, "*", 0) >= 0 || strstrofs(box.text, "?", 0) >= 0)
252                         me.filterString = strzone(box.text);
253                 else
254                         me.filterString = strzone(strcat("*", box.text, "*"));
255         }
256         else
257                 me.filterString = string_null;
258
259         me.getHUDSkins(me);
260 }
261
262 void SaveHUDSkin_Click(entity btn, entity me)
263 {
264         string s = me.savedName;
265         if(s == "")
266                 s = "myconfig";
267         localcmd(sprintf("hud save \"%s\"\n", s));
268         me.delayedRefreshTime = time + 1;
269 }
270
271 void XonoticHUDSkinList_draw(entity me)
272 {
273         if(me.delayedRefreshTime > 0 && me.delayedRefreshTime < time)
274         {
275                 HUDSkinList_Refresh_Click(NULL, me);
276                 me.delayedRefreshTime = 0;
277         }
278         SUPER(XonoticHUDSkinList).draw(me);
279 }
280
281 void XonoticHUDSkinList_setHUDSkin(entity me)
282 {
283         string cfg = strcat(me.hudskinPath(me, me.selectedItem), "hud_", me.hudskinName(me, me.selectedItem), ".cfg");
284         localcmd("exec \"", cfg, "\"\n");
285 }
286
287 void SetHUDSkin_Click(entity btn, entity me)
288 {
289         me.setHUDSkin(me);
290 }
291
292 void XonoticHUDSkinList_doubleClickListBoxItem(entity me, float i, vector where)
293 {
294         m_play_click_sound(MENU_SOUND_EXECUTE);
295         me.setHUDSkin(me);
296 }
297
298 float XonoticHUDSkinList_keyDown(entity me, float scan, float ascii, float shift)
299 {
300         if(scan == K_ENTER || scan == K_KP_ENTER)
301         {
302                 me.setHUDSkin(me);
303                 return 1;
304         }
305         else
306         {
307                 return SUPER(XonoticHUDSkinList).keyDown(me, scan, ascii, shift);
308         }
309 }
310 #endif
311