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