>wowhelm_
Loading ruleset status…
~/forever/addon-api/source/1.60.1.70755

Interface/AddOns/Blizzard_Menu/Menu.lua

1.60.1.70755 compared with 1.60.1.70707 · 2026-11-03 · +50 −13· view file
@@ -1299,6 +1299,22 @@ local function SecureGetChildExtentPadding(menuFrame)
return padding.width, padding.height;
end
+-- Lets frames override their extents for the final column and row count. Returns true if any frame did.
+function MenuMixin:FinalizeGridLayout(columns, rows)
+ local menuFrame = self:ToProxy();
+ local finalized = false;
+ for _index, frame in self.frames:Enumerate() do
+ local descriptionProxy = frame:GetElementDescription();
+ local description = Proxies:ToPrivate(descriptionProxy);
+
+ if description.finalizeGridLayout:IsSet() then
+ description.finalizeGridLayout:CallFunction(frame, descriptionProxy, menuFrame, columns, rows);
+ finalized = true;
+ end
+ end
+ return finalized;
+end
+
function MenuMixin:PerformLayout()
--[[
GetTop() is returning inconsistently between openings despite it's anchor being fixed in space.
@@ -1363,6 +1379,39 @@ function MenuMixin:PerformLayout()
local maxMenuHeight = math.max(0, menuFrame:GetTop() - compactionMargin);
local maxRows = math.max(1, math.floor(maxMenuHeight / childMaxHeight));
finalColumns, finalRows = TransformColumnsAndRows(size, columns, rows, maxRows);
+
+ --[[
+ Only compacting menus are clamped to the screen width. Grids with an explicit column count
+ and no compaction margin are expected to be configured by the caller to fit.
+ Menus in external windows are not bounded by the top level parent.
+ ]]--
+ if (finalColumns > 1) and (menuFrame:GetWindow() == nil) then
+ -- Convert the top level parent's width into this menu's (possibly scaled) units.
+ local boundsParent = GetAppropriateTopLevelParent();
+ local screenWidth = boundsParent:GetWidth() * boundsParent:GetEffectiveScale() / menuFrame:GetEffectiveScale();
+ local insetLeft, _insetTop, insetRight = securecallfunction(SecureGetInset, menuFrame);
+ local availableWidth = screenWidth - insetLeft - insetRight;
+ local gridPadding = self.menuDescription:GetGridPadding();
+
+ -- Frames are only narrower in a multi-column menu, so only measure them as such if they might not fit.
+ if ((finalColumns * childMaxWidth) + ((finalColumns - 1) * gridPadding)) > availableWidth then
+ -- Frame widths depend on the column count, so re-measure at each candidate until it fits.
+ while finalColumns > 1 do
+ local columnWidth = childMaxWidth;
+ if self:FinalizeGridLayout(finalColumns, finalRows) then
+ columnWidth = self:MeasureFrameExtents();
+ end
+
+ local maxColumns = math.max(1, math.floor((availableWidth + gridPadding) / (columnWidth + gridPadding)));
+ if finalColumns <= maxColumns then
+ break;
+ end
+
+ finalColumns = maxColumns;
+ finalRows = math.ceil(size / finalColumns);
+ end
+ end
+ end
else
finalColumns, finalRows = columns, rows;
end
@@ -1371,19 +1420,7 @@ function MenuMixin:PerformLayout()
The final column and row count may be required by some frames to override their extents.
If this occurs, we will have to recalculate the ideal frame size again.
]]--
- local recalculateSize = false;
-
- for index, frame in self.frames:Enumerate() do
- local descriptionProxy = frame:GetElementDescription();
- local description = Proxies:ToPrivate(descriptionProxy);
-
- if description.finalizeGridLayout:IsSet() then
- description.finalizeGridLayout:CallFunction(frame, descriptionProxy, menuFrame, finalColumns, finalRows);
- recalculateSize = true;
- end
- end
-
- if recalculateSize then
+ if self:FinalizeGridLayout(finalColumns, finalRows) then
childMaxWidth = self:MeasureFrameExtents();
end
end