]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud_config.qc
Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud_config.qc
1 #define HUD_Write(s) fputs(fh, s)
2 // q: quoted, n: not quoted
3 #define HUD_Write_Cvar_n(cvar) HUD_Write(strcat("seta ", cvar, " ", cvar_string(cvar), "\n"))
4 #define HUD_Write_Cvar_q(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n"))
5 #define HUD_Write_PanelCvar_n(cvar_suf) HUD_Write_Cvar_n(strcat("hud_panel_", panel_name, cvar_suf))
6 #define HUD_Write_PanelCvar_q(cvar_suf) HUD_Write_Cvar_q(strcat("hud_panel_", panel_name, cvar_suf))
7 // Save the config
8 void HUD_Panel_ExportCfg(string cfgname)
9 {
10         float fh;
11         string filename = strcat("hud_", autocvar_hud_skin, "_", cfgname, ".cfg");
12         fh = fopen(filename, FILE_WRITE);
13         if(fh >= 0)
14         {
15                 HUD_Write_Cvar_q("hud_skin");
16                 HUD_Write_Cvar_q("hud_panel_bg");
17                 HUD_Write_Cvar_q("hud_panel_bg_color");
18                 HUD_Write_Cvar_q("hud_panel_bg_color_team");
19                 HUD_Write_Cvar_q("hud_panel_bg_alpha");
20                 HUD_Write_Cvar_q("hud_panel_bg_border");
21                 HUD_Write_Cvar_q("hud_panel_bg_padding");
22                 HUD_Write_Cvar_q("hud_panel_fg_alpha");
23                 HUD_Write("\n");
24
25                 HUD_Write_Cvar_q("hud_dock");
26                 HUD_Write_Cvar_q("hud_dock_color");
27                 HUD_Write_Cvar_q("hud_dock_color_team");
28                 HUD_Write_Cvar_q("hud_dock_alpha");
29                 HUD_Write("\n");
30
31                 HUD_Write_Cvar_q("hud_progressbar_alpha");
32                 HUD_Write_Cvar_q("hud_progressbar_strength_color");
33                 HUD_Write_Cvar_q("hud_progressbar_shield_color");
34                 HUD_Write_Cvar_q("hud_progressbar_health_color");
35                 HUD_Write_Cvar_q("hud_progressbar_armor_color");
36                 HUD_Write_Cvar_q("hud_progressbar_fuel_color");
37                 HUD_Write_Cvar_q("hud_progressbar_nexball_color");
38                 HUD_Write_Cvar_q("hud_progressbar_speed_color");
39                 HUD_Write_Cvar_q("hud_progressbar_acceleration_color");
40                 HUD_Write_Cvar_q("hud_progressbar_acceleration_neg_color");
41                 HUD_Write("\n");
42
43                 HUD_Write_Cvar_q("_hud_panelorder");
44                 HUD_Write("\n");
45
46                 HUD_Write_Cvar_q("hud_configure_grid");
47                 HUD_Write_Cvar_q("hud_configure_grid_xsize");
48                 HUD_Write_Cvar_q("hud_configure_grid_ysize");
49                 HUD_Write("\n");
50
51                 // common cvars for all panels
52                 float i;
53                 for (i = 0; i < HUD_PANEL_NUM; ++i)
54                 {
55                         HUD_Panel_GetName(i);
56
57                         HUD_Write_PanelCvar_n("");
58                         HUD_Write_PanelCvar_q("_pos");
59                         HUD_Write_PanelCvar_q("_size");
60                         HUD_Write_PanelCvar_q("_bg");
61                         HUD_Write_PanelCvar_q("_bg_color");
62                         HUD_Write_PanelCvar_q("_bg_color_team");
63                         HUD_Write_PanelCvar_q("_bg_alpha");
64                         HUD_Write_PanelCvar_q("_bg_border");
65                         HUD_Write_PanelCvar_q("_bg_padding");
66                         switch(i) {
67                                 case HUD_PANEL_WEAPONS:
68                                         HUD_Write_PanelCvar_q("_accuracy");
69                                         HUD_Write_PanelCvar_q("_label");
70                                         HUD_Write_PanelCvar_q("_complainbubble");
71                                         HUD_Write_PanelCvar_q("_complainbubble_padding");
72                                         HUD_Write_PanelCvar_q("_complainbubble_time");
73                                         HUD_Write_PanelCvar_q("_complainbubble_fadetime");
74                                         HUD_Write_PanelCvar_q("_complainbubble_color_outofammo");
75                                         HUD_Write_PanelCvar_q("_complainbubble_color_donthave");
76                                         HUD_Write_PanelCvar_q("_complainbubble_color_unavailable");
77                                         HUD_Write_PanelCvar_q("_ammo");
78                                         HUD_Write_PanelCvar_q("_ammo_color");
79                                         HUD_Write_PanelCvar_q("_ammo_alpha");
80                                         HUD_Write_PanelCvar_q("_aspect");
81                                         HUD_Write_PanelCvar_q("_timeout");
82                                         HUD_Write_PanelCvar_q("_timeout_effect");
83                                         HUD_Write_PanelCvar_q("_onlyowned");
84                                         break;
85                                 case HUD_PANEL_AMMO:
86                                         HUD_Write_PanelCvar_q("_onlycurrent");
87                                         HUD_Write_PanelCvar_q("_iconalign");
88                                         HUD_Write_PanelCvar_q("_progressbar");
89                                         HUD_Write_PanelCvar_q("_progressbar_name");
90                                         HUD_Write_PanelCvar_q("_progressbar_xoffset");
91                                         HUD_Write_PanelCvar_q("_text");
92                                         break;
93                                 case HUD_PANEL_POWERUPS:
94                                         HUD_Write_PanelCvar_q("_flip");
95                                         HUD_Write_PanelCvar_q("_iconalign");
96                                         HUD_Write_PanelCvar_q("_baralign");
97                                         HUD_Write_PanelCvar_q("_progressbar");
98                                         HUD_Write_PanelCvar_q("_progressbar_strength");
99                                         HUD_Write_PanelCvar_q("_progressbar_shield");
100                                         HUD_Write_PanelCvar_q("_text");
101                                         break;
102                                 case HUD_PANEL_HEALTHARMOR:
103                                         HUD_Write_PanelCvar_q("_flip");
104                                         HUD_Write_PanelCvar_q("_iconalign");
105                                         HUD_Write_PanelCvar_q("_baralign");
106                                         HUD_Write_PanelCvar_q("_progressbar");
107                                         HUD_Write_PanelCvar_q("_progressbar_health");
108                                         HUD_Write_PanelCvar_q("_progressbar_armor");
109                                         HUD_Write_PanelCvar_q("_progressbar_gfx");
110                                         HUD_Write_PanelCvar_q("_progressbar_gfx_smooth");
111                                         HUD_Write_PanelCvar_q("_text");
112                                         break;
113                                 case HUD_PANEL_NOTIFY:
114                                         HUD_Write_PanelCvar_q("_flip");
115                                         HUD_Write_PanelCvar_q("_fontsize");
116                                         HUD_Write_PanelCvar_q("_print");
117                                         HUD_Write_PanelCvar_q("_time");
118                                         HUD_Write_PanelCvar_q("_fadetime");
119                                         break;
120                                 case HUD_PANEL_TIMER:
121                                         HUD_Write_PanelCvar_q("_increment");
122                                         break;
123                                 case HUD_PANEL_RADAR:
124                                         HUD_Write_PanelCvar_q("_foreground_alpha");
125                                         HUD_Write_PanelCvar_q("_rotation");
126                                         HUD_Write_PanelCvar_q("_zoommode");
127                                         HUD_Write_PanelCvar_q("_scale");
128                                         HUD_Write_PanelCvar_q("_maximized_scale");
129                                         HUD_Write_PanelCvar_q("_maximized_size");
130                                         break;
131                                 case HUD_PANEL_SCORE:
132                                         HUD_Write_PanelCvar_q("_rankings");
133                                         break;
134                                 case HUD_PANEL_VOTE:
135                                         HUD_Write_PanelCvar_q("_alreadyvoted_alpha");
136                                         break;
137                                 case HUD_PANEL_MODICONS:
138                                         HUD_Write_PanelCvar_q("_dom_layout");
139                                         break;
140                                 case HUD_PANEL_PRESSEDKEYS:
141                                         HUD_Write_PanelCvar_q("_aspect");
142                                         break;
143                                 case HUD_PANEL_ENGINEINFO:
144                                         HUD_Write_PanelCvar_q("_framecounter_time");
145                                         HUD_Write_PanelCvar_q("_framecounter_decimals");
146                                         break;
147                                 case HUD_PANEL_INFOMESSAGES:
148                                         HUD_Write_PanelCvar_q("_flip");
149                                         break;
150                                 case HUD_PANEL_PHYSICS:
151                                         HUD_Write_PanelCvar_q("_speed_unit");
152                                         HUD_Write_PanelCvar_q("_speed_unit_show");
153                                         HUD_Write_PanelCvar_q("_speed_max");
154                                         HUD_Write_PanelCvar_q("_speed_vertical");
155                                         HUD_Write_PanelCvar_q("_topspeed");
156                                         HUD_Write_PanelCvar_q("_topspeed_time");
157                                         HUD_Write_PanelCvar_q("_acceleration_max");
158                                         HUD_Write_PanelCvar_q("_acceleration_vertical");
159                                         HUD_Write_PanelCvar_q("_flip");
160                                         HUD_Write_PanelCvar_q("_baralign");
161                                         HUD_Write_PanelCvar_q("_progressbar");
162                                         HUD_Write_PanelCvar_q("_acceleration_mode");
163                                         HUD_Write_PanelCvar_q("_text");
164                                         break;
165                                 case HUD_PANEL_CENTERPRINT:
166                                         HUD_Write_PanelCvar_q("_align");
167                                         HUD_Write_PanelCvar_q("_flip");
168                                         HUD_Write_PanelCvar_q("_fontscale");
169                                         HUD_Write_PanelCvar_q("_time");
170                                         HUD_Write_PanelCvar_q("_fade_in");
171                                         HUD_Write_PanelCvar_q("_fade_out");
172                                         HUD_Write_PanelCvar_q("_fade_subsequent");
173                                         HUD_Write_PanelCvar_q("_fade_subsequent_passone");
174                                         HUD_Write_PanelCvar_q("_fade_subsequent_passone_minalpha");
175                                         HUD_Write_PanelCvar_q("_fade_subsequent_passtwo");
176                                         HUD_Write_PanelCvar_q("_fade_subsequent_passtwo_minalpha");
177                                         HUD_Write_PanelCvar_q("_fade_subsequent_minfontsize");
178                                         HUD_Write_PanelCvar_q("_fade_minfontsize");
179                                         break;
180                         }
181                         HUD_Write("\n");
182                 }
183                 HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated
184
185                 print(sprintf(_("^2Successfully exported to %s! (Note: It's saved in data/data/)\n"), filename));
186                 fclose(fh);
187         }
188         else
189                 print(sprintf(_("^1Couldn't write to %s\n"), filename));
190 }
191
192 void HUD_Configure_Exit_Force()
193 {
194         if (menu_enabled)
195         {
196                 menu_enabled = 0;
197                 localcmd("togglemenu\n");
198         }
199         cvar_set("_hud_configure", "0");
200 }
201
202 // check if move will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector
203 vector HUD_Panel_CheckMove(vector myPos, vector mySize)
204 {
205         float i;
206         float myCenter_x, myCenter_y, targCenter_x, targCenter_y;
207         vector myTarget;
208         myTarget = myPos;
209
210         for (i = 0; i < HUD_PANEL_NUM; ++i) {
211                 if(i == highlightedPanel || !panel_enabled)
212                         continue;
213
214                 HUD_Panel_UpdatePosSizeForId(i);
215
216                 panel_pos -= '1 1 0' * panel_bg_border;
217                 panel_size += '2 2 0' * panel_bg_border;
218
219                 if(myPos_y + mySize_y < panel_pos_y)
220                         continue;
221                 if(myPos_y > panel_pos_y + panel_size_y)
222                         continue;
223
224                 if(myPos_x + mySize_x < panel_pos_x)
225                         continue;
226                 if(myPos_x > panel_pos_x + panel_size_x)
227                         continue;
228
229                 // OK, there IS a collision.
230
231                 myCenter_x = myPos_x + 0.5 * mySize_x;
232                 myCenter_y = myPos_y + 0.5 * mySize_y;
233
234                 targCenter_x = panel_pos_x + 0.5 * panel_size_x;
235                 targCenter_y = panel_pos_y + 0.5 * panel_size_y;
236
237                 if(myCenter_x < targCenter_x && myCenter_y < targCenter_y) // top left (of the target panel)
238                 {
239                         if(myPos_x + mySize_x - panel_pos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side
240                                 myTarget_x = panel_pos_x - mySize_x;
241                         else // push it upwards
242                                 myTarget_y = panel_pos_y - mySize_y;
243                 }
244                 else if(myCenter_x > targCenter_x && myCenter_y < targCenter_y) // top right
245                 {
246                         if(panel_pos_x + panel_size_x - myPos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side
247                                 myTarget_x = panel_pos_x + panel_size_x;
248                         else // push it upwards
249                                 myTarget_y = panel_pos_y - mySize_y;
250                 }
251                 else if(myCenter_x < targCenter_x && myCenter_y > targCenter_y) // bottom left
252                 {
253                         if(myPos_x + mySize_x - panel_pos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side
254                                 myTarget_x = panel_pos_x - mySize_x;
255                         else // push it downwards
256                                 myTarget_y = panel_pos_y + panel_size_y;
257                 }
258                 else if(myCenter_x > targCenter_x && myCenter_y > targCenter_y) // bottom right
259                 {
260                         if(panel_pos_x + panel_size_x - myPos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side
261                                 myTarget_x = panel_pos_x + panel_size_x;
262                         else // push it downwards
263                                 myTarget_y = panel_pos_y + panel_size_y;
264                 }
265                 //if(cvar("hud_configure_checkcollisions_debug"))
266                         //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL);
267         }
268
269         return myTarget;
270 }
271
272 void HUD_Panel_SetPos(vector pos)
273 {
274         HUD_Panel_UpdatePosSizeForId(highlightedPanel);
275         vector mySize;
276         mySize = panel_size;
277
278         //if(cvar("hud_configure_checkcollisions_debug"))
279                 //drawfill(pos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL);
280
281         if(autocvar_hud_configure_grid)
282         {
283                 pos_x = floor((pos_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x;
284                 pos_y = floor((pos_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y;
285         }
286
287         if(hud_configure_checkcollisions)
288                 pos = HUD_Panel_CheckMove(pos, mySize);
289
290         pos_x = bound(0, pos_x, vid_conwidth - mySize_x);
291         pos_y = bound(0, pos_y, vid_conheight - mySize_y);
292
293         string s;
294         s = strcat(ftos(pos_x/vid_conwidth), " ", ftos(pos_y/vid_conheight));
295
296         HUD_Panel_GetName(highlightedPanel);
297         cvar_set(strcat("hud_panel_", panel_name, "_pos"), s);
298 }
299
300 // check if resize will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector
301 vector HUD_Panel_CheckResize(vector mySize, vector resizeorigin) {
302         float i;
303
304         vector targEndPos;
305
306         float dist_x, dist_y;
307         float ratio;
308         ratio = mySize_x/mySize_y;
309
310         for (i = 0; i < HUD_PANEL_NUM; ++i) {
311                 if(i == highlightedPanel || !panel_enabled)
312                         continue;
313
314                 HUD_Panel_UpdatePosSizeForId(i);
315
316                 panel_pos -= '1 1 0' * panel_bg_border;
317                 panel_size += '2 2 0' * panel_bg_border;
318
319                 targEndPos = panel_pos + panel_size;
320
321                 // resizeorigin is WITHIN target panel, just abort any collision testing against that particular panel to produce expected behaviour!
322                 if(resizeorigin_x > panel_pos_x && resizeorigin_x < targEndPos_x && resizeorigin_y > panel_pos_y && resizeorigin_y < targEndPos_y)
323                         continue;
324
325                 if (resizeCorner == 1)
326                 {
327                         // check if this panel is on our way
328                         if (resizeorigin_x <= panel_pos_x)
329                                 continue;
330                         if (resizeorigin_y <= panel_pos_y)
331                                 continue;
332                         if (targEndPos_x <= resizeorigin_x - mySize_x)
333                                 continue;
334                         if (targEndPos_y <= resizeorigin_y - mySize_y)
335                                 continue;
336
337                         // there is a collision:
338                         // detect which side of the panel we are facing is actually limiting the resizing
339                         // (which side the resize direction finds for first) and reduce the size up to there
340                         //
341                         // dist is the distance between resizeorigin and the "analogous" point of the panel
342                         // in this case between resizeorigin (bottom-right point) and the bottom-right point of the panel
343                         dist_x = resizeorigin_x - targEndPos_x;
344                         dist_y = resizeorigin_y - targEndPos_y;
345                         if (dist_y <= 0 || dist_x / dist_y > ratio)
346                                 mySize_x = min(mySize_x, dist_x);
347                         else
348                                 mySize_y = min(mySize_y, dist_y);
349                 }
350                 else if (resizeCorner == 2)
351                 {
352                         if (resizeorigin_x >= targEndPos_x)
353                                 continue;
354                         if (resizeorigin_y <= panel_pos_y)
355                                 continue;
356                         if (panel_pos_x >= resizeorigin_x + mySize_x)
357                                 continue;
358                         if (targEndPos_y <= resizeorigin_y - mySize_y)
359                                 continue;
360
361                         dist_x = panel_pos_x - resizeorigin_x;
362                         dist_y = resizeorigin_y - targEndPos_y;
363                         if (dist_y <= 0 || dist_x / dist_y > ratio)
364                                 mySize_x = min(mySize_x, dist_x);
365                         else
366                                 mySize_y = min(mySize_y, dist_y);
367                 }
368                 else if (resizeCorner == 3)
369                 {
370                         if (resizeorigin_x <= panel_pos_x)
371                                 continue;
372                         if (resizeorigin_y >= targEndPos_y)
373                                 continue;
374                         if (targEndPos_x <= resizeorigin_x - mySize_x)
375                                 continue;
376                         if (panel_pos_y >= resizeorigin_y + mySize_y)
377                                 continue;
378
379                         dist_x = resizeorigin_x - targEndPos_x;
380                         dist_y = panel_pos_y - resizeorigin_y;
381                         if (dist_y <= 0 || dist_x / dist_y > ratio)
382                                 mySize_x = min(mySize_x, dist_x);
383                         else
384                                 mySize_y = min(mySize_y, dist_y);
385                 }
386                 else if (resizeCorner == 4)
387                 {
388                         if (resizeorigin_x >= targEndPos_x)
389                                 continue;
390                         if (resizeorigin_y >= targEndPos_y)
391                                 continue;
392                         if (panel_pos_x >= resizeorigin_x + mySize_x)
393                                 continue;
394                         if (panel_pos_y >= resizeorigin_y + mySize_y)
395                                 continue;
396
397                         dist_x = panel_pos_x - resizeorigin_x;
398                         dist_y = panel_pos_y - resizeorigin_y;
399                         if (dist_y <= 0 || dist_x / dist_y > ratio)
400                                 mySize_x = min(mySize_x, dist_x);
401                         else
402                                 mySize_y = min(mySize_y, dist_y);
403                 }
404                 //if(cvar("hud_configure_checkcollisions_debug"))
405                         //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL);
406         }
407
408         return mySize;
409 }
410
411 void HUD_Panel_SetPosSize(vector mySize)
412 {
413         HUD_Panel_UpdatePosSizeForId(highlightedPanel);
414         vector resizeorigin;
415         resizeorigin = panel_click_resizeorigin;
416         local noref vector myPos; // fteqcc sucks
417
418         // minimum panel size cap
419         mySize_x = max(0.025 * vid_conwidth, mySize_x);
420         mySize_y = max(0.025 * vid_conheight, mySize_y);
421
422         if(highlightedPanel == HUD_PANEL_CHAT) // some panels have their own restrictions, like the chat panel (which actually only moves the engine chat print around). Looks bad if it's too small.
423         {
424                 mySize_x = max(17 * autocvar_con_chatsize, mySize_x);
425                 mySize_y = max(2 * autocvar_con_chatsize + 2 * panel_bg_padding, mySize_y);
426         }
427
428         // collision testing|
429         // -----------------+
430
431         // we need to know pos at this stage, but it might still change later if we hit a screen edge/other panel (?)
432         if(resizeCorner == 1) {
433                 myPos_x = resizeorigin_x - mySize_x;
434                 myPos_y = resizeorigin_y - mySize_y;
435         } else if(resizeCorner == 2) {
436                 myPos_x = resizeorigin_x;
437                 myPos_y = resizeorigin_y - mySize_y;
438         } else if(resizeCorner == 3) {
439                 myPos_x = resizeorigin_x - mySize_x;
440                 myPos_y = resizeorigin_y;
441         } else { // resizeCorner == 4
442                 myPos_x = resizeorigin_x;
443                 myPos_y = resizeorigin_y;
444         }
445
446         // left/top screen edges
447         if(myPos_x < 0)
448                 mySize_x = mySize_x + myPos_x;
449         if(myPos_y < 0)
450                 mySize_y = mySize_y + myPos_y;
451
452         // bottom/right screen edges
453         if(myPos_x + mySize_x > vid_conwidth)
454                 mySize_x = vid_conwidth - myPos_x;
455         if(myPos_y + mySize_y > vid_conheight)
456                 mySize_y = vid_conheight - myPos_y;
457
458         //if(cvar("hud_configure_checkcollisions_debug"))
459                 //drawfill(myPos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL);
460
461         // before checkresize, otherwise panel can be snapped partially inside another panel or panel aspect ratio can be broken
462         if(autocvar_hud_configure_grid)
463         {
464                 mySize_x = floor((mySize_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x;
465                 mySize_y = floor((mySize_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y;
466         }
467
468         if(hud_configure_checkcollisions)
469                 mySize = HUD_Panel_CheckResize(mySize, resizeorigin);
470
471         // minimum panel size cap, do this once more so we NEVER EVER EVER have a panel smaller than this, JUST IN CASE above code still makes the panel eg negative (impossible to resize back without changing cvars manually then)
472         mySize_x = max(0.025 * vid_conwidth, mySize_x);
473         mySize_y = max(0.025 * vid_conheight, mySize_y);
474
475         // do another pos check, as size might have changed by now
476         if(resizeCorner == 1) {
477                 myPos_x = resizeorigin_x - mySize_x;
478                 myPos_y = resizeorigin_y - mySize_y;
479         } else if(resizeCorner == 2) {
480                 myPos_x = resizeorigin_x;
481                 myPos_y = resizeorigin_y - mySize_y;
482         } else if(resizeCorner == 3) {
483                 myPos_x = resizeorigin_x - mySize_x;
484                 myPos_y = resizeorigin_y;
485         } else { // resizeCorner == 4
486                 myPos_x = resizeorigin_x;
487                 myPos_y = resizeorigin_y;
488         }
489
490         //if(cvar("hud_configure_checkcollisions_debug"))
491                 //drawfill(myPos, mySize, '0 1 0', .3, DRAWFLAG_NORMAL);
492
493         HUD_Panel_GetName(highlightedPanel);
494         string s;
495         s = strcat(ftos(mySize_x/vid_conwidth), " ", ftos(mySize_y/vid_conheight));
496         cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
497
498         s = strcat(ftos(myPos_x/vid_conwidth), " ", ftos(myPos_y/vid_conheight));
499         cvar_set(strcat("hud_panel_", panel_name, "_pos"), s);
500 }
501
502 float pressed_key_time;
503 vector highlightedPanel_initial_pos, highlightedPanel_initial_size;
504 void HUD_Panel_Arrow_Action(float nPrimary)
505 {
506         if (highlightedPanel == -1)
507                 return;
508
509         hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
510
511         float step;
512         if(autocvar_hud_configure_grid)
513         {
514                 if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW)
515                 {
516                         if (hudShiftState & S_SHIFT)
517                                 step = hud_configure_realGridSize_y;
518                         else
519                                 step = 2 * hud_configure_realGridSize_y;
520                 }
521                 else
522                 {
523                         if (hudShiftState & S_SHIFT)
524                                 step = hud_configure_realGridSize_x;
525                         else
526                                 step = 2 * hud_configure_realGridSize_x;
527                 }
528         }
529         else
530         {
531                 if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW)
532                         step = vid_conheight;
533                 else
534                         step = vid_conwidth;
535                 if (hudShiftState & S_SHIFT)
536                         step = (step / 256); // more precision
537                 else
538                         step = (step / 64) * (1 + 2 * (time - pressed_key_time));
539         }
540
541         HUD_Panel_UpdatePosSizeForId(highlightedPanel);
542
543         highlightedPanel_initial_pos = panel_pos;
544         highlightedPanel_initial_size = panel_size;
545
546         if (hudShiftState & S_ALT) // resize
547         {
548                 highlightedAction = 1;
549                 if(nPrimary == K_UPARROW)
550                         resizeCorner = 1;
551                 else if(nPrimary == K_RIGHTARROW)
552                         resizeCorner = 2;
553                 else if(nPrimary == K_LEFTARROW)
554                         resizeCorner = 3;
555                 else // if(nPrimary == K_DOWNARROW)
556                         resizeCorner = 4;
557
558                 // ctrl+arrow reduces the size, instead of increasing it
559                 // Note that ctrl disables collisions check too, but it's fine
560                 // since we don't collide with anything reducing the size
561                 if (hudShiftState & S_CTRL) {
562                         step = -step;
563                         resizeCorner = 5 - resizeCorner;
564                 }
565
566                 vector mySize;
567                 mySize = panel_size;
568                 panel_click_resizeorigin = panel_pos;
569                 if(resizeCorner == 1) {
570                         panel_click_resizeorigin += mySize;
571                         mySize_y += step;
572                 } else if(resizeCorner == 2) {
573                         panel_click_resizeorigin_y += mySize_y;
574                         mySize_x += step;
575                 } else if(resizeCorner == 3) {
576                         panel_click_resizeorigin_x += mySize_x;
577                         mySize_x += step;
578                 } else { // resizeCorner == 4
579                         mySize_y += step;
580                 }
581                 HUD_Panel_SetPosSize(mySize);
582         }
583         else // move
584         {
585                 highlightedAction = 2;
586                 vector pos;
587                 pos = panel_pos;
588                 if(nPrimary == K_UPARROW)
589                         pos_y -= step;
590                 else if(nPrimary == K_DOWNARROW)
591                         pos_y += step;
592                 else if(nPrimary == K_LEFTARROW)
593                         pos_x -= step;
594                 else // if(nPrimary == K_RIGHTARROW)
595                         pos_x += step;
596
597                 HUD_Panel_SetPos(pos);
598         }
599
600         HUD_Panel_UpdatePosSizeForId(highlightedPanel);
601
602         if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size)
603         {
604                 // backup!
605                 panel_pos_backup = highlightedPanel_initial_pos;
606                 panel_size_backup = highlightedPanel_initial_size;
607                 highlightedPanel_backup = highlightedPanel;
608         }
609 }
610
611 const float S_MOUSE1 = 1;
612 const float S_MOUSE2 = 2;
613 const float S_MOUSE3 = 4;
614 float mouseClicked;
615 float prevMouseClicked; // previous state
616 float prevMouseClickedTime; // time during previous left mouse click, to check for doubleclicks
617 vector prevMouseClickedPos; // pos during previous left mouse click, to check for doubleclicks
618
619 void HUD_Panel_EnableMenu();
620 float tab_panels[HUD_PANEL_NUM];
621 float tab_panel, tab_backward;
622 vector tab_panel_pos;
623 void HUD_Panel_FirstInDrawQ(float id);
624 void reset_tab_panels()
625 {
626         int i;
627         for(i = 0; i < HUD_PANEL_NUM; ++i)
628                 tab_panels[i] = -1;
629 }
630 float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
631 {
632         string s;
633
634         // we only care for keyboard events
635         if(bInputType != 0 && bInputType != 1)
636                 return false;
637
638         if(!autocvar__hud_configure)
639                 return false;
640
641         // block any input while a menu dialog is fading
642         if(autocvar__menu_alpha)
643                 return true;
644
645         // allow console bind to work
646         string con_keys;
647         float keys;
648         con_keys = findkeysforcommand("toggleconsole", 0);
649         keys = tokenize(con_keys); // findkeysforcommand returns data for this
650
651         float hit_con_bind, i;
652         for (i = 0; i < keys; ++i)
653         {
654                 if(nPrimary == stof(argv(i)))
655                         hit_con_bind = 1;
656         }
657
658         if(bInputType == 0) {
659                 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
660                 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
661                 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
662         }
663         else if(bInputType == 1) {
664                 if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
665                 if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
666                 if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
667         }
668
669         if(nPrimary == K_CTRL)
670         {
671                 if (bInputType == 1) //ctrl has been released
672                 {
673                         if (tab_panel != -1)
674                         {
675                                 //switch to selected panel
676                                 highlightedPanel = tab_panel;
677                                 highlightedAction = 0;
678                                 HUD_Panel_FirstInDrawQ(highlightedPanel);
679                         }
680                         tab_panel = -1;
681                         reset_tab_panels();
682                 }
683         }
684
685         if(nPrimary == K_MOUSE1)
686         {
687                 if(bInputType == 0) // key pressed
688                         mouseClicked |= S_MOUSE1;
689                 else if(bInputType == 1) // key released
690                         mouseClicked -= (mouseClicked & S_MOUSE1);
691         }
692         else if(nPrimary == K_MOUSE2)
693         {
694                 if(bInputType == 0) // key pressed
695                         mouseClicked |= S_MOUSE2;
696                 else if(bInputType == 1) // key released
697                         mouseClicked -= (mouseClicked & S_MOUSE2);
698         }
699         else if(nPrimary == K_ESCAPE)
700         {
701                 if (bInputType == 1)
702                         return true;
703                 menu_enabled = 1;
704                 menu_enabled_time = time;
705                 localcmd("menu_showhudexit\n");
706         }
707         else if(nPrimary == K_BACKSPACE && hudShiftState & S_CTRL)
708         {
709                 if (bInputType == 1)
710                         return true;
711                 if (!menu_enabled)
712                         cvar_set("_hud_configure", "0");
713         }
714         else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // select and highlight another panel
715         {
716                 if (bInputType == 1 || mouseClicked)
717                         return true;
718
719                 //FIXME: if a panel is highlighted, has the same pos_x and lays in the same level
720                 //of other panels then next consecutive ctrl-tab will select the highlighted panel too
721                 //(it should only after every other panel of the hud)
722                 //It's a minor bug anyway, we can live with it
723
724                 float starting_panel;
725                 float old_tab_panel = tab_panel;
726                 if (tab_panel == -1) //first press of TAB
727                 {
728                         if (highlightedPanel != -1)
729                                 HUD_Panel_UpdatePosSizeForId(highlightedPanel)
730                         else
731                                 panel_pos = '0 0 0';
732                         starting_panel = highlightedPanel; //can be -1, it means no starting panel
733                         tab_panel_pos = panel_pos; //to compute level
734                 }
735                 else
736                 {
737                         if ( ((!tab_backward) && (hudShiftState & S_SHIFT)) || (tab_backward && !(hudShiftState & S_SHIFT)) ) //tab direction changed?
738                                 reset_tab_panels();
739                         starting_panel = tab_panel;
740                 }
741                 tab_backward = (hudShiftState & S_SHIFT);
742
743                 float k, level, start_pos_x;
744                 vector candidate_pos;
745                 const float LEVELS_NUM = 4;
746                 float level_height = vid_conheight / LEVELS_NUM;
747 :find_tab_panel
748                 level = floor(tab_panel_pos_y / level_height) * level_height; //starting level
749                 candidate_pos_x = (!tab_backward) ? vid_conwidth : 0;
750                 start_pos_x = tab_panel_pos_x;
751                 tab_panel = -1;
752                 k=0;
753                 while(++k)
754                 {
755                         for(i = 0; i < HUD_PANEL_NUM; ++i)
756                         {
757                                 if (i == tab_panels[i] || i == starting_panel)
758                                         continue;
759                                 HUD_Panel_UpdatePosSizeForId(i)
760                                 if (panel_pos_y >= level && (panel_pos_y - level) < level_height)
761                                 if (  ( !tab_backward && panel_pos_x >= start_pos_x && (panel_pos_x < candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y <= candidate_pos_y)) )
762                                         || ( tab_backward && panel_pos_x <= start_pos_x && (panel_pos_x > candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y >= candidate_pos_y)) )  )
763                                 {
764                                         tab_panel = i;
765                                         tab_panel_pos = candidate_pos = panel_pos;
766                                 }
767                         }
768                         if (tab_panel != -1)
769                                 break;
770                         if (k == LEVELS_NUM) //tab_panel not found
771                         {
772                                 reset_tab_panels();
773                                 if (old_tab_panel == -2) //this prevents an infinite loop (should not happen normally)
774                                 {
775                                         tab_panel = -1;
776                                         return true;
777                                 }
778                                 starting_panel = old_tab_panel;
779                                 old_tab_panel = -2;
780                                 goto find_tab_panel; //u must find tab_panel!
781                         }
782                         if (!tab_backward)
783                         {
784                                 level = mod(level + level_height, vid_conheight);
785                                 start_pos_x = 0;
786                                 candidate_pos_x = vid_conwidth;
787                         }
788                         else
789                         {
790                                 level = mod(level - level_height, vid_conheight);
791                                 start_pos_x = vid_conwidth;
792                                 candidate_pos_x = 0;
793                         }
794                 }
795
796                 tab_panels[tab_panel] = tab_panel;
797         }
798         else if(nPrimary == K_SPACE && hudShiftState & S_CTRL) // enable/disable highlighted panel or dock
799         {
800                 if (bInputType == 1 || mouseClicked)
801                         return true;
802
803                 if (highlightedPanel != -1)
804                 {
805                         HUD_Panel_GetName(highlightedPanel);
806                         cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled)));
807                 }
808                 else
809                         cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : "");
810         }
811         else if(nPrimary == 'c' && hudShiftState & S_CTRL) // copy highlighted panel size
812         {
813                 if (bInputType == 1 || mouseClicked)
814                         return true;
815
816                 if (highlightedPanel != -1)
817                 {
818                         HUD_Panel_UpdatePosSizeForId(highlightedPanel);
819                         panel_size_copied = panel_size;
820                         highlightedPanel_copied = highlightedPanel;
821                 }
822         }
823         else if(nPrimary == 'v' && hudShiftState & S_CTRL) // past copied size on the highlighted panel
824         {
825                 if (bInputType == 1 || mouseClicked)
826                         return true;
827
828                 if (highlightedPanel_copied == -1 || highlightedPanel == -1)
829                         return true;
830
831                 HUD_Panel_UpdatePosSizeForId(highlightedPanel);
832
833                 // reduce size if it'd go beyond screen boundaries
834                 vector tmp_size = panel_size_copied;
835                 if (panel_pos_x + panel_size_copied_x > vid_conwidth)
836                         tmp_size_x = vid_conwidth - panel_pos_x;
837                 if (panel_pos_y + panel_size_copied_y > vid_conheight)
838                         tmp_size_y = vid_conheight - panel_pos_y;
839
840                 if (panel_size == tmp_size)
841                         return true;
842
843                 // backup first!
844                 panel_pos_backup = panel_pos;
845                 panel_size_backup = panel_size;
846                 highlightedPanel_backup = highlightedPanel;
847
848                 s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight));
849                 HUD_Panel_GetName(highlightedPanel);
850                 cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
851         }
852         else if(nPrimary == 'z' && hudShiftState & S_CTRL) // undo last action
853         {
854                 if (bInputType == 1 || mouseClicked)
855                         return true;
856                 //restore previous values
857                 if (highlightedPanel_backup != -1)
858                 {
859                         HUD_Panel_GetName(highlightedPanel_backup);
860                         s = strcat(ftos(panel_pos_backup_x/vid_conwidth), " ", ftos(panel_pos_backup_y/vid_conheight));
861                         cvar_set(strcat("hud_panel_", panel_name, "_pos"), s);
862                         s = strcat(ftos(panel_size_backup_x/vid_conwidth), " ", ftos(panel_size_backup_y/vid_conheight));
863                         cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
864                         highlightedPanel_backup = -1;
865                 }
866         }
867         else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW)
868         {
869                 if (bInputType == 1)
870                 {
871                         pressed_key_time = 0;
872                         return true;
873                 }
874                 else if (pressed_key_time == 0)
875                         pressed_key_time = time;
876
877                 if (!mouseClicked)
878                         HUD_Panel_Arrow_Action(nPrimary); //move or resize panel
879         }
880         else if(nPrimary == K_ENTER || nPrimary == K_SPACE || nPrimary == K_KP_ENTER)
881         {
882                 if (bInputType == 1)
883                         return true;
884                 if (highlightedPanel != -1)
885                         HUD_Panel_EnableMenu();
886         }
887         else if(hit_con_bind)
888                 return false;
889
890         return true;
891 }
892
893 float HUD_Panel_Check_Mouse_Pos(float allow_move)
894 {
895         float i, j, border;
896
897         while(j < HUD_PANEL_NUM)
898         {
899                 i = panel_order[j];
900                 j += 1;
901
902                 HUD_Panel_UpdatePosSizeForId(i);
903
904                 border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize
905
906                 // move
907                 if(allow_move && mousepos_x >= panel_pos_x && mousepos_y >= panel_pos_y && mousepos_x <= panel_pos_x + panel_size_x && mousepos_y <= panel_pos_y + panel_size_y)
908                 {
909                         return 1;
910                 }
911                 // resize from topleft border
912                 else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
913                 {
914                         return 2;
915                 }
916                 // resize from topright border
917                 else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
918                 {
919                         return 3;
920                 }
921                 // resize from bottomleft border
922                 else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + panel_size_y + border)
923                 {
924                         return 3;
925                 }
926                 // resize from bottomright border
927                 else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + panel_size_y + border)
928                 {
929                         return 2;
930                 }
931         }
932         return 0;
933 }
934
935 // move a panel to the beginning of the panel order array (which means it gets drawn last, on top of everything else)
936 void HUD_Panel_FirstInDrawQ(float id)
937 {
938         float i;
939         var float place = -1;
940         // find out where in the array our current id is, save into place
941         for(i = 0; i < HUD_PANEL_NUM; ++i)
942         {
943                 if(panel_order[i] == id)
944                 {
945                         place = i;
946                         break;
947                 }
948         }
949         // place last if we didn't find a place for it yet (probably new panel, or screwed up cvar)
950         if(place == -1)
951                 place = HUD_PANEL_NUM - 1;
952
953         // move all ids up by one step in the array until "place"
954         for(i = place; i > 0; --i)
955         {
956                 panel_order[i] = panel_order[i-1];
957         }
958         // now save the new top id
959         panel_order[0] = id;
960         
961         // let's save them into the cvar by some strcat trickery
962         string s;
963         for(i = 0; i < HUD_PANEL_NUM; ++i)
964         {
965                 s = strcat(s, ftos(panel_order[i]), " ");
966         }
967         cvar_set("_hud_panelorder", s);
968         if(hud_panelorder_prev)
969                 strunzone(hud_panelorder_prev);
970         hud_panelorder_prev = strzone(autocvar__hud_panelorder); // prevent HUD_Main from doing useless update, we already updated here
971 }
972
973 void HUD_Panel_Highlight(float allow_move)
974 {
975         float i, j, border;
976
977         while(j < HUD_PANEL_NUM)
978         {
979                 i = panel_order[j];
980                 j += 1;
981
982                 HUD_Panel_UpdatePosSizeForId(i);
983
984                 border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize
985
986                 // move
987                 if(allow_move && mousepos_x >= panel_pos_x && mousepos_y >= panel_pos_y && mousepos_x <= panel_pos_x + panel_size_x && mousepos_y <= panel_pos_y + panel_size_y)
988                 {
989                         highlightedPanel = i;
990                         HUD_Panel_FirstInDrawQ(i);
991                         highlightedAction = 1;
992                         panel_click_distance = mousepos - panel_pos;
993                         return;
994                 }
995                 // resize from topleft border
996                 else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
997                 {
998                         highlightedPanel = i;
999                         HUD_Panel_FirstInDrawQ(i);
1000                         highlightedAction = 2;
1001                         resizeCorner = 1;
1002                         panel_click_distance = mousepos - panel_pos;
1003                         panel_click_resizeorigin = panel_pos + panel_size;
1004                         return;
1005                 }
1006                 // resize from topright border
1007                 else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
1008                 {
1009                         highlightedPanel = i;
1010                         HUD_Panel_FirstInDrawQ(i);
1011                         highlightedAction = 2;
1012                         resizeCorner = 2;
1013                         panel_click_distance_x = panel_size_x - mousepos_x + panel_pos_x;
1014                         panel_click_distance_y = mousepos_y - panel_pos_y;
1015                         panel_click_resizeorigin = panel_pos + eY * panel_size_y;
1016                         return;
1017                 }
1018                 // resize from bottomleft border
1019                 else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + panel_size_y + border)
1020                 {
1021                         highlightedPanel = i;
1022                         HUD_Panel_FirstInDrawQ(i);
1023                         highlightedAction = 2;
1024                         resizeCorner = 3;
1025                         panel_click_distance_x = mousepos_x - panel_pos_x;
1026                         panel_click_distance_y = panel_size_y - mousepos_y + panel_pos_y;
1027                         panel_click_resizeorigin = panel_pos + eX * panel_size_x;
1028                         return;
1029                 }
1030                 // resize from bottomright border
1031                 else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + panel_size_y + border)
1032                 {
1033                         highlightedPanel = i;
1034                         HUD_Panel_FirstInDrawQ(i);
1035                         highlightedAction = 2;
1036                         resizeCorner = 4;
1037                         panel_click_distance = panel_size - mousepos + panel_pos;
1038                         panel_click_resizeorigin = panel_pos;
1039                         return;
1040                 }
1041         }
1042         highlightedPanel = -1;
1043         highlightedAction = 0;
1044 }
1045
1046 void HUD_Panel_EnableMenu()
1047 {
1048         menu_enabled = 2;
1049         menu_enabled_time = time;
1050         HUD_Panel_GetName(highlightedPanel);
1051         localcmd("menu_showhudoptions ", panel_name, "\n");
1052 }
1053 float mouse_over_panel;
1054 void HUD_Panel_Mouse()
1055 {
1056         // TODO: needs better check... is there any float that contains the current state of the menu? _menu_alpha isn't apparently updated the frame the menu gets enabled
1057         if (autocvar__menu_alpha == 0 && time - menu_enabled_time > 0.5)
1058                 menu_enabled = 0;
1059
1060         /*
1061         print("menu_enabled: ", ftos(menu_enabled), "\n");
1062         print("Highlighted: ", ftos(highlightedPanel), "\n");
1063         print("Menu theAlpha: ", ftos(autocvar__menu_alpha), "\n");
1064         */
1065
1066         if(autocvar__menu_alpha == 1)
1067                 return;
1068
1069         mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
1070
1071         mousepos_x = bound(0, mousepos_x, vid_conwidth);
1072         mousepos_y = bound(0, mousepos_y, vid_conheight);
1073
1074         if(mouseClicked)
1075         {
1076                 if(prevMouseClicked == 0)
1077                 {
1078                         if (tab_panel != -1)
1079                         {
1080                                 //stop ctrl-tab selection
1081                                 tab_panel = -1;
1082                                 reset_tab_panels();
1083                         }
1084                         HUD_Panel_Highlight(mouseClicked & S_MOUSE1); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin
1085                                                                         // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel
1086                         if (highlightedPanel != -1)
1087                         {
1088                                 highlightedPanel_initial_pos = panel_pos;
1089                                 highlightedPanel_initial_size = panel_size;
1090                         }
1091                         // doubleclick check
1092                         if ((mouseClicked & S_MOUSE1) && time - prevMouseClickedTime < 0.4 && highlightedPanel != -1 && prevMouseClickedPos == mousepos)
1093                         {
1094                                 mouseClicked = 0; // to prevent spam, I guess.
1095                                 HUD_Panel_EnableMenu();
1096                         }
1097                         else
1098                         {
1099                                 if (mouseClicked & S_MOUSE1)
1100                                 {
1101                                         prevMouseClickedTime = time;
1102                                         prevMouseClickedPos = mousepos;
1103                                 }
1104                                 mouse_over_panel = HUD_Panel_Check_Mouse_Pos(mouseClicked & S_MOUSE1);
1105                         }
1106                 }
1107                 else
1108                         HUD_Panel_UpdatePosSizeForId(highlightedPanel);
1109
1110                 if (highlightedPanel != -1)
1111                 {
1112                         drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .1, DRAWFLAG_NORMAL);
1113                         if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size)
1114                         {
1115                                 hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
1116                                 // backup!
1117                                 panel_pos_backup = highlightedPanel_initial_pos;
1118                                 panel_size_backup = highlightedPanel_initial_size;
1119                                 highlightedPanel_backup = highlightedPanel;
1120                         }
1121                         else
1122                                 // in case the clicked panel is inside another panel and we aren't
1123                                 // moving it, avoid the immediate "fix" of its position/size
1124                                 // (often unwanted and hateful) by disabling collisions check
1125                                 hud_configure_checkcollisions = false;
1126                 }
1127
1128                 if(highlightedAction == 1)
1129                         HUD_Panel_SetPos(mousepos - panel_click_distance);
1130                 else if(highlightedAction == 2)
1131                 {
1132                         vector mySize;
1133                         if(resizeCorner == 1) {
1134                                 mySize_x = panel_click_resizeorigin_x - (mousepos_x - panel_click_distance_x);
1135                                 mySize_y = panel_click_resizeorigin_y - (mousepos_y - panel_click_distance_y);
1136                         } else if(resizeCorner == 2) {
1137                                 mySize_x = mousepos_x + panel_click_distance_x - panel_click_resizeorigin_x;
1138                                 mySize_y = panel_click_distance_y + panel_click_resizeorigin_y - mousepos_y;
1139                         } else if(resizeCorner == 3) {
1140                                 mySize_x = panel_click_resizeorigin_x + panel_click_distance_x - mousepos_x;
1141                                 mySize_y = mousepos_y + panel_click_distance_y - panel_click_resizeorigin_y;
1142                         } else { // resizeCorner == 4
1143                                 mySize_x = mousepos_x - (panel_click_resizeorigin_x - panel_click_distance_x);
1144                                 mySize_y = mousepos_y - (panel_click_resizeorigin_y - panel_click_distance_y);
1145                         }
1146                         HUD_Panel_SetPosSize(mySize);
1147                 }
1148         }
1149         else
1150         {
1151                 if(menu_enabled == 2)
1152                         mouse_over_panel = 0;
1153                 else
1154                         mouse_over_panel = HUD_Panel_Check_Mouse_Pos(TRUE);
1155                 if (mouse_over_panel && tab_panel == -1)
1156                         drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .1, DRAWFLAG_NORMAL);
1157         }
1158         // draw cursor after performing move/resize to have the panel pos/size updated before mouse_over_panel
1159         const vector cursorsize = '32 32 0';
1160         float cursor_alpha = 1 - autocvar__menu_alpha;
1161
1162         if(!mouse_over_panel)
1163                 drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', cursor_alpha, DRAWFLAG_NORMAL);
1164         else if(mouse_over_panel == 1)
1165                 drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_move.tga"), cursorsize, '1 1 1', cursor_alpha, DRAWFLAG_NORMAL);
1166         else if(mouse_over_panel == 2)
1167                 drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize.tga"), cursorsize, '1 1 1', cursor_alpha, DRAWFLAG_NORMAL);
1168         else
1169                 drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize2.tga"), cursorsize, '1 1 1', cursor_alpha, DRAWFLAG_NORMAL);
1170
1171         prevMouseClicked = mouseClicked;
1172 }
1173
1174 const float hlBorderSize = 4;
1175 const string hlBorder = "gfx/hud/default/border_highlighted";
1176 const string hlBorder2 = "gfx/hud/default/border_highlighted2";
1177 void HUD_Panel_HlBorder(float myBorder, vector color, float theAlpha)
1178 {
1179         drawfill(panel_pos - '1 1 0' * myBorder, panel_size + '2 2 0' * myBorder, '0 0.5 1', .5 * theAlpha, DRAWFLAG_NORMAL);
1180         drawpic_tiled(panel_pos - '1 1 0' * myBorder, hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, theAlpha, DRAWFLAG_NORMAL);
1181         drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * (panel_size_y + 2 * myBorder - hlBorderSize), hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, theAlpha, DRAWFLAG_NORMAL);
1182         drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize, hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, theAlpha, DRAWFLAG_NORMAL);
1183         drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize + eX * (panel_size_x + 2 * myBorder - hlBorderSize), hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, theAlpha, DRAWFLAG_NORMAL);
1184 }