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