mySize_y = 0.25; // 0.25 * width, trial and error...
break;
}
- if(!mySize_x && mySize_y)
- mySize_x = 1/mySize_y;
return mySize;
}
cvar_set(strcat("hud_", HUD_Panel_GetName(id), "_pos"), s);
}
-float HUD_Panel_CheckValidity_of_ResizeSuggestion(float id, vector mySize)
-{
- vector oldSize;
- oldSize = mySize;
-
- // copy pasta from SetPosSize:
- // minimum panel size cap
- mySize_x = max(0.025 * vid_conwidth, mySize_x);
- mySize_y = max(0.025 * vid_conheight, mySize_y);
-
- if(id == 12) // 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 * cvar("con_chatsize"), mySize_x);
- mySize_y = max(2 * cvar("con_chatsize") + 2 * HUD_Panel_GetPadding(id), mySize_y);
- }
-
- // cap against panel's own limits
- vector minSize;
- minSize = HUD_Panel_GetMinSize(id); // mySize_x at least minSize_x * mySize_y, and vice versa
-
- mySize_x = max(minSize_x * mySize_y, mySize_x);
- mySize_y = max(minSize_y * mySize_x, mySize_y);
-
- if(mySize == oldSize)
- return 1;
- else
- return 0;
-}
-
// 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(float id, vector myPos, vector mySize, vector resizeorigin)
-{
+vector HUD_Panel_CheckResize(float id, vector mySize, vector resizeorigin, float ratio) {
float i;
+ float targBorder;
vector targPos;
vector targSize;
- vector myCenter;
- vector targCenter;
- myCenter = '0 0 0'; // shut up fteqcc, there IS a reference
- targCenter = '0 0 0'; // shut up fteqcc, there IS a reference
+ vector targEndPos;
+ vector dist;
for (i = 0; i < HUD_PANEL_NUM; ++i) {
if(i == id || !HUD_Panel_CheckActive(i))
continue;
- targPos = HUD_Panel_GetPos(i) - '1 1 0' * HUD_Panel_GetBorder(id);
- targSize = HUD_Panel_GetSize(i) + '2 2 0' * HUD_Panel_GetBorder(id);
-
- if(myPos_y + mySize_y < targPos_y)
- continue;
- if(myPos_y > targPos_y + targSize_y)
- continue;
-
- if(myPos_x + mySize_x < targPos_x)
- continue;
- if(myPos_x > targPos_x + targSize_x)
- continue;
+ targBorder = HUD_Panel_GetBorder(i);
+ targPos = HUD_Panel_GetPos(i) - '1 1 0' * targBorder;
+ targSize = HUD_Panel_GetSize(i) + '2 2 0' * targBorder;
+ targEndPos = targPos + targSize;
- // OK, there IS a collision.
- //
-
- // Now check some special cases
- // If the resizeorigin is too close to the target panel on either axis, we do not want to perform any collision avoidance on that axis
- float Check_X, Check_Y;
- Check_X = Check_Y = 1;
- // check upper/left edges of targ panel
- if(fabs(targPos_x - resizeorigin_x) < 0.025 * vid_conwidth)
- Check_X = 0;
- if(fabs(targPos_y - resizeorigin_y) < 0.025 * vid_conheight)
- Check_Y = 0;
- // check lower/right edges of targ panel
- if(fabs(resizeorigin_x - (targPos_x + targSize_x)) < 0.025 * vid_conwidth)
- Check_X = 0;
- if(fabs(resizeorigin_y - (targPos_y + targSize_y)) < 0.025 * vid_conheight)
- Check_Y = 0;
-
- myCenter_x = myPos_x + 0.5 * mySize_x;
- myCenter_y = myPos_y + 0.5 * mySize_y;
-
- targCenter_x = targPos_x + 0.5 * targSize_x;
- targCenter_y = targPos_y + 0.5 * targSize_y;
-
- if(myCenter_x < targCenter_x && myCenter_y < targCenter_y) // top left (of target panel)
+ if (resizeCorner == 1)
{
- //if(!HUD_Panel_CheckValidity_of_ResizeSuggestion(id, eX * (targPos_x - myPos_x) + eY * (targPos_y - resizeorigin_y)))
- // continue;
+ // check if this panel is on our way
+ if (resizeorigin_x < targPos_x)
+ continue;
+ if (resizeorigin_y < targPos_y)
+ continue;
+ if (targEndPos_x < resizeorigin_x - mySize_x)
+ continue;
+ if (targEndPos_y < resizeorigin_y - mySize_y)
+ continue;
- if(myPos_x + mySize_x - targPos_x < myPos_y + mySize_y - targPos_y && Check_X) // push it to the side
- mySize_x = targPos_x - myPos_x;
- else if(Check_Y) // push it upwards
- mySize_y = targPos_y - resizeorigin_y;
+ // 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 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(myCenter_x > targCenter_x && myCenter_y < targCenter_y) // top right
+ else if (resizeCorner == 2)
{
- //if(!HUD_Panel_CheckValidity_of_ResizeSuggestion(id, eX * (resizeorigin_x - (targPos_x + targSize_x)) + eY * (targPos_y - resizeorigin_y)))
- // continue;
+ if (resizeorigin_x > targEndPos_x)
+ continue;
+ if (resizeorigin_y < targPos_y)
+ continue;
+ if (targPos_x > resizeorigin_x + mySize_x)
+ continue;
+ if (targEndPos_y < resizeorigin_y - mySize_y)
+ continue;
- if(targPos_x + targSize_x - myPos_x < myPos_y + mySize_y - targPos_y && Check_X) // push it to the side
- mySize_x = resizeorigin_x - (targPos_x + targSize_x);
- else if(Check_Y) // push it upwards
- mySize_y = targPos_y - resizeorigin_y;
+ dist_x = targPos_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(myCenter_x < targCenter_x && myCenter_y > targCenter_y) // bottom left
+ else if (resizeCorner == 3)
{
- //if(!HUD_Panel_CheckValidity_of_ResizeSuggestion(id, eX * (targPos_x - resizeorigin_x) + eY * (resizeorigin_y - (targPos_y + targSize_y))))
- // continue;
+ if (resizeorigin_x < targPos_x)
+ continue;
+ if (resizeorigin_y > targEndPos_y)
+ continue;
+ if (targEndPos_x < resizeorigin_x - mySize_x)
+ continue;
+ if (targPos_y > resizeorigin_y + mySize_y)
+ continue;
- if(myPos_x + mySize_x - targPos_x < targPos_y + targSize_y - myPos_y && Check_X) // push it to the side
- mySize_x = targPos_x - resizeorigin_x;
- else if(Check_Y) // push it upwards
- mySize_y = resizeorigin_y - (targPos_y + targSize_y);
+ dist_x = resizeorigin_x - targEndPos_x;
+ dist_y = targPos_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(myCenter_x > targCenter_x && myCenter_y > targCenter_y) // bottom right
+ else if (resizeCorner == 4)
{
- //if(!HUD_Panel_CheckValidity_of_ResizeSuggestion(id, eX * (resizeorigin_x - (targPos_x + targSize_x)) + eY * (resizeorigin_y - (targPos_y + targSize_y))))
- // continue;
+ if (resizeorigin_x > targEndPos_x)
+ continue;
+ if (resizeorigin_y > targEndPos_y)
+ continue;
+ if (targPos_x > resizeorigin_x + mySize_x)
+ continue;
+ if (targPos_y > resizeorigin_y + mySize_y)
+ continue;
- if(targPos_x + targSize_x - myPos_x < targPos_y + targSize_y - myPos_y && Check_X) // push it to the side
- mySize_x = resizeorigin_x - (targPos_x + targSize_x);
- else if(Check_Y) // push it upwards
- mySize_y = resizeorigin_y - (targPos_y + targSize_y);
+ dist_x = targPos_x - resizeorigin_x;
+ dist_y = targPos_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(targPos + '1 1 0' * targBorder, targSize - '2 2 0' * targBorder, '1 1 0', .3, DRAWFLAG_NORMAL);
}
-
return mySize;
}
-void HUD_Panel_SetPosSize(float id, vector resizeorigin)
+void HUD_Panel_SetPosSize(float id)
{
+ vector resizeorigin;
+ resizeorigin = panel_click_resizeorigin;
vector mySize, myPos;
if(resizeCorner == 1) {
// cap against panel's own limits
vector minSize;
minSize = HUD_Panel_GetMinSize(id); // mySize_x at least minSize_x * mySize_y, and vice versa
-
- mySize_x = max(minSize_x * mySize_y, mySize_x);
- mySize_y = max(minSize_y * mySize_x, mySize_y);
+ float fixedRatio;
+ if(!minSize_x && minSize_y)
+ {
+ minSize_x = 1/minSize_y;
+ fixedRatio = minSize_x;
+ mySize_x = max(minSize_x * mySize_y, mySize_x);
+ mySize_y = max(minSize_y * mySize_x, mySize_y);
+ }
+ else if(minSize_x && !minSize_y) // hybrid aspect ratio, currently supported only in one dimension
+ {
+ if (mySize_x/mySize_y < minSize_x) // resizing in x direction allows free aspect ratio
+ {
+ fixedRatio = minSize_x;
+ minSize_y = 1/minSize_x;
+ mySize_y = max(minSize_y * mySize_x, mySize_y);
+ mySize_x = max(minSize_x * mySize_y, mySize_x);
+ }
+ else
+ fixedRatio = -minSize_x; //negative so that it will be used ONLY after checkResize
+ }
// collision testing|
// -----------------+
mySize_x = min(vid_conwidth - myPos_x, mySize_x);
mySize_y = min(vid_conheight - myPos_y, mySize_y);
- if(cvar("hud_configure_checkcollisions"))
- mySize = HUD_Panel_CheckResize(id, myPos, mySize, resizeorigin);
+ 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(cvar("hud_configure_grid"))
{
mySize_x = floor(mySize_x/cvar("hud_configure_grid_x") + 0.5) * cvar("hud_configure_grid_x");
mySize_y = floor(mySize_y/cvar("hud_configure_grid_y") + 0.5) * cvar("hud_configure_grid_y");
}
+ if (fixedRatio > 0)
+ {
+ // keep aspect ratio _MAXIMIZING_ the size
+ if (mySize_x / mySize_y > fixedRatio)
+ mySize_y = mySize_x / fixedRatio;
+ else
+ mySize_x = mySize_y * fixedRatio;
+ }
+
+ if(cvar("hud_configure_checkcollisions"))
+ {
+ if (fixedRatio > 0)
+ {
+ mySize = HUD_Panel_CheckResize(id, mySize, resizeorigin, fixedRatio);
+ // restore again aspect ratio, _minimizing_ the size
+ if (mySize_x / mySize_y < fixedRatio)
+ mySize_y = mySize_x / fixedRatio;
+ else
+ mySize_x = mySize_y * fixedRatio;
+ }
+ else
+ {
+ mySize = HUD_Panel_CheckResize(id, mySize, resizeorigin, mySize_x / mySize_y);
+ if (fixedRatio < 0)
+ {
+ fixedRatio = -fixedRatio;
+ // restore again aspect ratio, _minimizing_ the size
+ if (mySize_x / mySize_y < fixedRatio)
+ mySize_y = mySize_x / fixedRatio;
+ }
+ }
+ }
+
// do another pos check, as size might have changed by now
if(resizeCorner == 1) {
myPos_x = resizeorigin_x - mySize_x;
myPos_y = resizeorigin_y;
}
+ if(cvar("hud_configure_checkcollisions_debug"))
+ if(cvar("hud_configure_checkcollisions"))
+ drawfill(myPos, mySize, '0 1 0', .3, DRAWFLAG_NORMAL);
+
string s;
s = strcat(ftos(mySize_x/vid_conwidth), " ", ftos(mySize_y/vid_conheight));
cvar_set(strcat("hud_", HUD_Panel_GetName(id), "_size"), s);
}
}
+ if(cvar("hud_configure_checkcollisions_debug"))
+ drawfill(panelPos, panelSize, '1 0 0', .3, DRAWFLAG_NORMAL);
+
if(highlightedAction == 1)
HUD_Panel_SetPos(i, mousepos - panel_click_distance);
else if(highlightedAction == 2)
- HUD_Panel_SetPosSize(i, panel_click_resizeorigin);
+ HUD_Panel_SetPosSize(i);
}
}