From: terencehill Date: Sun, 19 Dec 2010 18:00:02 +0000 (+0100) Subject: Move most of the hud config. code in hud_config.qc to reduce size of hud.qc X-Git-Tag: xonotic-v0.5.0~344 X-Git-Url: http://de.git.xonotic.org/?a=commitdiff_plain;h=423c31082a256c5082afb5532c3fe5c788315708;p=xonotic%2Fxonotic-data.pk3dir.git Move most of the hud config. code in hud_config.qc to reduce size of hud.qc --- diff --git a/qcsrc/client/hud.qc b/qcsrc/client/hud.qc index db842f6ae..c03755e01 100644 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@ -417,154 +417,6 @@ HUD panels ================== */ -#define HUD_Write(s) fputs(fh, s) -// q: quoted, n: not quoted -#define HUD_Write_Cvar_n(cvar) HUD_Write(strcat("seta ", cvar, " ", cvar_string(cvar), "\n")) -#define HUD_Write_Cvar_q(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n")) -#define HUD_Write_PanelCvar_n(cvar_suf) HUD_Write_Cvar_n(strcat("hud_panel_", panel_name, cvar_suf)) -#define HUD_Write_PanelCvar_q(cvar_suf) HUD_Write_Cvar_q(strcat("hud_panel_", panel_name, cvar_suf)) -// Save the config -void HUD_Panel_ExportCfg(string cfgname) -{ - float fh; - string filename = strcat("hud_", autocvar_hud_skin, "_", cfgname, ".cfg"); - fh = fopen(filename, FILE_WRITE); - if(fh >= 0) - { - HUD_Write_Cvar_q("hud_skin"); - HUD_Write_Cvar_q("hud_panel_bg"); - HUD_Write_Cvar_q("hud_panel_bg_color"); - HUD_Write_Cvar_q("hud_panel_bg_color_team"); - HUD_Write_Cvar_q("hud_panel_bg_alpha"); - HUD_Write_Cvar_q("hud_panel_bg_border"); - HUD_Write_Cvar_q("hud_panel_bg_padding"); - HUD_Write_Cvar_q("hud_panel_fg_alpha"); - HUD_Write("\n"); - - HUD_Write_Cvar_q("hud_dock"); - HUD_Write_Cvar_q("hud_dock_color"); - HUD_Write_Cvar_q("hud_dock_color_team"); - HUD_Write_Cvar_q("hud_dock_alpha"); - HUD_Write("\n"); - - HUD_Write_Cvar_q("hud_progressbar_alpha"); - HUD_Write_Cvar_q("hud_progressbar_strength_color"); - HUD_Write_Cvar_q("hud_progressbar_shield_color"); - HUD_Write_Cvar_q("hud_progressbar_health_color"); - HUD_Write_Cvar_q("hud_progressbar_armor_color"); - HUD_Write_Cvar_q("hud_progressbar_fuel_color"); - HUD_Write_Cvar_q("hud_progressbar_nexball_color"); - HUD_Write("\n"); - - HUD_Write_Cvar_q("_hud_panelorder"); - HUD_Write("\n"); - - HUD_Write_Cvar_q("hud_configure_grid"); - HUD_Write_Cvar_q("hud_configure_grid_xsize"); - HUD_Write_Cvar_q("hud_configure_grid_ysize"); - HUD_Write("\n"); - - HUD_Write_Cvar_q("scr_centerpos"); - HUD_Write("\n"); - - // common cvars for all panels - float i; - for (i = 0; i < HUD_PANEL_NUM; ++i) - { - HUD_Panel_GetName(i); - - HUD_Write_PanelCvar_n(""); - HUD_Write_PanelCvar_q("_pos"); - HUD_Write_PanelCvar_q("_size"); - HUD_Write_PanelCvar_q("_bg"); - HUD_Write_PanelCvar_q("_bg_color"); - HUD_Write_PanelCvar_q("_bg_color_team"); - HUD_Write_PanelCvar_q("_bg_alpha"); - HUD_Write_PanelCvar_q("_bg_border"); - HUD_Write_PanelCvar_q("_bg_padding"); - switch(i) { - case HUD_PANEL_WEAPONS: - HUD_Write_PanelCvar_q("_complainbubble"); - HUD_Write_PanelCvar_q("_complainbubble_padding"); - HUD_Write_PanelCvar_q("_complainbubble_color_outofammo"); - HUD_Write_PanelCvar_q("_complainbubble_color_donthave"); - HUD_Write_PanelCvar_q("_complainbubble_color_unavailable"); - HUD_Write_PanelCvar_q("_ammo_color"); - HUD_Write_PanelCvar_q("_ammo_alpha"); - HUD_Write_PanelCvar_q("_aspect"); - HUD_Write_PanelCvar_q("_timeout"); - HUD_Write_PanelCvar_q("_timeout_effect"); - break; - case HUD_PANEL_AMMO: - HUD_Write_PanelCvar_q("_onlycurrent"); - HUD_Write_PanelCvar_q("_iconalign"); - HUD_Write_PanelCvar_q("_progressbar"); - HUD_Write_PanelCvar_q("_progressbar_name"); - HUD_Write_PanelCvar_q("_progressbar_xoffset"); - HUD_Write_PanelCvar_q("_text"); - break; - case HUD_PANEL_POWERUPS: - HUD_Write_PanelCvar_q("_flip"); - HUD_Write_PanelCvar_q("_iconalign"); - HUD_Write_PanelCvar_q("_baralign"); - HUD_Write_PanelCvar_q("_progressbar"); - HUD_Write_PanelCvar_q("_progressbar_strength"); - HUD_Write_PanelCvar_q("_progressbar_shield"); - break; - case HUD_PANEL_HEALTHARMOR: - HUD_Write_PanelCvar_q("_flip"); - HUD_Write_PanelCvar_q("_iconalign"); - HUD_Write_PanelCvar_q("_baralign"); - HUD_Write_PanelCvar_q("_progressbar"); - HUD_Write_PanelCvar_q("_progressbar_health"); - HUD_Write_PanelCvar_q("_progressbar_armor"); - HUD_Write_PanelCvar_q("_text"); - break; - case HUD_PANEL_NOTIFY: - HUD_Write_PanelCvar_q("_flip"); - HUD_Write_PanelCvar_q("_print"); - break; - case HUD_PANEL_RADAR: - HUD_Write_PanelCvar_q("_foreground_alpha"); - break; - case HUD_PANEL_VOTE: - HUD_Write_PanelCvar_q("_alreadyvoted_alpha"); - break; - case HUD_PANEL_PRESSEDKEYS: - HUD_Write_PanelCvar_q("_aspect"); - break; - case HUD_PANEL_INFOMESSAGES: - HUD_Write_PanelCvar_q("_flip"); - break; - case HUD_PANEL_PHYSICS: - HUD_Write_PanelCvar_q("_flip"); - HUD_Write_PanelCvar_q("_baralign"); - HUD_Write_PanelCvar_q("_progressbar"); - break; - } - HUD_Write("\n"); - } - HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated - - print("^2Successfully exported to ", filename, "! (Note: It's saved in data/data/)\n"); - fclose(fh); - } - else - print("^1Couldn't write to ", filename, "\n"); -} - -const float hlBorderSize = 4; -const string hlBorder = "gfx/hud/default/border_highlighted"; -const string hlBorder2 = "gfx/hud/default/border_highlighted2"; -void HUD_Panel_HlBorder(float myBorder, vector color, float alpha) -{ - drawfill(panel_pos - '1 1 0' * myBorder, panel_size + '2 2 0' * myBorder, '0 0.5 1', .5 * alpha, DRAWFLAG_NORMAL); - drawpic_tiled(panel_pos - '1 1 0' * myBorder, hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); - drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * (panel_size_y + 2 * myBorder - hlBorderSize), hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); - drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize, hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); - drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize + eX * (panel_size_x + 2 * myBorder - hlBorderSize), hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); -} - // draw the background/borders #define HUD_Panel_DrawBg(alpha)\ if(panel_bg != "0")\ @@ -666,955 +518,6 @@ void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float alph drawsubpic(pos + eX * mySize_x - eX * min(mySize_x * 0.5, mySize_y), eX * min(mySize_x * 0.5, mySize_y) + eY * mySize_y, pic, '0.75 0 0', '0.25 1 0', color, alpha, drawflag); } -// check if move will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector -vector HUD_Panel_CheckMove(vector myPos, vector mySize) -{ - float i; - float myCenter_x, myCenter_y, targCenter_x, targCenter_y; - vector myTarget; - myTarget = myPos; - - for (i = 0; i < HUD_PANEL_NUM; ++i) { - if(i == highlightedPanel || !panel_enabled) - continue; - - HUD_Panel_UpdatePosSizeForId(i); - - panel_pos -= '1 1 0' * panel_bg_border; - panel_size += '2 2 0' * panel_bg_border; - - if(myPos_y + mySize_y < panel_pos_y) - continue; - if(myPos_y > panel_pos_y + panel_size_y) - continue; - - if(myPos_x + mySize_x < panel_pos_x) - continue; - if(myPos_x > panel_pos_x + panel_size_x) - continue; - - // OK, there IS a collision. - - myCenter_x = myPos_x + 0.5 * mySize_x; - myCenter_y = myPos_y + 0.5 * mySize_y; - - targCenter_x = panel_pos_x + 0.5 * panel_size_x; - targCenter_y = panel_pos_y + 0.5 * panel_size_y; - - if(myCenter_x < targCenter_x && myCenter_y < targCenter_y) // top left (of the target panel) - { - if(myPos_x + mySize_x - panel_pos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side - myTarget_x = panel_pos_x - mySize_x; - else // push it upwards - myTarget_y = panel_pos_y - mySize_y; - } - else if(myCenter_x > targCenter_x && myCenter_y < targCenter_y) // top right - { - if(panel_pos_x + panel_size_x - myPos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side - myTarget_x = panel_pos_x + panel_size_x; - else // push it upwards - myTarget_y = panel_pos_y - mySize_y; - } - else if(myCenter_x < targCenter_x && myCenter_y > targCenter_y) // bottom left - { - if(myPos_x + mySize_x - panel_pos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side - myTarget_x = panel_pos_x - mySize_x; - else // push it downwards - myTarget_y = panel_pos_y + panel_size_y; - } - else if(myCenter_x > targCenter_x && myCenter_y > targCenter_y) // bottom right - { - if(panel_pos_x + panel_size_x - myPos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side - myTarget_x = panel_pos_x + panel_size_x; - else // push it downwards - myTarget_y = panel_pos_y + panel_size_y; - } - //if(cvar("hud_configure_checkcollisions_debug")) - //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL); - } - - return myTarget; -} - -void HUD_Panel_SetPos(vector pos) -{ - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - vector mySize; - mySize = panel_size; - - //if(cvar("hud_configure_checkcollisions_debug")) - //drawfill(pos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL); - - if(autocvar_hud_configure_grid) - { - pos_x = floor((pos_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x; - pos_y = floor((pos_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y; - } - - if(hud_configure_checkcollisions) - pos = HUD_Panel_CheckMove(pos, mySize); - - pos_x = bound(0, pos_x, vid_conwidth - mySize_x); - pos_y = bound(0, pos_y, vid_conheight - mySize_y); - - string s; - s = strcat(ftos(pos_x/vid_conwidth), " ", ftos(pos_y/vid_conheight)); - - HUD_Panel_GetName(highlightedPanel); - cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); -} - -// check if resize will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector -vector HUD_Panel_CheckResize(vector mySize, vector resizeorigin) { - float i; - - vector targEndPos; - - float dist_x, dist_y; - float ratio; - ratio = mySize_x/mySize_y; - - for (i = 0; i < HUD_PANEL_NUM; ++i) { - if(i == highlightedPanel || !panel_enabled) - continue; - - HUD_Panel_UpdatePosSizeForId(i); - - panel_pos -= '1 1 0' * panel_bg_border; - panel_size += '2 2 0' * panel_bg_border; - - targEndPos = panel_pos + panel_size; - - // resizeorigin is WITHIN target panel, just abort any collision testing against that particular panel to produce expected behaviour! - if(resizeorigin_x > panel_pos_x && resizeorigin_x < targEndPos_x && resizeorigin_y > panel_pos_y && resizeorigin_y < targEndPos_y) - continue; - - if (resizeCorner == 1) - { - // check if this panel is on our way - if (resizeorigin_x <= panel_pos_x) - continue; - if (resizeorigin_y <= panel_pos_y) - continue; - if (targEndPos_x <= resizeorigin_x - mySize_x) - continue; - if (targEndPos_y <= resizeorigin_y - mySize_y) - continue; - - // there is a collision: - // detect which side of the panel we are facing is actually limiting the resizing - // (which side the resize direction finds for first) and reduce the size up to there - // - // dist is the distance between resizeorigin and the "analogous" point of the panel - // in this case between resizeorigin (bottom-right point) and the bottom-right point of the panel - dist_x = resizeorigin_x - targEndPos_x; - dist_y = resizeorigin_y - targEndPos_y; - if (dist_y <= 0 || dist_x / dist_y > ratio) - mySize_x = min(mySize_x, dist_x); - else - mySize_y = min(mySize_y, dist_y); - } - else if (resizeCorner == 2) - { - if (resizeorigin_x >= targEndPos_x) - continue; - if (resizeorigin_y <= panel_pos_y) - continue; - if (panel_pos_x >= resizeorigin_x + mySize_x) - continue; - if (targEndPos_y <= resizeorigin_y - mySize_y) - continue; - - dist_x = panel_pos_x - resizeorigin_x; - dist_y = resizeorigin_y - targEndPos_y; - if (dist_y <= 0 || dist_x / dist_y > ratio) - mySize_x = min(mySize_x, dist_x); - else - mySize_y = min(mySize_y, dist_y); - } - else if (resizeCorner == 3) - { - if (resizeorigin_x <= panel_pos_x) - continue; - if (resizeorigin_y >= targEndPos_y) - continue; - if (targEndPos_x <= resizeorigin_x - mySize_x) - continue; - if (panel_pos_y >= resizeorigin_y + mySize_y) - continue; - - dist_x = resizeorigin_x - targEndPos_x; - dist_y = panel_pos_y - resizeorigin_y; - if (dist_y <= 0 || dist_x / dist_y > ratio) - mySize_x = min(mySize_x, dist_x); - else - mySize_y = min(mySize_y, dist_y); - } - else if (resizeCorner == 4) - { - if (resizeorigin_x >= targEndPos_x) - continue; - if (resizeorigin_y >= targEndPos_y) - continue; - if (panel_pos_x >= resizeorigin_x + mySize_x) - continue; - if (panel_pos_y >= resizeorigin_y + mySize_y) - continue; - - dist_x = panel_pos_x - resizeorigin_x; - dist_y = panel_pos_y - resizeorigin_y; - if (dist_y <= 0 || dist_x / dist_y > ratio) - mySize_x = min(mySize_x, dist_x); - else - mySize_y = min(mySize_y, dist_y); - } - //if(cvar("hud_configure_checkcollisions_debug")) - //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL); - } - - return mySize; -} - -void HUD_Panel_SetPosSize(vector mySize) -{ - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - vector resizeorigin; - resizeorigin = panel_click_resizeorigin; - vector myPos; - - // minimum panel size cap - mySize_x = max(0.025 * vid_conwidth, mySize_x); - mySize_y = max(0.025 * vid_conheight, mySize_y); - - 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. - { - mySize_x = max(17 * autocvar_con_chatsize, mySize_x); - mySize_y = max(2 * autocvar_con_chatsize + 2 * panel_bg_padding, mySize_y); - } - - // collision testing| - // -----------------+ - - // we need to know pos at this stage, but it might still change later if we hit a screen edge/other panel (?) - if(resizeCorner == 1) { - myPos_x = resizeorigin_x - mySize_x; - myPos_y = resizeorigin_y - mySize_y; - } else if(resizeCorner == 2) { - myPos_x = resizeorigin_x; - myPos_y = resizeorigin_y - mySize_y; - } else if(resizeCorner == 3) { - myPos_x = resizeorigin_x - mySize_x; - myPos_y = resizeorigin_y; - } else { // resizeCorner == 4 - myPos_x = resizeorigin_x; - myPos_y = resizeorigin_y; - } - - // left/top screen edges - if(myPos_x < 0) - mySize_x = mySize_x + myPos_x; - if(myPos_y < 0) - mySize_y = mySize_y + myPos_y; - - // bottom/right screen edges - if(myPos_x + mySize_x > vid_conwidth) - mySize_x = vid_conwidth - myPos_x; - if(myPos_y + mySize_y > vid_conheight) - mySize_y = vid_conheight - myPos_y; - - //if(cvar("hud_configure_checkcollisions_debug")) - //drawfill(myPos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL); - - // before checkresize, otherwise panel can be snapped partially inside another panel or panel aspect ratio can be broken - if(autocvar_hud_configure_grid) - { - mySize_x = floor((mySize_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x; - mySize_y = floor((mySize_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y; - } - - if(hud_configure_checkcollisions) - mySize = HUD_Panel_CheckResize(mySize, resizeorigin); - - // 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) - mySize_x = max(0.025 * vid_conwidth, mySize_x); - mySize_y = max(0.025 * vid_conheight, mySize_y); - - // do another pos check, as size might have changed by now - if(resizeCorner == 1) { - myPos_x = resizeorigin_x - mySize_x; - myPos_y = resizeorigin_y - mySize_y; - } else if(resizeCorner == 2) { - myPos_x = resizeorigin_x; - myPos_y = resizeorigin_y - mySize_y; - } else if(resizeCorner == 3) { - myPos_x = resizeorigin_x - mySize_x; - myPos_y = resizeorigin_y; - } else { // resizeCorner == 4 - myPos_x = resizeorigin_x; - myPos_y = resizeorigin_y; - } - - //if(cvar("hud_configure_checkcollisions_debug")) - //drawfill(myPos, mySize, '0 1 0', .3, DRAWFLAG_NORMAL); - - HUD_Panel_GetName(highlightedPanel); - string s; - s = strcat(ftos(mySize_x/vid_conwidth), " ", ftos(mySize_y/vid_conheight)); - cvar_set(strcat("hud_panel_", panel_name, "_size"), s); - - s = strcat(ftos(myPos_x/vid_conwidth), " ", ftos(myPos_y/vid_conheight)); - cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); -} - -float pressed_key_time; -vector highlightedPanel_initial_pos, highlightedPanel_initial_size; -void HUD_Panel_Arrow_Action(float nPrimary) -{ - if (highlightedPanel == -1) - return; - - hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions); - - float step; - if(autocvar_hud_configure_grid) - { - if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW) - { - if (hudShiftState & S_SHIFT) - step = hud_configure_realGridSize_y; - else - step = 2 * hud_configure_realGridSize_y; - } - else - { - if (hudShiftState & S_SHIFT) - step = hud_configure_realGridSize_x; - else - step = 2 * hud_configure_realGridSize_x; - } - } - else - { - if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW) - step = vid_conheight; - else - step = vid_conwidth; - if (hudShiftState & S_SHIFT) - step = (step / 256); // more precision - else - step = (step / 64) * (1 + 2 * (time - pressed_key_time)); - } - - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - - highlightedPanel_initial_pos = panel_pos; - highlightedPanel_initial_size = panel_size; - - if (hudShiftState & S_ALT) // resize - { - highlightedAction = 1; - if(nPrimary == K_UPARROW) - resizeCorner = 1; - else if(nPrimary == K_RIGHTARROW) - resizeCorner = 2; - else if(nPrimary == K_LEFTARROW) - resizeCorner = 3; - else // if(nPrimary == K_DOWNARROW) - resizeCorner = 4; - - // ctrl+arrow reduces the size, instead of increasing it - // Note that ctrl disables collisions check too, but it's fine - // since we don't collide with anything reducing the size - if (hudShiftState & S_CTRL) { - step = -step; - resizeCorner = 5 - resizeCorner; - } - - vector mySize; - mySize = panel_size; - panel_click_resizeorigin = panel_pos; - if(resizeCorner == 1) { - panel_click_resizeorigin += mySize; - mySize_y += step; - } else if(resizeCorner == 2) { - panel_click_resizeorigin_y += mySize_y; - mySize_x += step; - } else if(resizeCorner == 3) { - panel_click_resizeorigin_x += mySize_x; - mySize_x += step; - } else { // resizeCorner == 4 - mySize_y += step; - } - HUD_Panel_SetPosSize(mySize); - } - else // move - { - highlightedAction = 2; - vector pos; - pos = panel_pos; - if(nPrimary == K_UPARROW) - pos_y -= step; - else if(nPrimary == K_DOWNARROW) - pos_y += step; - else if(nPrimary == K_LEFTARROW) - pos_x -= step; - else // if(nPrimary == K_RIGHTARROW) - pos_x += step; - - HUD_Panel_SetPos(pos); - } - - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - - if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size) - { - // backup! - panel_pos_backup = highlightedPanel_initial_pos; - panel_size_backup = highlightedPanel_initial_size; - highlightedPanel_backup = highlightedPanel; - } -} - -float mouseClicked; -float prevMouseClicked; // previous state -float prevMouseClickedTime; // time during previous mouse click, to check for doubleclicks -vector prevMouseClickedPos; // pos during previous mouse click, to check for doubleclicks - -void HUD_Panel_EnableMenu(); -float tab_panels[HUD_PANEL_NUM]; -float tab_panel, tab_backward; -vector tab_panel_pos; -void HUD_Panel_FirstInDrawQ(float id); -void reset_tab_panels() -{ - int i; - for(i = 0; i < HUD_PANEL_NUM; ++i) - tab_panels[i] = -1; -} -float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary) -{ - string s; - - if(!autocvar__hud_configure) - return false; - - // allow console bind to work - string con_keys; - float keys; - con_keys = findkeysforcommand("toggleconsole"); - keys = tokenize(con_keys); - - float hit_con_bind, i; - for (i = 0; i < keys; ++i) - { - if(nPrimary == stof(argv(i))) - hit_con_bind = 1; - } - - if(bInputType == 0) { - if(nPrimary == K_ALT) hudShiftState |= S_ALT; - if(nPrimary == K_CTRL) hudShiftState |= S_CTRL; - if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT; - } - else if(bInputType == 1) { - if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT); - if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL); - if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT); - } - - if(nPrimary == K_CTRL) - { - if (bInputType == 1) //ctrl has been released - { - if (tab_panel != -1) - { - //switch to selected panel - highlightedPanel = tab_panel; - highlightedAction = 0; - HUD_Panel_FirstInDrawQ(highlightedPanel); - } - tab_panel = -1; - reset_tab_panels(); - } - } - - if(nPrimary == K_MOUSE1) - { - if(bInputType == 0) { // key pressed - mouseClicked = 1; - return true; - } - else if(bInputType == 1) {// key released - mouseClicked = 0; - return true; - } - } - else if(nPrimary == K_ESCAPE) - { - if (bInputType == 1) - return true; - menu_enabled = 1; - menu_enabled_time = time; - localcmd("menu_showhudexit\n"); - } - else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // select and highlight another panel - { - if (bInputType == 1 || mouseClicked) - return true; - - //FIXME: if a panel is highlighted, has the same pos_x and lays in the same level - //of other panels then next consecutive ctrl-tab will select the highlighted panel too - //(it should only after every other panel of the hud) - //It's a minor bug anyway, we can live with it - - float starting_panel; - float old_tab_panel = tab_panel; - if (tab_panel == -1) //first press of TAB - { - if (highlightedPanel != -1) - HUD_Panel_UpdatePosSizeForId(highlightedPanel) - else - panel_pos = '0 0 0'; - starting_panel = highlightedPanel; //can be -1, it means no starting panel - tab_panel_pos = panel_pos; //to compute level - } - else - { - if ( ((!tab_backward) && (hudShiftState & S_SHIFT)) || (tab_backward && !(hudShiftState & S_SHIFT)) ) //tab direction changed? - reset_tab_panels(); - starting_panel = tab_panel; - } - tab_backward = (hudShiftState & S_SHIFT); - - float k, level, start_pos_x; - vector candidate_pos; - const float LEVELS_NUM = 4; - const float level_height = vid_conheight / LEVELS_NUM; -:find_tab_panel - level = floor(tab_panel_pos_y / level_height) * level_height; //starting level - candidate_pos_x = (!tab_backward) ? vid_conwidth : 0; - start_pos_x = tab_panel_pos_x; - tab_panel = -1; - k=0; - while(++k) - { - for(i = 0; i < HUD_PANEL_NUM; ++i) - { - if (i == tab_panels[i] || i == starting_panel) - continue; - HUD_Panel_UpdatePosSizeForId(i) - if (panel_pos_y >= level && (panel_pos_y - level) < level_height) - if ( ( !tab_backward && panel_pos_x >= start_pos_x && (panel_pos_x < candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y <= candidate_pos_y)) ) - || ( tab_backward && panel_pos_x <= start_pos_x && (panel_pos_x > candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y >= candidate_pos_y)) ) ) - { - tab_panel = i; - tab_panel_pos = candidate_pos = panel_pos; - } - } - if (tab_panel != -1) - break; - if (k == LEVELS_NUM) //tab_panel not found - { - reset_tab_panels(); - if (old_tab_panel == -2) //this prevents an infinite loop (should not happen normally) - { - tab_panel = -1; - return true; - } - starting_panel = old_tab_panel; - old_tab_panel = -2; - goto find_tab_panel; //u must find tab_panel! - } - if (!tab_backward) - { - level = mod(level + level_height, vid_conheight); - start_pos_x = 0; - candidate_pos_x = vid_conwidth; - } - else - { - level = mod(level - level_height, vid_conheight); - start_pos_x = vid_conwidth; - candidate_pos_x = 0; - } - } - - tab_panels[tab_panel] = tab_panel; - } - else if(nPrimary == K_SPACE && hudShiftState & S_CTRL) // enable/disable highlighted panel or dock - { - if (bInputType == 1 || mouseClicked) - return true; - - if (highlightedPanel != -1) - { - HUD_Panel_GetName(highlightedPanel); - cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled))); - } - else - cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : ""); - } - else if(nPrimary == 'c' && hudShiftState & S_CTRL) // copy highlighted panel size - { - if (bInputType == 1 || mouseClicked) - return true; - - if (highlightedPanel != -1) - { - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - panel_size_copied = panel_size; - highlightedPanel_copied = highlightedPanel; - } - } - else if(nPrimary == 'v' && hudShiftState & S_CTRL) // past copied size on the highlighted panel - { - if (bInputType == 1 || mouseClicked) - return true; - - if (highlightedPanel_copied == -1 || highlightedPanel == -1) - return true; - - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - - // reduce size if it'd go beyond screen boundaries - vector tmp_size = panel_size_copied; - if (panel_pos_x + panel_size_copied_x > vid_conwidth) - tmp_size_x = vid_conwidth - panel_pos_x; - if (panel_pos_y + panel_size_copied_y > vid_conheight) - tmp_size_y = vid_conheight - panel_pos_y; - - if (panel_size == tmp_size) - return true; - - // backup first! - panel_pos_backup = panel_pos; - panel_size_backup = panel_size; - highlightedPanel_backup = highlightedPanel; - - s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight)); - HUD_Panel_GetName(highlightedPanel); - cvar_set(strcat("hud_panel_", panel_name, "_size"), s); - } - else if(nPrimary == 'z' && hudShiftState & S_CTRL) // undo last action - { - if (bInputType == 1 || mouseClicked) - return true; - //restore previous values - if (highlightedPanel_backup != -1) - { - HUD_Panel_GetName(highlightedPanel_backup); - s = strcat(ftos(panel_pos_backup_x/vid_conwidth), " ", ftos(panel_pos_backup_y/vid_conheight)); - cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); - s = strcat(ftos(panel_size_backup_x/vid_conwidth), " ", ftos(panel_size_backup_y/vid_conheight)); - cvar_set(strcat("hud_panel_", panel_name, "_size"), s); - highlightedPanel_backup = -1; - } - } - else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW) - { - if (bInputType == 1) - { - pressed_key_time = 0; - return true; - } - else if (pressed_key_time == 0) - pressed_key_time = time; - - if (!mouseClicked) - HUD_Panel_Arrow_Action(nPrimary); //move or resize panel - } - else if(nPrimary == K_ENTER || nPrimary == K_SPACE || nPrimary == K_KP_ENTER) - { - if (bInputType == 1) - return true; - if (highlightedPanel != -1) - HUD_Panel_EnableMenu(); - } - else if(hit_con_bind) - return false; - - return true; -} - -float HUD_Panel_Check_Mouse_Pos() -{ - float i, j, border; - - while(j < HUD_PANEL_NUM) - { - i = panel_order[j]; - j += 1; - - HUD_Panel_UpdatePosSizeForId(i); - - border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize - - // move - if(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) - { - return 1; - } - // resize from topleft border - 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) - { - return 2; - } - // resize from topright border - 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) - { - return 3; - } - // resize from bottomleft border - 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) - { - return 3; - } - // resize from bottomright border - 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) - { - return 2; - } - } - return 0; -} - -// move a panel to the beginning of the panel order array (which means it gets drawn last, on top of everything else) -void HUD_Panel_FirstInDrawQ(float id) -{ - float i; - var float place = -1; - // find out where in the array our current id is, save into place - for(i = 0; i < HUD_PANEL_NUM; ++i) - { - if(panel_order[i] == id) - { - place = i; - break; - } - } - // place last if we didn't find a place for it yet (probably new panel, or screwed up cvar) - if(place == -1) - place = HUD_PANEL_NUM - 1; - - // move all ids up by one step in the array until "place" - for(i = place; i > 0; --i) - { - panel_order[i] = panel_order[i-1]; - } - // now save the new top id - panel_order[0] = id; - - // let's save them into the cvar by some strcat trickery - string s; - for(i = 0; i < HUD_PANEL_NUM; ++i) - { - s = strcat(s, ftos(panel_order[i]), " "); - } - cvar_set("_hud_panelorder", s); - if(hud_panelorder_prev) - strunzone(hud_panelorder_prev); - hud_panelorder_prev = strzone(autocvar__hud_panelorder); // prevent HUD_Main from doing useless update, we already updated here -} - -void HUD_Panel_Highlight() -{ - float i, j, border; - - while(j < HUD_PANEL_NUM) - { - i = panel_order[j]; - j += 1; - - HUD_Panel_UpdatePosSizeForId(i); - - border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize - - // move - if(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) - { - highlightedPanel = i; - HUD_Panel_FirstInDrawQ(i); - highlightedAction = 1; - panel_click_distance = mousepos - panel_pos; - return; - } - // resize from topleft border - 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) - { - highlightedPanel = i; - HUD_Panel_FirstInDrawQ(i); - highlightedAction = 2; - resizeCorner = 1; - panel_click_distance = mousepos - panel_pos; - panel_click_resizeorigin = panel_pos + panel_size; - return; - } - // resize from topright border - 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) - { - highlightedPanel = i; - HUD_Panel_FirstInDrawQ(i); - highlightedAction = 2; - resizeCorner = 2; - panel_click_distance_x = panel_size_x - mousepos_x + panel_pos_x; - panel_click_distance_y = mousepos_y - panel_pos_y; - panel_click_resizeorigin = panel_pos + eY * panel_size_y; - return; - } - // resize from bottomleft border - 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) - { - highlightedPanel = i; - HUD_Panel_FirstInDrawQ(i); - highlightedAction = 2; - resizeCorner = 3; - panel_click_distance_x = mousepos_x - panel_pos_x; - panel_click_distance_y = panel_size_y - mousepos_y + panel_pos_y; - panel_click_resizeorigin = panel_pos + eX * panel_size_x; - return; - } - // resize from bottomright border - 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) - { - highlightedPanel = i; - HUD_Panel_FirstInDrawQ(i); - highlightedAction = 2; - resizeCorner = 4; - panel_click_distance = panel_size - mousepos + panel_pos; - panel_click_resizeorigin = panel_pos; - return; - } - } - highlightedPanel = -1; - highlightedAction = 0; -} - -void HUD_Panel_EnableMenu() -{ - menu_enabled = 2; - menu_enabled_time = time; - HUD_Panel_GetName(highlightedPanel); - localcmd("menu_showhudoptions ", panel_name, "\n"); -} -float mouse_over_panel; -void HUD_Panel_Mouse() -{ - // TODO: needs better check... is there any float that contains the current state of the menu? _menu_alpha isn't apparently updated the frame the menu gets enabled - if (autocvar__menu_alpha == 0 && time - menu_enabled_time > 0.5) - menu_enabled = 0; - - /* - print("menu_enabled: ", ftos(menu_enabled), "\n"); - print("Highlighted: ", ftos(highlightedPanel), "\n"); - print("Menu alpha: ", ftos(autocvar__menu_alpha), "\n"); - */ - - // instantly hide the editor cursor if we open the HUDExit dialog - // as hud_fade_alpha doesn't decrease to 0 in this case - // TODO: find a way to fade the cursor out even in this case - if(menu_enabled == 1 || (menu_enabled == 2 && !hud_fade_alpha)) - return; - - mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed; - - mousepos_x = bound(0, mousepos_x, vid_conwidth); - mousepos_y = bound(0, mousepos_y, vid_conheight); - - if(mouseClicked) - { - if(prevMouseClicked == 0) - { - if (tab_panel != -1) - { - //stop ctrl-tab selection - tab_panel = -1; - reset_tab_panels(); - } - HUD_Panel_Highlight(); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin - // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel - if (highlightedPanel != -1) - { - highlightedPanel_initial_pos = panel_pos; - highlightedPanel_initial_size = panel_size; - } - // doubleclick check - if (time - prevMouseClickedTime < 0.4 && highlightedPanel != -1 && prevMouseClickedPos == mousepos) - { - mouseClicked = 0; // to prevent spam, I guess. - HUD_Panel_EnableMenu(); - } - else - { - prevMouseClickedTime = time; - prevMouseClickedPos = mousepos; - } - } - else - HUD_Panel_UpdatePosSizeForId(highlightedPanel); - - if (highlightedPanel != -1) - { - drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .1, DRAWFLAG_NORMAL); - if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size) - { - hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions); - // backup! - panel_pos_backup = highlightedPanel_initial_pos; - panel_size_backup = highlightedPanel_initial_size; - highlightedPanel_backup = highlightedPanel; - } - else - // in case the clicked panel is inside another panel and we aren't - // moving it, avoid the immediate "fix" of its position/size - // (often unwanted and hateful) by disabling collisions check - hud_configure_checkcollisions = false; - } - - if(highlightedAction == 1) - HUD_Panel_SetPos(mousepos - panel_click_distance); - else if(highlightedAction == 2) - { - vector mySize; - if(resizeCorner == 1) { - mySize_x = panel_click_resizeorigin_x - (mousepos_x - panel_click_distance_x); - mySize_y = panel_click_resizeorigin_y - (mousepos_y - panel_click_distance_y); - } else if(resizeCorner == 2) { - mySize_x = mousepos_x + panel_click_distance_x - panel_click_resizeorigin_x; - mySize_y = panel_click_distance_y + panel_click_resizeorigin_y - mousepos_y; - } else if(resizeCorner == 3) { - mySize_x = panel_click_resizeorigin_x + panel_click_distance_x - mousepos_x; - mySize_y = mousepos_y + panel_click_distance_y - panel_click_resizeorigin_y; - } else { // resizeCorner == 4 - mySize_x = mousepos_x - (panel_click_resizeorigin_x - panel_click_distance_x); - mySize_y = mousepos_y - (panel_click_resizeorigin_y - panel_click_distance_y); - } - HUD_Panel_SetPosSize(mySize); - } - } - else - { - if(menu_enabled == 2) - mouse_over_panel = 0; - else - mouse_over_panel = HUD_Panel_Check_Mouse_Pos(); - if (mouse_over_panel && tab_panel == -1) - drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .1, DRAWFLAG_NORMAL); - } - // draw cursor after performing move/resize to have the panel pos/size updated before mouse_over_panel - const vector cursorsize = '32 32 0'; - - if(!mouse_over_panel) - drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); - else if(mouse_over_panel == 1) - drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_move.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); - else if(mouse_over_panel == 2) - drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); - else - drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize2.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); - - prevMouseClicked = mouseClicked; -} - // Weapon icons (#0) // float weaponspace[10]; diff --git a/qcsrc/client/hud_config.qc b/qcsrc/client/hud_config.qc new file mode 100644 index 000000000..5fca9d28f --- /dev/null +++ b/qcsrc/client/hud_config.qc @@ -0,0 +1,1096 @@ +#define HUD_Write(s) fputs(fh, s) +// q: quoted, n: not quoted +#define HUD_Write_Cvar_n(cvar) HUD_Write(strcat("seta ", cvar, " ", cvar_string(cvar), "\n")) +#define HUD_Write_Cvar_q(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n")) +#define HUD_Write_PanelCvar_n(cvar_suf) HUD_Write_Cvar_n(strcat("hud_panel_", panel_name, cvar_suf)) +#define HUD_Write_PanelCvar_q(cvar_suf) HUD_Write_Cvar_q(strcat("hud_panel_", panel_name, cvar_suf)) +// Save the config +void HUD_Panel_ExportCfg(string cfgname) +{ + float fh; + string filename = strcat("hud_", autocvar_hud_skin, "_", cfgname, ".cfg"); + fh = fopen(filename, FILE_WRITE); + if(fh >= 0) + { + HUD_Write_Cvar_q("hud_skin"); + HUD_Write_Cvar_q("hud_panel_bg"); + HUD_Write_Cvar_q("hud_panel_bg_color"); + HUD_Write_Cvar_q("hud_panel_bg_color_team"); + HUD_Write_Cvar_q("hud_panel_bg_alpha"); + HUD_Write_Cvar_q("hud_panel_bg_border"); + HUD_Write_Cvar_q("hud_panel_bg_padding"); + HUD_Write_Cvar_q("hud_panel_fg_alpha"); + HUD_Write("\n"); + + HUD_Write_Cvar_q("hud_dock"); + HUD_Write_Cvar_q("hud_dock_color"); + HUD_Write_Cvar_q("hud_dock_color_team"); + HUD_Write_Cvar_q("hud_dock_alpha"); + HUD_Write("\n"); + + HUD_Write_Cvar_q("hud_progressbar_alpha"); + HUD_Write_Cvar_q("hud_progressbar_strength_color"); + HUD_Write_Cvar_q("hud_progressbar_shield_color"); + HUD_Write_Cvar_q("hud_progressbar_health_color"); + HUD_Write_Cvar_q("hud_progressbar_armor_color"); + HUD_Write_Cvar_q("hud_progressbar_fuel_color"); + HUD_Write_Cvar_q("hud_progressbar_nexball_color"); + HUD_Write("\n"); + + HUD_Write_Cvar_q("_hud_panelorder"); + HUD_Write("\n"); + + HUD_Write_Cvar_q("hud_configure_grid"); + HUD_Write_Cvar_q("hud_configure_grid_xsize"); + HUD_Write_Cvar_q("hud_configure_grid_ysize"); + HUD_Write("\n"); + + HUD_Write_Cvar_q("scr_centerpos"); + HUD_Write("\n"); + + // common cvars for all panels + float i; + for (i = 0; i < HUD_PANEL_NUM; ++i) + { + HUD_Panel_GetName(i); + + HUD_Write_PanelCvar_n(""); + HUD_Write_PanelCvar_q("_pos"); + HUD_Write_PanelCvar_q("_size"); + HUD_Write_PanelCvar_q("_bg"); + HUD_Write_PanelCvar_q("_bg_color"); + HUD_Write_PanelCvar_q("_bg_color_team"); + HUD_Write_PanelCvar_q("_bg_alpha"); + HUD_Write_PanelCvar_q("_bg_border"); + HUD_Write_PanelCvar_q("_bg_padding"); + switch(i) { + case HUD_PANEL_WEAPONS: + HUD_Write_PanelCvar_q("_complainbubble"); + HUD_Write_PanelCvar_q("_complainbubble_padding"); + HUD_Write_PanelCvar_q("_complainbubble_color_outofammo"); + HUD_Write_PanelCvar_q("_complainbubble_color_donthave"); + HUD_Write_PanelCvar_q("_complainbubble_color_unavailable"); + HUD_Write_PanelCvar_q("_ammo_color"); + HUD_Write_PanelCvar_q("_ammo_alpha"); + HUD_Write_PanelCvar_q("_aspect"); + HUD_Write_PanelCvar_q("_timeout"); + HUD_Write_PanelCvar_q("_timeout_effect"); + break; + case HUD_PANEL_AMMO: + HUD_Write_PanelCvar_q("_onlycurrent"); + HUD_Write_PanelCvar_q("_iconalign"); + HUD_Write_PanelCvar_q("_progressbar"); + HUD_Write_PanelCvar_q("_progressbar_name"); + HUD_Write_PanelCvar_q("_progressbar_xoffset"); + HUD_Write_PanelCvar_q("_text"); + break; + case HUD_PANEL_POWERUPS: + HUD_Write_PanelCvar_q("_flip"); + HUD_Write_PanelCvar_q("_iconalign"); + HUD_Write_PanelCvar_q("_baralign"); + HUD_Write_PanelCvar_q("_progressbar"); + HUD_Write_PanelCvar_q("_progressbar_strength"); + HUD_Write_PanelCvar_q("_progressbar_shield"); + break; + case HUD_PANEL_HEALTHARMOR: + HUD_Write_PanelCvar_q("_flip"); + HUD_Write_PanelCvar_q("_iconalign"); + HUD_Write_PanelCvar_q("_baralign"); + HUD_Write_PanelCvar_q("_progressbar"); + HUD_Write_PanelCvar_q("_progressbar_health"); + HUD_Write_PanelCvar_q("_progressbar_armor"); + HUD_Write_PanelCvar_q("_text"); + break; + case HUD_PANEL_NOTIFY: + HUD_Write_PanelCvar_q("_flip"); + HUD_Write_PanelCvar_q("_print"); + break; + case HUD_PANEL_RADAR: + HUD_Write_PanelCvar_q("_foreground_alpha"); + break; + case HUD_PANEL_VOTE: + HUD_Write_PanelCvar_q("_alreadyvoted_alpha"); + break; + case HUD_PANEL_PRESSEDKEYS: + HUD_Write_PanelCvar_q("_aspect"); + break; + case HUD_PANEL_INFOMESSAGES: + HUD_Write_PanelCvar_q("_flip"); + break; + case HUD_PANEL_PHYSICS: + HUD_Write_PanelCvar_q("_flip"); + HUD_Write_PanelCvar_q("_baralign"); + HUD_Write_PanelCvar_q("_progressbar"); + break; + } + HUD_Write("\n"); + } + HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated + + print("^2Successfully exported to ", filename, "! (Note: It's saved in data/data/)\n"); + fclose(fh); + } + else + print("^1Couldn't write to ", filename, "\n"); +} + +// check if move will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector +vector HUD_Panel_CheckMove(vector myPos, vector mySize) +{ + float i; + float myCenter_x, myCenter_y, targCenter_x, targCenter_y; + vector myTarget; + myTarget = myPos; + + for (i = 0; i < HUD_PANEL_NUM; ++i) { + if(i == highlightedPanel || !panel_enabled) + continue; + + HUD_Panel_UpdatePosSizeForId(i); + + panel_pos -= '1 1 0' * panel_bg_border; + panel_size += '2 2 0' * panel_bg_border; + + if(myPos_y + mySize_y < panel_pos_y) + continue; + if(myPos_y > panel_pos_y + panel_size_y) + continue; + + if(myPos_x + mySize_x < panel_pos_x) + continue; + if(myPos_x > panel_pos_x + panel_size_x) + continue; + + // OK, there IS a collision. + + myCenter_x = myPos_x + 0.5 * mySize_x; + myCenter_y = myPos_y + 0.5 * mySize_y; + + targCenter_x = panel_pos_x + 0.5 * panel_size_x; + targCenter_y = panel_pos_y + 0.5 * panel_size_y; + + if(myCenter_x < targCenter_x && myCenter_y < targCenter_y) // top left (of the target panel) + { + if(myPos_x + mySize_x - panel_pos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side + myTarget_x = panel_pos_x - mySize_x; + else // push it upwards + myTarget_y = panel_pos_y - mySize_y; + } + else if(myCenter_x > targCenter_x && myCenter_y < targCenter_y) // top right + { + if(panel_pos_x + panel_size_x - myPos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side + myTarget_x = panel_pos_x + panel_size_x; + else // push it upwards + myTarget_y = panel_pos_y - mySize_y; + } + else if(myCenter_x < targCenter_x && myCenter_y > targCenter_y) // bottom left + { + if(myPos_x + mySize_x - panel_pos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side + myTarget_x = panel_pos_x - mySize_x; + else // push it downwards + myTarget_y = panel_pos_y + panel_size_y; + } + else if(myCenter_x > targCenter_x && myCenter_y > targCenter_y) // bottom right + { + if(panel_pos_x + panel_size_x - myPos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side + myTarget_x = panel_pos_x + panel_size_x; + else // push it downwards + myTarget_y = panel_pos_y + panel_size_y; + } + //if(cvar("hud_configure_checkcollisions_debug")) + //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL); + } + + return myTarget; +} + +void HUD_Panel_SetPos(vector pos) +{ + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + vector mySize; + mySize = panel_size; + + //if(cvar("hud_configure_checkcollisions_debug")) + //drawfill(pos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL); + + if(autocvar_hud_configure_grid) + { + pos_x = floor((pos_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x; + pos_y = floor((pos_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y; + } + + if(hud_configure_checkcollisions) + pos = HUD_Panel_CheckMove(pos, mySize); + + pos_x = bound(0, pos_x, vid_conwidth - mySize_x); + pos_y = bound(0, pos_y, vid_conheight - mySize_y); + + string s; + s = strcat(ftos(pos_x/vid_conwidth), " ", ftos(pos_y/vid_conheight)); + + HUD_Panel_GetName(highlightedPanel); + cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); +} + +// check if resize will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector +vector HUD_Panel_CheckResize(vector mySize, vector resizeorigin) { + float i; + + vector targEndPos; + + float dist_x, dist_y; + float ratio; + ratio = mySize_x/mySize_y; + + for (i = 0; i < HUD_PANEL_NUM; ++i) { + if(i == highlightedPanel || !panel_enabled) + continue; + + HUD_Panel_UpdatePosSizeForId(i); + + panel_pos -= '1 1 0' * panel_bg_border; + panel_size += '2 2 0' * panel_bg_border; + + targEndPos = panel_pos + panel_size; + + // resizeorigin is WITHIN target panel, just abort any collision testing against that particular panel to produce expected behaviour! + if(resizeorigin_x > panel_pos_x && resizeorigin_x < targEndPos_x && resizeorigin_y > panel_pos_y && resizeorigin_y < targEndPos_y) + continue; + + if (resizeCorner == 1) + { + // check if this panel is on our way + if (resizeorigin_x <= panel_pos_x) + continue; + if (resizeorigin_y <= panel_pos_y) + continue; + if (targEndPos_x <= resizeorigin_x - mySize_x) + continue; + if (targEndPos_y <= resizeorigin_y - mySize_y) + continue; + + // there is a collision: + // detect which side of the panel we are facing is actually limiting the resizing + // (which side the resize direction finds for first) and reduce the size up to there + // + // dist is the distance between resizeorigin and the "analogous" point of the panel + // in this case between resizeorigin (bottom-right point) and the bottom-right point of the panel + dist_x = resizeorigin_x - targEndPos_x; + dist_y = resizeorigin_y - targEndPos_y; + if (dist_y <= 0 || dist_x / dist_y > ratio) + mySize_x = min(mySize_x, dist_x); + else + mySize_y = min(mySize_y, dist_y); + } + else if (resizeCorner == 2) + { + if (resizeorigin_x >= targEndPos_x) + continue; + if (resizeorigin_y <= panel_pos_y) + continue; + if (panel_pos_x >= resizeorigin_x + mySize_x) + continue; + if (targEndPos_y <= resizeorigin_y - mySize_y) + continue; + + dist_x = panel_pos_x - resizeorigin_x; + dist_y = resizeorigin_y - targEndPos_y; + if (dist_y <= 0 || dist_x / dist_y > ratio) + mySize_x = min(mySize_x, dist_x); + else + mySize_y = min(mySize_y, dist_y); + } + else if (resizeCorner == 3) + { + if (resizeorigin_x <= panel_pos_x) + continue; + if (resizeorigin_y >= targEndPos_y) + continue; + if (targEndPos_x <= resizeorigin_x - mySize_x) + continue; + if (panel_pos_y >= resizeorigin_y + mySize_y) + continue; + + dist_x = resizeorigin_x - targEndPos_x; + dist_y = panel_pos_y - resizeorigin_y; + if (dist_y <= 0 || dist_x / dist_y > ratio) + mySize_x = min(mySize_x, dist_x); + else + mySize_y = min(mySize_y, dist_y); + } + else if (resizeCorner == 4) + { + if (resizeorigin_x >= targEndPos_x) + continue; + if (resizeorigin_y >= targEndPos_y) + continue; + if (panel_pos_x >= resizeorigin_x + mySize_x) + continue; + if (panel_pos_y >= resizeorigin_y + mySize_y) + continue; + + dist_x = panel_pos_x - resizeorigin_x; + dist_y = panel_pos_y - resizeorigin_y; + if (dist_y <= 0 || dist_x / dist_y > ratio) + mySize_x = min(mySize_x, dist_x); + else + mySize_y = min(mySize_y, dist_y); + } + //if(cvar("hud_configure_checkcollisions_debug")) + //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL); + } + + return mySize; +} + +void HUD_Panel_SetPosSize(vector mySize) +{ + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + vector resizeorigin; + resizeorigin = panel_click_resizeorigin; + vector myPos; + + // minimum panel size cap + mySize_x = max(0.025 * vid_conwidth, mySize_x); + mySize_y = max(0.025 * vid_conheight, mySize_y); + + 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. + { + mySize_x = max(17 * autocvar_con_chatsize, mySize_x); + mySize_y = max(2 * autocvar_con_chatsize + 2 * panel_bg_padding, mySize_y); + } + + // collision testing| + // -----------------+ + + // we need to know pos at this stage, but it might still change later if we hit a screen edge/other panel (?) + if(resizeCorner == 1) { + myPos_x = resizeorigin_x - mySize_x; + myPos_y = resizeorigin_y - mySize_y; + } else if(resizeCorner == 2) { + myPos_x = resizeorigin_x; + myPos_y = resizeorigin_y - mySize_y; + } else if(resizeCorner == 3) { + myPos_x = resizeorigin_x - mySize_x; + myPos_y = resizeorigin_y; + } else { // resizeCorner == 4 + myPos_x = resizeorigin_x; + myPos_y = resizeorigin_y; + } + + // left/top screen edges + if(myPos_x < 0) + mySize_x = mySize_x + myPos_x; + if(myPos_y < 0) + mySize_y = mySize_y + myPos_y; + + // bottom/right screen edges + if(myPos_x + mySize_x > vid_conwidth) + mySize_x = vid_conwidth - myPos_x; + if(myPos_y + mySize_y > vid_conheight) + mySize_y = vid_conheight - myPos_y; + + //if(cvar("hud_configure_checkcollisions_debug")) + //drawfill(myPos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL); + + // before checkresize, otherwise panel can be snapped partially inside another panel or panel aspect ratio can be broken + if(autocvar_hud_configure_grid) + { + mySize_x = floor((mySize_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x; + mySize_y = floor((mySize_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y; + } + + if(hud_configure_checkcollisions) + mySize = HUD_Panel_CheckResize(mySize, resizeorigin); + + // 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) + mySize_x = max(0.025 * vid_conwidth, mySize_x); + mySize_y = max(0.025 * vid_conheight, mySize_y); + + // do another pos check, as size might have changed by now + if(resizeCorner == 1) { + myPos_x = resizeorigin_x - mySize_x; + myPos_y = resizeorigin_y - mySize_y; + } else if(resizeCorner == 2) { + myPos_x = resizeorigin_x; + myPos_y = resizeorigin_y - mySize_y; + } else if(resizeCorner == 3) { + myPos_x = resizeorigin_x - mySize_x; + myPos_y = resizeorigin_y; + } else { // resizeCorner == 4 + myPos_x = resizeorigin_x; + myPos_y = resizeorigin_y; + } + + //if(cvar("hud_configure_checkcollisions_debug")) + //drawfill(myPos, mySize, '0 1 0', .3, DRAWFLAG_NORMAL); + + HUD_Panel_GetName(highlightedPanel); + string s; + s = strcat(ftos(mySize_x/vid_conwidth), " ", ftos(mySize_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_size"), s); + + s = strcat(ftos(myPos_x/vid_conwidth), " ", ftos(myPos_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); +} + +float pressed_key_time; +vector highlightedPanel_initial_pos, highlightedPanel_initial_size; +void HUD_Panel_Arrow_Action(float nPrimary) +{ + if (highlightedPanel == -1) + return; + + hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions); + + float step; + if(autocvar_hud_configure_grid) + { + if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW) + { + if (hudShiftState & S_SHIFT) + step = hud_configure_realGridSize_y; + else + step = 2 * hud_configure_realGridSize_y; + } + else + { + if (hudShiftState & S_SHIFT) + step = hud_configure_realGridSize_x; + else + step = 2 * hud_configure_realGridSize_x; + } + } + else + { + if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW) + step = vid_conheight; + else + step = vid_conwidth; + if (hudShiftState & S_SHIFT) + step = (step / 256); // more precision + else + step = (step / 64) * (1 + 2 * (time - pressed_key_time)); + } + + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + + highlightedPanel_initial_pos = panel_pos; + highlightedPanel_initial_size = panel_size; + + if (hudShiftState & S_ALT) // resize + { + highlightedAction = 1; + if(nPrimary == K_UPARROW) + resizeCorner = 1; + else if(nPrimary == K_RIGHTARROW) + resizeCorner = 2; + else if(nPrimary == K_LEFTARROW) + resizeCorner = 3; + else // if(nPrimary == K_DOWNARROW) + resizeCorner = 4; + + // ctrl+arrow reduces the size, instead of increasing it + // Note that ctrl disables collisions check too, but it's fine + // since we don't collide with anything reducing the size + if (hudShiftState & S_CTRL) { + step = -step; + resizeCorner = 5 - resizeCorner; + } + + vector mySize; + mySize = panel_size; + panel_click_resizeorigin = panel_pos; + if(resizeCorner == 1) { + panel_click_resizeorigin += mySize; + mySize_y += step; + } else if(resizeCorner == 2) { + panel_click_resizeorigin_y += mySize_y; + mySize_x += step; + } else if(resizeCorner == 3) { + panel_click_resizeorigin_x += mySize_x; + mySize_x += step; + } else { // resizeCorner == 4 + mySize_y += step; + } + HUD_Panel_SetPosSize(mySize); + } + else // move + { + highlightedAction = 2; + vector pos; + pos = panel_pos; + if(nPrimary == K_UPARROW) + pos_y -= step; + else if(nPrimary == K_DOWNARROW) + pos_y += step; + else if(nPrimary == K_LEFTARROW) + pos_x -= step; + else // if(nPrimary == K_RIGHTARROW) + pos_x += step; + + HUD_Panel_SetPos(pos); + } + + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + + if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size) + { + // backup! + panel_pos_backup = highlightedPanel_initial_pos; + panel_size_backup = highlightedPanel_initial_size; + highlightedPanel_backup = highlightedPanel; + } +} + +float mouseClicked; +float prevMouseClicked; // previous state +float prevMouseClickedTime; // time during previous mouse click, to check for doubleclicks +vector prevMouseClickedPos; // pos during previous mouse click, to check for doubleclicks + +void HUD_Panel_EnableMenu(); +float tab_panels[HUD_PANEL_NUM]; +float tab_panel, tab_backward; +vector tab_panel_pos; +void HUD_Panel_FirstInDrawQ(float id); +void reset_tab_panels() +{ + int i; + for(i = 0; i < HUD_PANEL_NUM; ++i) + tab_panels[i] = -1; +} +float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary) +{ + string s; + + if(!autocvar__hud_configure) + return false; + + // allow console bind to work + string con_keys; + float keys; + con_keys = findkeysforcommand("toggleconsole"); + keys = tokenize(con_keys); + + float hit_con_bind, i; + for (i = 0; i < keys; ++i) + { + if(nPrimary == stof(argv(i))) + hit_con_bind = 1; + } + + if(bInputType == 0) { + if(nPrimary == K_ALT) hudShiftState |= S_ALT; + if(nPrimary == K_CTRL) hudShiftState |= S_CTRL; + if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT; + } + else if(bInputType == 1) { + if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT); + if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL); + if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT); + } + + if(nPrimary == K_CTRL) + { + if (bInputType == 1) //ctrl has been released + { + if (tab_panel != -1) + { + //switch to selected panel + highlightedPanel = tab_panel; + highlightedAction = 0; + HUD_Panel_FirstInDrawQ(highlightedPanel); + } + tab_panel = -1; + reset_tab_panels(); + } + } + + if(nPrimary == K_MOUSE1) + { + if(bInputType == 0) { // key pressed + mouseClicked = 1; + return true; + } + else if(bInputType == 1) {// key released + mouseClicked = 0; + return true; + } + } + else if(nPrimary == K_ESCAPE) + { + if (bInputType == 1) + return true; + menu_enabled = 1; + menu_enabled_time = time; + localcmd("menu_showhudexit\n"); + } + else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // select and highlight another panel + { + if (bInputType == 1 || mouseClicked) + return true; + + //FIXME: if a panel is highlighted, has the same pos_x and lays in the same level + //of other panels then next consecutive ctrl-tab will select the highlighted panel too + //(it should only after every other panel of the hud) + //It's a minor bug anyway, we can live with it + + float starting_panel; + float old_tab_panel = tab_panel; + if (tab_panel == -1) //first press of TAB + { + if (highlightedPanel != -1) + HUD_Panel_UpdatePosSizeForId(highlightedPanel) + else + panel_pos = '0 0 0'; + starting_panel = highlightedPanel; //can be -1, it means no starting panel + tab_panel_pos = panel_pos; //to compute level + } + else + { + if ( ((!tab_backward) && (hudShiftState & S_SHIFT)) || (tab_backward && !(hudShiftState & S_SHIFT)) ) //tab direction changed? + reset_tab_panels(); + starting_panel = tab_panel; + } + tab_backward = (hudShiftState & S_SHIFT); + + float k, level, start_pos_x; + vector candidate_pos; + const float LEVELS_NUM = 4; + const float level_height = vid_conheight / LEVELS_NUM; +:find_tab_panel + level = floor(tab_panel_pos_y / level_height) * level_height; //starting level + candidate_pos_x = (!tab_backward) ? vid_conwidth : 0; + start_pos_x = tab_panel_pos_x; + tab_panel = -1; + k=0; + while(++k) + { + for(i = 0; i < HUD_PANEL_NUM; ++i) + { + if (i == tab_panels[i] || i == starting_panel) + continue; + HUD_Panel_UpdatePosSizeForId(i) + if (panel_pos_y >= level && (panel_pos_y - level) < level_height) + if ( ( !tab_backward && panel_pos_x >= start_pos_x && (panel_pos_x < candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y <= candidate_pos_y)) ) + || ( tab_backward && panel_pos_x <= start_pos_x && (panel_pos_x > candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y >= candidate_pos_y)) ) ) + { + tab_panel = i; + tab_panel_pos = candidate_pos = panel_pos; + } + } + if (tab_panel != -1) + break; + if (k == LEVELS_NUM) //tab_panel not found + { + reset_tab_panels(); + if (old_tab_panel == -2) //this prevents an infinite loop (should not happen normally) + { + tab_panel = -1; + return true; + } + starting_panel = old_tab_panel; + old_tab_panel = -2; + goto find_tab_panel; //u must find tab_panel! + } + if (!tab_backward) + { + level = mod(level + level_height, vid_conheight); + start_pos_x = 0; + candidate_pos_x = vid_conwidth; + } + else + { + level = mod(level - level_height, vid_conheight); + start_pos_x = vid_conwidth; + candidate_pos_x = 0; + } + } + + tab_panels[tab_panel] = tab_panel; + } + else if(nPrimary == K_SPACE && hudShiftState & S_CTRL) // enable/disable highlighted panel or dock + { + if (bInputType == 1 || mouseClicked) + return true; + + if (highlightedPanel != -1) + { + HUD_Panel_GetName(highlightedPanel); + cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled))); + } + else + cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : ""); + } + else if(nPrimary == 'c' && hudShiftState & S_CTRL) // copy highlighted panel size + { + if (bInputType == 1 || mouseClicked) + return true; + + if (highlightedPanel != -1) + { + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + panel_size_copied = panel_size; + highlightedPanel_copied = highlightedPanel; + } + } + else if(nPrimary == 'v' && hudShiftState & S_CTRL) // past copied size on the highlighted panel + { + if (bInputType == 1 || mouseClicked) + return true; + + if (highlightedPanel_copied == -1 || highlightedPanel == -1) + return true; + + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + + // reduce size if it'd go beyond screen boundaries + vector tmp_size = panel_size_copied; + if (panel_pos_x + panel_size_copied_x > vid_conwidth) + tmp_size_x = vid_conwidth - panel_pos_x; + if (panel_pos_y + panel_size_copied_y > vid_conheight) + tmp_size_y = vid_conheight - panel_pos_y; + + if (panel_size == tmp_size) + return true; + + // backup first! + panel_pos_backup = panel_pos; + panel_size_backup = panel_size; + highlightedPanel_backup = highlightedPanel; + + s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight)); + HUD_Panel_GetName(highlightedPanel); + cvar_set(strcat("hud_panel_", panel_name, "_size"), s); + } + else if(nPrimary == 'z' && hudShiftState & S_CTRL) // undo last action + { + if (bInputType == 1 || mouseClicked) + return true; + //restore previous values + if (highlightedPanel_backup != -1) + { + HUD_Panel_GetName(highlightedPanel_backup); + s = strcat(ftos(panel_pos_backup_x/vid_conwidth), " ", ftos(panel_pos_backup_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); + s = strcat(ftos(panel_size_backup_x/vid_conwidth), " ", ftos(panel_size_backup_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_size"), s); + highlightedPanel_backup = -1; + } + } + else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW) + { + if (bInputType == 1) + { + pressed_key_time = 0; + return true; + } + else if (pressed_key_time == 0) + pressed_key_time = time; + + if (!mouseClicked) + HUD_Panel_Arrow_Action(nPrimary); //move or resize panel + } + else if(nPrimary == K_ENTER || nPrimary == K_SPACE || nPrimary == K_KP_ENTER) + { + if (bInputType == 1) + return true; + if (highlightedPanel != -1) + HUD_Panel_EnableMenu(); + } + else if(hit_con_bind) + return false; + + return true; +} + +float HUD_Panel_Check_Mouse_Pos() +{ + float i, j, border; + + while(j < HUD_PANEL_NUM) + { + i = panel_order[j]; + j += 1; + + HUD_Panel_UpdatePosSizeForId(i); + + border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize + + // move + if(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) + { + return 1; + } + // resize from topleft border + 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) + { + return 2; + } + // resize from topright border + 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) + { + return 3; + } + // resize from bottomleft border + 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) + { + return 3; + } + // resize from bottomright border + 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) + { + return 2; + } + } + return 0; +} + +// move a panel to the beginning of the panel order array (which means it gets drawn last, on top of everything else) +void HUD_Panel_FirstInDrawQ(float id) +{ + float i; + var float place = -1; + // find out where in the array our current id is, save into place + for(i = 0; i < HUD_PANEL_NUM; ++i) + { + if(panel_order[i] == id) + { + place = i; + break; + } + } + // place last if we didn't find a place for it yet (probably new panel, or screwed up cvar) + if(place == -1) + place = HUD_PANEL_NUM - 1; + + // move all ids up by one step in the array until "place" + for(i = place; i > 0; --i) + { + panel_order[i] = panel_order[i-1]; + } + // now save the new top id + panel_order[0] = id; + + // let's save them into the cvar by some strcat trickery + string s; + for(i = 0; i < HUD_PANEL_NUM; ++i) + { + s = strcat(s, ftos(panel_order[i]), " "); + } + cvar_set("_hud_panelorder", s); + if(hud_panelorder_prev) + strunzone(hud_panelorder_prev); + hud_panelorder_prev = strzone(autocvar__hud_panelorder); // prevent HUD_Main from doing useless update, we already updated here +} + +void HUD_Panel_Highlight() +{ + float i, j, border; + + while(j < HUD_PANEL_NUM) + { + i = panel_order[j]; + j += 1; + + HUD_Panel_UpdatePosSizeForId(i); + + border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize + + // move + if(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) + { + highlightedPanel = i; + HUD_Panel_FirstInDrawQ(i); + highlightedAction = 1; + panel_click_distance = mousepos - panel_pos; + return; + } + // resize from topleft border + 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) + { + highlightedPanel = i; + HUD_Panel_FirstInDrawQ(i); + highlightedAction = 2; + resizeCorner = 1; + panel_click_distance = mousepos - panel_pos; + panel_click_resizeorigin = panel_pos + panel_size; + return; + } + // resize from topright border + 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) + { + highlightedPanel = i; + HUD_Panel_FirstInDrawQ(i); + highlightedAction = 2; + resizeCorner = 2; + panel_click_distance_x = panel_size_x - mousepos_x + panel_pos_x; + panel_click_distance_y = mousepos_y - panel_pos_y; + panel_click_resizeorigin = panel_pos + eY * panel_size_y; + return; + } + // resize from bottomleft border + 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) + { + highlightedPanel = i; + HUD_Panel_FirstInDrawQ(i); + highlightedAction = 2; + resizeCorner = 3; + panel_click_distance_x = mousepos_x - panel_pos_x; + panel_click_distance_y = panel_size_y - mousepos_y + panel_pos_y; + panel_click_resizeorigin = panel_pos + eX * panel_size_x; + return; + } + // resize from bottomright border + 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) + { + highlightedPanel = i; + HUD_Panel_FirstInDrawQ(i); + highlightedAction = 2; + resizeCorner = 4; + panel_click_distance = panel_size - mousepos + panel_pos; + panel_click_resizeorigin = panel_pos; + return; + } + } + highlightedPanel = -1; + highlightedAction = 0; +} + +void HUD_Panel_EnableMenu() +{ + menu_enabled = 2; + menu_enabled_time = time; + HUD_Panel_GetName(highlightedPanel); + localcmd("menu_showhudoptions ", panel_name, "\n"); +} +float mouse_over_panel; +void HUD_Panel_Mouse() +{ + // TODO: needs better check... is there any float that contains the current state of the menu? _menu_alpha isn't apparently updated the frame the menu gets enabled + if (autocvar__menu_alpha == 0 && time - menu_enabled_time > 0.5) + menu_enabled = 0; + + /* + print("menu_enabled: ", ftos(menu_enabled), "\n"); + print("Highlighted: ", ftos(highlightedPanel), "\n"); + print("Menu alpha: ", ftos(autocvar__menu_alpha), "\n"); + */ + + // instantly hide the editor cursor if we open the HUDExit dialog + // as hud_fade_alpha doesn't decrease to 0 in this case + // TODO: find a way to fade the cursor out even in this case + if(menu_enabled == 1 || (menu_enabled == 2 && !hud_fade_alpha)) + return; + + mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed; + + mousepos_x = bound(0, mousepos_x, vid_conwidth); + mousepos_y = bound(0, mousepos_y, vid_conheight); + + if(mouseClicked) + { + if(prevMouseClicked == 0) + { + if (tab_panel != -1) + { + //stop ctrl-tab selection + tab_panel = -1; + reset_tab_panels(); + } + HUD_Panel_Highlight(); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin + // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel + if (highlightedPanel != -1) + { + highlightedPanel_initial_pos = panel_pos; + highlightedPanel_initial_size = panel_size; + } + // doubleclick check + if (time - prevMouseClickedTime < 0.4 && highlightedPanel != -1 && prevMouseClickedPos == mousepos) + { + mouseClicked = 0; // to prevent spam, I guess. + HUD_Panel_EnableMenu(); + } + else + { + prevMouseClickedTime = time; + prevMouseClickedPos = mousepos; + } + } + else + HUD_Panel_UpdatePosSizeForId(highlightedPanel); + + if (highlightedPanel != -1) + { + drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .1, DRAWFLAG_NORMAL); + if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size) + { + hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions); + // backup! + panel_pos_backup = highlightedPanel_initial_pos; + panel_size_backup = highlightedPanel_initial_size; + highlightedPanel_backup = highlightedPanel; + } + else + // in case the clicked panel is inside another panel and we aren't + // moving it, avoid the immediate "fix" of its position/size + // (often unwanted and hateful) by disabling collisions check + hud_configure_checkcollisions = false; + } + + if(highlightedAction == 1) + HUD_Panel_SetPos(mousepos - panel_click_distance); + else if(highlightedAction == 2) + { + vector mySize; + if(resizeCorner == 1) { + mySize_x = panel_click_resizeorigin_x - (mousepos_x - panel_click_distance_x); + mySize_y = panel_click_resizeorigin_y - (mousepos_y - panel_click_distance_y); + } else if(resizeCorner == 2) { + mySize_x = mousepos_x + panel_click_distance_x - panel_click_resizeorigin_x; + mySize_y = panel_click_distance_y + panel_click_resizeorigin_y - mousepos_y; + } else if(resizeCorner == 3) { + mySize_x = panel_click_resizeorigin_x + panel_click_distance_x - mousepos_x; + mySize_y = mousepos_y + panel_click_distance_y - panel_click_resizeorigin_y; + } else { // resizeCorner == 4 + mySize_x = mousepos_x - (panel_click_resizeorigin_x - panel_click_distance_x); + mySize_y = mousepos_y - (panel_click_resizeorigin_y - panel_click_distance_y); + } + HUD_Panel_SetPosSize(mySize); + } + } + else + { + if(menu_enabled == 2) + mouse_over_panel = 0; + else + mouse_over_panel = HUD_Panel_Check_Mouse_Pos(); + if (mouse_over_panel && tab_panel == -1) + drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .1, DRAWFLAG_NORMAL); + } + // draw cursor after performing move/resize to have the panel pos/size updated before mouse_over_panel + const vector cursorsize = '32 32 0'; + + if(!mouse_over_panel) + drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); + else if(mouse_over_panel == 1) + drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_move.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); + else if(mouse_over_panel == 2) + drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); + else + drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize2.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL); + + prevMouseClicked = mouseClicked; +} + +const float hlBorderSize = 4; +const string hlBorder = "gfx/hud/default/border_highlighted"; +const string hlBorder2 = "gfx/hud/default/border_highlighted2"; +void HUD_Panel_HlBorder(float myBorder, vector color, float alpha) +{ + drawfill(panel_pos - '1 1 0' * myBorder, panel_size + '2 2 0' * myBorder, '0 0.5 1', .5 * alpha, DRAWFLAG_NORMAL); + drawpic_tiled(panel_pos - '1 1 0' * myBorder, hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); + drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * (panel_size_y + 2 * myBorder - hlBorderSize), hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); + drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize, hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); + drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize + eX * (panel_size_x + 2 * myBorder - hlBorderSize), hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, alpha, DRAWFLAG_NORMAL); +} \ No newline at end of file diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 1334d7d3c..9ca35fbf8 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -38,6 +38,7 @@ teamplay.qc ctf.qc teamradar.qc +hud_config.qc hud.qc scoreboard.qc mapvoting.qc