The vehicle list wraps instead of running off the bottom

Adding eleven vehicles to the setup menu made the column longer than the
window. At 1920x1080 it used to end at 994 against a 1080 client and now
wanted 1324, so the bottom of the list was simply off screen - and the rows
cannot shrink to absorb it, being already at the 18px floor that keeps them
legible.

The list now wraps across two columns when it does not fit, split evenly
rather than filled-then-spilled, and the loadout column - colours and
badges, or team and position - moves one place right along with the pilot
name box and the launch, host and join buttons. A roster short enough for a
single column lays out exactly as it did before, so this only changes the
screen when it has to.

Four columns still fit the width everywhere we ship: the right edge lands at
623 of 640, 1250 of 1280 and 1877 of 1920. The tallest column is 19 rows,
ending at 428, 502 and 754 against those clients.

AddGroupItems grows a 'first' argument so a group can start partway through
its own list. The items stay contiguous in fe->items, so the header still
draws once above the first of them, and each item keeps its true index -
selection and hit-testing already work off item->index rather than position.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-07 08:25:41 -05:00
co-authored by Claude Opus 5
parent 3ba79476fc
commit cf90698159
+43 -14
View File
@@ -612,15 +612,18 @@ namespace
//---------------------------------------------------------------
// Layout: three columns of lists + the launch button
//---------------------------------------------------------------
// 'first' is the index of the group's own list to start at, so a long
// group can be laid out as several columns; the items stay contiguous
// in fe->items, so the header still draws once, above the first one.
void AddGroupItems(
FEState *fe, int group, int count,
int x, int *y, int row_h, int width)
int x, int *y, int row_h, int width, int first = 0)
{
for (int i = 0; i < count; ++i)
{
FEItem *item = &fe->items[fe->itemCount++];
item->group = group;
item->index = i;
item->index = first + i;
item->rect.left = x;
item->rect.top = *y;
item->rect.right = x + width;
@@ -642,8 +645,28 @@ namespace
int col1 = client_w / 14;
int col2 = col1 + col_w + client_w / 28;
int col3 = col2 + col_w + client_w / 28;
int col4 = col3 + col_w + client_w / 28;
int top = client_h / 7;
//---------------------------------------------------------------
// The vehicle list outgrew one column when the promoted resource
// file brought eleven more machines: at 1080p it ran a couple of
// hundred pixels past the bottom of the window. Wrap it over two
// columns rather than shrinking rows below the 18px floor, and
// shift the loadout column (and the buttons that live with it)
// one place right. A roster short enough for one column lays out
// exactly as it always did.
//---------------------------------------------------------------
int rows_per_col = (client_h - top - 3 * row_h) / row_h;
if (rows_per_col < 1) rows_per_col = 1;
int vehicle_count = FE_COUNT(kVehicles);
Logical wrap_vehicles = (vehicle_count > rows_per_col);
int vehicle_split = wrap_vehicles
? (vehicle_count + 1) / 2 // balanced, not filled-then-spilled
: vehicle_count;
int loadout_col = wrap_vehicles ? col4 : col3;
int y = top;
AddGroupItems(fe, GroupScenario, FE_COUNT(kScenarios), col1, &y, row_h, col_w);
int map_count;
@@ -654,27 +677,33 @@ namespace
AddGroupItems(fe, GroupLength, FE_COUNT(kLengths), col1, &y, row_h, col_w);
y = top;
AddGroupItems(fe, GroupVehicle, FE_COUNT(kVehicles), col2, &y, row_h, col_w);
AddGroupItems(fe, GroupVehicle, vehicle_split, col2, &y, row_h, col_w);
if (wrap_vehicles)
{
y = top;
AddGroupItems(fe, GroupVehicle, vehicle_count - vehicle_split,
col3, &y, row_h, col_w, vehicle_split);
}
y = top + 2 * row_h; // leave room for the name edit + header
if (IsFootball(fe->selection))
{
AddGroupItems(fe, GroupTeam, FE_COUNT(kTeams), col3, &y, row_h, col_w);
AddGroupItems(fe, GroupPosition, FE_COUNT(kPositions), col3, &y, row_h, col_w);
AddGroupItems(fe, GroupTeam, FE_COUNT(kTeams), loadout_col, &y, row_h, col_w);
AddGroupItems(fe, GroupPosition, FE_COUNT(kPositions), loadout_col, &y, row_h, col_w);
}
else
{
AddGroupItems(fe, GroupColor, FE_COUNT(kColors), col3, &y, row_h, col_w);
AddGroupItems(fe, GroupBadge, FE_COUNT(kBadges), col3, &y, row_h, col_w);
AddGroupItems(fe, GroupColor, FE_COUNT(kColors), loadout_col, &y, row_h, col_w);
AddGroupItems(fe, GroupBadge, FE_COUNT(kBadges), loadout_col, &y, row_h, col_w);
}
// launch button
FEItem *launch = &fe->items[fe->itemCount++];
launch->group = GroupLaunch;
launch->index = 0;
launch->rect.left = col3;
launch->rect.left = loadout_col;
launch->rect.top = client_h - 3 * row_h;
launch->rect.right = col3 + col_w;
launch->rect.right = loadout_col + col_w;
launch->rect.bottom = client_h - row_h;
// Steam lobby buttons, offered whenever environ.ini asked for Steam.
@@ -684,17 +713,17 @@ namespace
FEItem *host = &fe->items[fe->itemCount++];
host->group = GroupSteamHost;
host->index = 0;
host->rect.left = col3;
host->rect.left = loadout_col;
host->rect.top = client_h - 6 * row_h;
host->rect.right = col3 + col_w;
host->rect.right = loadout_col + col_w;
host->rect.bottom = client_h - 5 * row_h;
FEItem *join = &fe->items[fe->itemCount++];
join->group = GroupSteamJoin;
join->index = 0;
join->rect.left = col3;
join->rect.left = loadout_col;
join->rect.top = client_h - (9 * row_h) / 2;
join->rect.right = col3 + col_w;
join->rect.right = loadout_col + col_w;
join->rect.bottom = client_h - (7 * row_h) / 2;
}
@@ -719,7 +748,7 @@ namespace
if (fe->nameEdit != NULL)
{
MoveWindow(fe->nameEdit,
col3, top - row_h / 4, col_w, row_h, TRUE);
loadout_col, top - row_h / 4, col_w, row_h, TRUE);
}
}