From: FruitieX Date: Mon, 11 Apr 2011 12:56:27 +0000 (+0300) Subject: Merge remote-tracking branch 'origin/master' into terencehill/newpanelhud X-Git-Tag: xonotic-v0.5.0~307 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=df9569abb4918e69c083528206451f783af24eeb;p=xonotic%2Fxonotic-data.pk3dir.git Merge remote-tracking branch 'origin/master' into terencehill/newpanelhud Conflicts: defaultXonotic.cfg hud_luminos.cfg qcsrc/client/hud.qc --- df9569abb4918e69c083528206451f783af24eeb diff --cc defaultXonotic.cfg index ca87620ef,f7351e2fa..f0016dfcd --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@@ -1417,9 -1420,8 +1420,9 @@@ seta hud_panel_weapons_ammo_full_fuel 1 seta hud_panel_ammo_maxammo "40" "when you have this much ammo, the ammo status bar is full" - seta hud_panel_healtharmor_maxhealth "250" "when you have this much health, the health status bar is full" - seta hud_panel_healtharmor_maxarmor "150" "when you have this much armor, the armor status bar is full" + seta hud_panel_healtharmor_maxhealth "200" "when you have this much health, the health status bar is full" + seta hud_panel_healtharmor_maxarmor "200" "when you have this much armor, the armor status bar is full" +seta hud_panel_healtharmor_progressbar_gfx 1 "add graphic effects to the progressbars when spawning and when being damaged" seta hud_panel_notify_time 10 "time that a new entry stays until it fades out" seta hud_panel_notify_fadetime 3 "fade out time" diff --cc qcsrc/client/hud.qc index 44a10eed1,ce8b608fc..580637b65 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@@ -699,9 -1621,16 +708,9 @@@ void HUD_Weapons(void } float i, weapid, wpnalpha, weapon_cnt; - weapon_cnt = 0; - for(i = WEP_FIRST; i <= WEP_LAST; ++i) - { - self = get_weaponinfo(i); - if(self.impulse >= 0) - ++weapon_cnt; - } // TODO make this configurable - if(weaponorder_bypriority != autocvar_cl_weaponpriority) + if(weaponorder_bypriority != autocvar_cl_weaponpriority || !weaponorder[0]) { if(weaponorder_bypriority) strunzone(weaponorder_bypriority); @@@ -4252,185 -5055,64 +4261,185 @@@ void HUD_Physics(void break; } - speed = strcat(ftos(floor( vlen(pmove_vel - pmove_vel_z * '0 0 1') * conversion_factor + 0.5 )), unit); + float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 ); + if (autocvar__hud_configure) + speed = floor( max_speed * 0.65 + 0.5 ); + else if(autocvar_hud_panel_physics_speed_vertical) + speed = floor( vlen(pmove_vel) * conversion_factor + 0.5 ); + else + speed = floor( vlen(pmove_vel - pmove_vel_z * '0 0 1') * conversion_factor + 0.5 ); - numsize_x = numsize_y = autocvar_cl_showspeed_size; - pos = (vid_conheight - numsize_y) * autocvar_cl_showspeed_position; + //compute acceleration + float acceleration, f; + if (autocvar__hud_configure) + acceleration = autocvar_hud_panel_physics_acceleration_max * 0.3; + else + { + // 1 m/s = 0.0254 qu/s; 1 g = 9.80665 m/s^2 + f = time - acc_prevtime; + if(autocvar_hud_panel_physics_acceleration_vertical) + acceleration = (vlen(pmove_vel) - vlen(acc_prevspeed)) * (1 / f) * (0.0254 / 9.80665); + else + acceleration = (vlen(pmove_vel - '0 0 1' * pmove_vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z)) * (1 / f) * (0.0254 / 9.80665); + acc_prevspeed = pmove_vel; + acc_prevtime = time; - drawstringcenter(eX + pos * eY, speed, numsize, '1 1 1', autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL); + f = bound(0, f * 10, 1); + acc_avg = acc_avg * (1 - f) + acceleration * f; + } - if (autocvar_cl_showspeed_z == 1) { - zspeed = strcat(ftos(fabs(floor( pmove_vel_z * conversion_factor + 0.5 ))), unit); - drawstringcenter(eX + pos * eY + numsize_y * eY, zspeed, numsize * 0.5, '1 1 1', autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL); + //compute layout + float panel_ar = panel_size_x/panel_size_y; + vector speed_offset, acceleration_offset; + if (panel_ar >= 5) + { + panel_size_x *= 0.5; + if (autocvar_hud_panel_physics_flip) + speed_offset_x = panel_size_x; + else + acceleration_offset_x = panel_size_x; } -} + else + { + panel_size_y *= 0.5; + if (autocvar_hud_panel_physics_flip) + speed_offset_y = panel_size_y; + else + acceleration_offset_y = panel_size_y; + } + float speed_baralign, acceleration_baralign; + if (autocvar_hud_panel_physics_baralign == 1) + acceleration_baralign = speed_baralign = 1; + else if(autocvar_hud_panel_physics_baralign == 4) + acceleration_baralign = speed_baralign = 2; + else if (autocvar_hud_panel_physics_flip) + { + acceleration_baralign = (autocvar_hud_panel_physics_baralign == 2); + speed_baralign = (autocvar_hud_panel_physics_baralign == 3); + } + else + { + speed_baralign = (autocvar_hud_panel_physics_baralign == 2); + acceleration_baralign = (autocvar_hud_panel_physics_baralign == 3); + } + if (autocvar_hud_panel_physics_acceleration_progressbar_mode == 0) + acceleration_baralign = 3; //override hud_panel_physics_baralign value for acceleration -vector acc_prevspeed; -float acc_prevtime; -float acc_avg; + //draw speed + if(speed) + if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2) + { + HUD_Panel_GetProgressBarColor(speed); + HUD_Panel_DrawProgressBar(panel_pos + speed_offset, panel_size, "progressbar", speed/max_speed, 0, speed_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + } + vector tmp_offset, tmp_size; + if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2) + { + tmp_size_x = panel_size_x * 0.75; + tmp_size_y = panel_size_y; + if (speed_baralign) + tmp_offset_x = panel_size_x - tmp_size_x; + //else + //tmp_offset_x = 0; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); -void HUD_ShowAcceleration(void) -{ - float acceleration, sz, scale, alpha, f; - vector pos, top, rgb; - top_x = vid_conwidth/2; - top_y = 0; - - f = time - acc_prevtime; - if(autocvar_cl_showacceleration_z) - acceleration = (vlen(pmove_vel) - vlen(acc_prevspeed)) * (1 / f); - else - acceleration = (vlen(pmove_vel - '0 0 1' * pmove_vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z)) * (1 / f); - acc_prevspeed = pmove_vel; - acc_prevtime = time; - - f = bound(0, f * 10, 1); - acc_avg = acc_avg * (1 - f) + acceleration * f; - acceleration = acc_avg / getstatf(STAT_MOVEVARS_MAXSPEED); - if (acceleration == 0) - return; + //draw speed unit + if (speed_baralign) + tmp_offset_x = 0; + else + tmp_offset_x = tmp_size_x; + if (autocvar_hud_panel_physics_speed_unit_show) + { + //tmp_offset_y = 0; + tmp_size_x = panel_size_x * (1 - 0.75); + tmp_size_y = panel_size_y * 0.4; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, unit, tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + } + } - pos = top - sz/2 * eY + (autocvar_cl_showacceleration_position * vid_conheight) * eY; + //compute and draw top speed + if (autocvar_hud_panel_physics_topspeed) + if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2) + { + if (autocvar__hud_configure) + { + top_speed = floor( max_speed * 0.75 + 0.5 ); + f = 1; + } + else + { + if (speed >= top_speed) + { + top_speed = speed; + top_speed_time = time; + } + if (top_speed != 0) + { + f = max(1, autocvar_hud_panel_physics_topspeed_time); + // divide by f to make it start from 1 + f = cos( ((time - top_speed_time) / f) * PI/2 ); + } + else //hide top speed 0, it would be stupid + f = 0; + } + if (f > 0) + { + //top speed progressbar peak + if(speed < top_speed) + if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2) + { + float peak_offset_x; + vector peak_size; + if (speed_baralign == 0) + peak_offset_x = min(top_speed, max_speed)/max_speed * panel_size_x; + else if (speed_baralign == 1) + peak_offset_x = (1 - min(top_speed, max_speed)/max_speed) * panel_size_x; + else if (speed_baralign == 2) + peak_offset_x = min(top_speed, max_speed)/max_speed * panel_size_x * 0.5; + //if speed is not 0 the speed progressbar already fetched the color + if (speed == 0) + HUD_Panel_GetProgressBarColor(speed); + peak_size_x = floor(panel_size_x * 0.01 + 1.5); + peak_size_y = panel_size_y; + if (speed_baralign == 2) // draw two peaks, on both sides + { + drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size_x + peak_offset_x - peak_size_x), peak_size, progressbar_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size_x - peak_offset_x + peak_size_x), peak_size, progressbar_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + } + else + drawfill(panel_pos + speed_offset + eX * (peak_offset_x - peak_size_x), peak_size, progressbar_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + } - sz = autocvar_cl_showacceleration_size; - scale = autocvar_cl_showacceleration_scale; - alpha = autocvar_cl_showacceleration_alpha; - if (autocvar_cl_showacceleration_color_custom) - rgb = stov(autocvar_cl_showacceleration_color); - else { - if (acceleration < 0) - rgb = '1 .5 .5' - '0 .5 .5' * bound(0, -acceleration * 0.2, 1); + //top speed + tmp_offset_y = panel_size_y * 0.4; + tmp_size_x = panel_size_x * (1 - 0.75); + tmp_size_y = panel_size_y - tmp_offset_y; + drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(top_speed), tmp_size, '1 0 0', f * panel_fg_alpha, DRAWFLAG_NORMAL); + } else - rgb = '.5 1 .5' - '.5 0 .5' * bound(0, +acceleration * 0.2, 1); + top_speed = 0; } - if (acceleration > 0) - HUD_Panel_DrawProgressBar(pos, eX * (vid_conwidth - pos_x) + eY * sz, "accelbar", 0, 0, acceleration * scale, rgb, alpha * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); - else - HUD_Panel_DrawProgressBar(eY * pos_y, eX * pos_x + eY * sz, "accelbar", 0, 1, -acceleration * scale, rgb, alpha * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + //draw acceleration + if(acceleration) + if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 3) + { + if (acceleration < 0) + HUD_Panel_GetProgressBarColor(acceleration_neg); + else + HUD_Panel_GetProgressBarColor(acceleration); - HUD_Panel_DrawProgressBar(panel_pos + acceleration_offset, panel_size, "progressbar", acceleration/autocvar_hud_panel_physics_acceleration_max, 0, acceleration_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); ++ HUD_Panel_DrawProgressBar(panel_pos + acceleration_offset, panel_size, "accelbar", acceleration/autocvar_hud_panel_physics_acceleration_max, 0, acceleration_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL); + } + if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3) + drawstring_aspect(panel_pos + acceleration_offset, strcat(ftos_decimals(acceleration, 2), "g"), panel_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); } +/* +================== +Main HUD system +================== +*/ + void HUD_Reset (void) { // reset gametype specific icons diff --cc qcsrc/client/hud_config.qc index dd34ab71f,000000000..0923e4ed9 mode 100644,000000..100644 --- a/qcsrc/client/hud_config.qc +++ b/qcsrc/client/hud_config.qc @@@ -1,1114 -1,0 +1,1115 @@@ +#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("_fontsize"); + 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"); + HUD_Write_PanelCvar_q("_acceleration_mode"); + break; + } + HUD_Write("\n"); + } + HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated + + print(sprintf(_("^2Successfully exported to %s! (Note: It's saved in data/data/)\n"), filename)); + fclose(fh); + } + else + print(sprintf(_("^1Couldn't write to %s\n"), filename)); +} + +// 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; + } +} + +const float S_MOUSE1 = 1; +const float S_MOUSE2 = 2; +const float S_MOUSE3 = 4; +float mouseClicked; +float prevMouseClicked; // previous state +float prevMouseClickedTime; // time during previous left mouse click, to check for doubleclicks +vector prevMouseClickedPos; // pos during previous left 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 |= S_MOUSE1; + else if(bInputType == 1) // key released + mouseClicked -= (mouseClicked & S_MOUSE1); + } + else if(nPrimary == K_MOUSE2) + { + if(bInputType == 0) // key pressed + mouseClicked |= S_MOUSE2; + else if(bInputType == 1) // key released + mouseClicked -= (mouseClicked & S_MOUSE2); + } + 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_BACKSPACE && hudShiftState & S_CTRL) + { + if (bInputType == 1) + return true; + if (!menu_enabled) + cvar_set("_hud_configure", "0"); + } + 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 allow_move) +{ + 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(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) + { + 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 allow_move) +{ + 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(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) + { + 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(mouseClicked & S_MOUSE1); // 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 ((mouseClicked & S_MOUSE1) && time - prevMouseClickedTime < 0.4 && highlightedPanel != -1 && prevMouseClickedPos == mousepos) + { + mouseClicked = 0; // to prevent spam, I guess. + HUD_Panel_EnableMenu(); + } + else + { + if (mouseClicked & S_MOUSE1) + { + prevMouseClickedTime = time; + prevMouseClickedPos = mousepos; + } + mouse_over_panel = HUD_Panel_Check_Mouse_Pos(mouseClicked & S_MOUSE1); + } + } + 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(TRUE); + 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); - } ++}