From fbbfcd8f2e34034d06ca18daea0c59576ae7adb9 Mon Sep 17 00:00:00 2001 From: majochem Date: Tue, 12 May 2026 07:48:49 +0000 Subject: [PATCH 1/6] Apply changes from https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9807 --- src/Modules/Main.lua | 146 +++++++++++++++++++++++++++++++++------ src/Modules/Main.lua.rej | 14 ++++ 2 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 src/Modules/Main.lua.rej diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 5002f34404..3b327b5a53 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -851,12 +851,57 @@ function main:ChangeUserPath(newUserPath, ignoreBuild) self:LoadSettings(ignoreBuild) self:LoadSharedItems() end - -function main:OpenOptionsPopup() +--- Opens the popup for the "Options" menu +--- @param savedState table|nil optional passing of saved values, in case of reopening `{nodePowerTheme, colorPositive, ...}` +function main:OpenOptionsPopup(savedState) local controls = { } - local currentY = 20 - local popupWidth = 600 + -- Check for `savedState` or assign initial values + -- NOTE: update both this and the `controls.cancel` section below, when adding new options + savedState = savedState or { + nodePowerTheme = self.nodePowerTheme, + colorPositive = self.colorPositive, + colorNegative = self.colorNegative, + colorHighlight = self.colorHighlight, + showThousandsSeparators = self.showThousandsSeparators, + thousandsSeparator = self.thousandsSeparator, + decimalSeparator = self.decimalSeparator, + showTitlebarName = self.showTitlebarName, + betaTest = self.betaTest, + edgeSearchHighlight = self.edgeSearchHighlight, + defaultGemQuality = self.defaultGemQuality or 0, + defaultCharLevel = self.defaultCharLevel or 1, + defaultItemAffixQuality = self.defaultItemAffixQuality or 0.5, + showWarnings = self.showWarnings, + slotOnlyTooltips = self.slotOnlyTooltips, + migrateEldritchImplicits = self.migrateEldritchImplicits, + notSupportedModTooltips = self.notSupportedModTooltips, + invertSliderScrollDirection = self.invertSliderScrollDirection, + disableDevAutoSave = self.disableDevAutoSave, + showPublicBuilds = self.showPublicBuilds, + showFlavourText = self.showFlavourText, + showAnimations = self.showAnimations, + showAllItemAffixes = self.showAllItemAffixes, + dpiScaleOverridePercent = self.dpiScaleOverridePercent + } + + -- NOTE: Height needs to be adjusted if more menu options are added + local oneColumnHeightReq = 850 -- Min height required to not split menu into two columns + local columnWidth = 600 + + local startingY = 20 + local currentY = startingY + local currentX = 0 -- initialized at `0`, only used for two-column layouts + + -- Determine layout limits and modes + local useTwoColumns = self.screenH < oneColumnHeightReq and self.screenW >= columnWidth * 2 + local useScrollBar = self.screenH < oneColumnHeightReq and not useTwoColumns + local scrollBarWidth = useScrollBar and 18 or 0 + + local popupWidth = useTwoColumns and columnWidth * 2 or columnWidth + + -- Scrollbar anchor + controls.sectionAnchor = new("Control", { "TOPLEFT", nil, "TOPLEFT" }, { 0, 0, popupWidth, 0 }) -- local func to make a new line with a heightModifier local function nextRow(heightModifier) @@ -868,18 +913,18 @@ function main:OpenOptionsPopup() -- local func to make a new section header local function drawSectionHeader(id, title, omitHorizontalLine) local headerBGColor ={ .6, .6, .6} - controls["section-"..id .. "-bg"] = new("RectangleOutlineControl", { "TOPLEFT", nil, "TOPLEFT" }, { 8, currentY, popupWidth - 17, 26 }, headerBGColor, 1) + controls["section-"..id .. "-bg"] = new("RectangleOutlineControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + scrollBarWidth + 8, currentY, columnWidth - (scrollBarWidth * 2) - 17, 26 }, headerBGColor, 1) nextRow(.2) - controls["section-"..id .. "-label"] = new("LabelControl", { "TOPLEFT", nil, "TOPLEFT" }, { popupWidth / 2 - 60, currentY, 0, 16 }, "^7" .. title) + controls["section-"..id .. "-label"] = new("LabelControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + columnWidth / 2 - 60, currentY, 0, 16 }, "^7" .. title) nextRow(1.5) end local defaultLabelSpacingPx = -4 - local defaultLabelPlacementX = popupWidth*0.45 + local defaultLabelPlacementX = columnWidth*0.45 drawSectionHeader("app", "Application options") - controls.connectionProtocol = new("DropDownControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 100, 18 }, { + controls.connectionProtocol = new("DropDownControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 100, 18 }, { { label = "Auto", protocol = 0 }, { label = "IPv4", protocol = 1 }, { label = "IPv6", protocol = 2 }, @@ -891,7 +936,7 @@ function main:OpenOptionsPopup() controls.connectionProtocol:SelByValue(launch.connectionProtocol, "protocol") nextRow() - controls.proxyType = new("DropDownControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 80, 18 }, { + controls.proxyType = new("DropDownControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 80, 18 }, { { label = "HTTP", scheme = "http" }, { label = "SOCKS", scheme = "socks5" }, { label = "SOCKS5H", scheme = "socks5h" }, @@ -906,7 +951,7 @@ function main:OpenOptionsPopup() end nextRow() - controls.dpiScaleOverride = new("DropDownControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 150, 18 }, { + controls.dpiScaleOverride = new("DropDownControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 150, 18 }, { { label = "Use system default", percent = 0 }, { label = "100%", percent = 100 }, { label = "125%", percent = 125 }, @@ -918,13 +963,16 @@ function main:OpenOptionsPopup() }, function(index, value) self.dpiScaleOverridePercent = value.percent SetDPIScaleOverridePercent(value.percent) + self.screenW, self.screenH = GetVirtualScreenSize() -- refresh screen size immediately + self:ClosePopup() + self:OpenOptionsPopup(savedState) end) controls.dpiScaleOverrideLabel = new("LabelControl", { "RIGHT", controls.dpiScaleOverride, "LEFT" }, { defaultLabelSpacingPx, 0, 0, 16 }, "^7UI scaling override:") controls.dpiScaleOverride.tooltipText = "Overrides Windows DPI scaling inside Path of Building.\nChoose a percentage between 100% and 250% or revert to the system default." controls.dpiScaleOverride:SelByValue(self.dpiScaleOverridePercent, "percent") nextRow() - controls.buildPath = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 290, 18 }) + controls.buildPath = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 290, 18 }) controls.buildPathLabel = new("LabelControl", { "RIGHT", controls.buildPath, "LEFT" }, { defaultLabelSpacingPx, 0, 0, 16 }, "^7Build save path:") if self.buildPath ~= self.defaultBuildPath then controls.buildPath:SetText(self.buildPath) @@ -932,7 +980,7 @@ function main:OpenOptionsPopup() controls.buildPath.tooltipText = "Overrides the default save location for builds.\nThe default location is: '"..self.defaultBuildPath.."'" nextRow() - controls.nodePowerTheme = new("DropDownControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 100, 18 }, { + controls.nodePowerTheme = new("DropDownControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 100, 18 }, { { label = "Red & Blue", theme = "RED/BLUE" }, { label = "Red & Green", theme = "RED/GREEN" }, { label = "Green & Blue", theme = "GREEN/BLUE" }, @@ -944,7 +992,7 @@ function main:OpenOptionsPopup() controls.nodePowerTheme:SelByValue(self.nodePowerTheme, "theme") nextRow() - controls.colorPositive = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 100, 18 }, tostring(self.colorPositive:gsub('^(^)', '0')), nil, nil, 8, function(buf) + controls.colorPositive = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 100, 18 }, tostring(self.colorPositive:gsub('^(^)', '0')), nil, nil, 8, function(buf) local match = string.match(buf, "0x%x+") if match and #match == 8 then updateColorCode("POSITIVE", buf) @@ -956,7 +1004,7 @@ function main:OpenOptionsPopup() "The default value is " .. tostring(defaultColorCodes.POSITIVE:gsub('^(^)', '0')) .. ".\nIf updating while inside a build, please re-load the build after saving." nextRow() - controls.colorNegative = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 100, 18 }, tostring(self.colorNegative:gsub('^(^)', '0')), nil, nil, 8, function(buf) + controls.colorNegative = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 100, 18 }, tostring(self.colorNegative:gsub('^(^)', '0')), nil, nil, 8, function(buf) local match = string.match(buf, "0x%x+") if match and #match == 8 then updateColorCode("NEGATIVE", buf) @@ -968,8 +1016,8 @@ function main:OpenOptionsPopup() "The default value is " .. tostring(defaultColorCodes.NEGATIVE:gsub('^(^)', '0')) .. ".\nIf updating while inside a build, please re-load the build after saving." nextRow() - - controls.colorHighlight = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 100, 18 }, tostring(self.colorHighlight:gsub('^(^)', '0')), nil, nil, 8, function(buf) + + controls.colorHighlight = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 100, 18 }, tostring(self.colorHighlight:gsub('^(^)', '0')), nil, nil, 8, function(buf) local match = string.match(buf, "0x%x+") if match and #match == 8 then updateColorCode("HIGHLIGHT", buf) @@ -1103,7 +1151,7 @@ function main:OpenOptionsPopup() if launch.devMode then nextRow() - controls.disableDevAutoSave = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Disable Dev AutoSave:", function(state) + controls.disableDevAutoSave = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Disable Dev AutoSave:", function(state) self.disableDevAutoSave = state end) controls.disableDevAutoSave.tooltipText = "Do not Autosave builds while on Dev branch" @@ -1143,10 +1191,14 @@ function main:OpenOptionsPopup() local initialShowAllItemAffixes = self.showAllItemAffixes local initialDpiScaleOverridePercent = self.dpiScaleOverridePercent + -- Adjust height in case of two-column layout + currentY = m_max(leftColumnMaxY, currentY) + -- last line with buttons has more spacing nextRow(1.5) - controls.save = new("ButtonControl", nil, {-45, currentY, 80, 20}, "Save", function() + -- lock the Save/Cancel buttons to the bottom so they don't scroll away + controls.save = new("ButtonControl", { "BOTTOM", nil, "BOTTOM" }, {-45, -10, 80, 20}, "Save", function() launch.connectionProtocol = tonumber(self.connectionProtocol) if controls.proxyURL.buf:match("%w") then launch.proxyURL = controls.proxyType.list[controls.proxyType.selIndex].scheme .. "://" .. controls.proxyURL.buf @@ -1171,7 +1223,7 @@ function main:OpenOptionsPopup() main:ClosePopup() main:SaveSettings() end) - controls.cancel = new("ButtonControl", nil, {45, currentY, 80, 20}, "Cancel", function() + controls.cancel = new("ButtonControl", { "BOTTOM", nil, "BOTTOM" }, {45, -10, 80, 20}, "Cancel", function() self.nodePowerTheme = initialNodePowerTheme self.colorPositive = initialColorPositive updateColorCode("POSITIVE", self.colorPositive) @@ -1203,8 +1255,60 @@ function main:OpenOptionsPopup() SetDPIScaleOverridePercent(self.dpiScaleOverridePercent) main:ClosePopup() end) - nextRow(1.5) - self:OpenPopup(popupWidth, currentY, "Options", controls, "save", nil, "cancel") + + local popupHeight = useScrollBar and (self.screenH - 20) or currentY + 30 + + if useScrollBar then + controls.scrollBar = new("ScrollBarControl", {"TOPRIGHT", nil, "TOPRIGHT"}, {-2, 25, scrollBarWidth, popupHeight - 65}, 50, "VERTICAL", true) + controls.scrollBar:SetContentDimension(currentY, popupHeight - 65) + end + + local function scrollBarFunc() + if useScrollBar then + controls.sectionAnchor.y = -controls.scrollBar.offset + end + end + + local popup = self:OpenPopup(popupWidth, popupHeight, "Options", controls, "save", nil, "cancel", useScrollBar and scrollBarFunc or nil) + + local originalDrawControls = popup.DrawControls + + local function controlIsInsideScrollClip(popupDialog, control) + if control == controls.scrollBar or control == controls.save or control == controls.cancel then + return true + end + local _, y = popupDialog:GetPos() + local _, height = popupDialog:GetSize() + local clipY_top = y + 20 -- just below title + local clipY_bottom = y + height - 40 -- just above buttons + local _, cy = control:GetPos() + local _, ch = control:GetSize() + return cy >= clipY_top and (cy + ch) <= clipY_bottom + end + + -- Modify draw controls to "clip" elements in case the scrollbar is used + popup.DrawControls = function(self, viewPort) + if not useScrollBar then + return originalDrawControls(self, viewPort) + end + + for id, control in pairs(self.controls) do + -- always draw static UI elements + if control:IsShown() and control.Draw and controlIsInsideScrollClip(self, control) then + control:Draw(viewPort, (self.selControl and self.selControl.hasFocus and self.selControl ~= control) or nil) + end + end + end + + if useScrollBar then + popup.GetMouseOverControl = function(self) + for _, control in pairs(self.controls) do + if control.IsMouseOver and controlIsInsideScrollClip(self, control) and control:IsMouseOver() then + return control + end + end + end + end end function main:SetManifestBranch(branchName) diff --git a/src/Modules/Main.lua.rej b/src/Modules/Main.lua.rej new file mode 100644 index 0000000000..a49e712f9d --- /dev/null +++ b/src/Modules/Main.lua.rej @@ -0,0 +1,14 @@ +diff a/src/Modules/Main.lua b/src/Modules/Main.lua (rejected hunks) +@@ -1172,10 +1172,10 @@ function main:OpenOptionsPopup(savedState) + updateColorCode("NEGATIVE", self.colorNegative) + self.colorHighlight = savedState.colorHighlight + updateColorCode("HIGHLIGHT", self.colorHighlight) +- self.showThousandsSeparators = savedState.chousandsSeparatorDisplay ++ self.showThousandsSeparators = savedState.showThousandsSeparators + self.thousandsSeparator = savedState.thousandsSeparator + self.decimalSeparator = savedState.decimalSeparator +- self.showTitlebarName = savedState.titlebarName ++ self.showTitlebarName = savedState.showTitlebarName + self.betaTest = savedState.betaTest + self.edgeSearchHighlight = savedState.edgeSearchHighlight + self.defaultGemQuality = savedState.defaultGemQuality From 5169798460c58eb39bc9eda7f72843356acbc395 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 25 May 2026 23:01:35 +1000 Subject: [PATCH 2/6] Remove rej --- src/Modules/Main.lua.rej | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/Modules/Main.lua.rej diff --git a/src/Modules/Main.lua.rej b/src/Modules/Main.lua.rej deleted file mode 100644 index a49e712f9d..0000000000 --- a/src/Modules/Main.lua.rej +++ /dev/null @@ -1,14 +0,0 @@ -diff a/src/Modules/Main.lua b/src/Modules/Main.lua (rejected hunks) -@@ -1172,10 +1172,10 @@ function main:OpenOptionsPopup(savedState) - updateColorCode("NEGATIVE", self.colorNegative) - self.colorHighlight = savedState.colorHighlight - updateColorCode("HIGHLIGHT", self.colorHighlight) -- self.showThousandsSeparators = savedState.chousandsSeparatorDisplay -+ self.showThousandsSeparators = savedState.showThousandsSeparators - self.thousandsSeparator = savedState.thousandsSeparator - self.decimalSeparator = savedState.decimalSeparator -- self.showTitlebarName = savedState.titlebarName -+ self.showTitlebarName = savedState.showTitlebarName - self.betaTest = savedState.betaTest - self.edgeSearchHighlight = savedState.edgeSearchHighlight - self.defaultGemQuality = savedState.defaultGemQuality From 617fce9f27fb7ef93f34e345786961d7e08ada46 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 25 May 2026 23:17:54 +1000 Subject: [PATCH 3/6] Fix missing lines --- src/Modules/Main.lua | 130 ++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 75 deletions(-) diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index ca94ef8b1f..4b071da0fd 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -866,15 +866,15 @@ function main:OpenOptionsPopup(savedState) betaTest = self.betaTest, edgeSearchHighlight = self.edgeSearchHighlight, defaultGemQuality = self.defaultGemQuality or 0, + initialDefaultItemQuality = self.defaultGemQuality or 20, defaultCharLevel = self.defaultCharLevel or 1, defaultItemAffixQuality = self.defaultItemAffixQuality or 0.5, showWarnings = self.showWarnings, slotOnlyTooltips = self.slotOnlyTooltips, - migrateEldritchImplicits = self.migrateEldritchImplicits, + initialMigrateAugments = self.migrateAugments, notSupportedModTooltips = self.notSupportedModTooltips, invertSliderScrollDirection = self.invertSliderScrollDirection, disableDevAutoSave = self.disableDevAutoSave, - showPublicBuilds = self.showPublicBuilds, showFlavourText = self.showFlavourText, showAnimations = self.showAnimations, showAllItemAffixes = self.showAllItemAffixes, @@ -1025,85 +1025,90 @@ function main:OpenOptionsPopup(savedState) "The default value is " .. tostring(defaultColorCodes.HIGHLIGHT:gsub('^(^)', '0')) .."\nIf updating while inside a build, please re-load the build after saving." nextRow() - controls.betaTest = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Opt-in to weekly beta test builds:", function(state) + controls.betaTest = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Opt-in to weekly beta test builds:", function(state) self.betaTest = state end) nextRow() - controls.edgeSearchHighlight = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20}, "^7Show search circles at viewport edge", function(state) + controls.edgeSearchHighlight = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20}, "^7Show search circles at viewport edge", function(state) self.edgeSearchHighlight = state end) - - --nextRow() - --controls.showPublicBuilds = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show Latest/Trending builds:", function(state) - --self.showPublicBuilds = state - --end) nextRow() - controls.showFlavourText = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Styled Tooltips with Flavour Text:", function(state) + controls.showFlavourText = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Styled Tooltips with Flavour Text:", function(state) self.showFlavourText = state end) controls.showFlavourText.tooltipText = "If updating while inside a build, please re-load the build after saving." nextRow() - controls.showAnimations = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show Animations:", function(state) + controls.showAnimations = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show Animations:", function(state) self.showAnimations = state end) nextRow() - controls.showAllItemAffixes = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show all item affixes sliders:", function(state) + controls.showAllItemAffixes = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show all item affixes sliders:", function(state) self.showAllItemAffixes = state end) controls.showAllItemAffixes.tooltipText = "Display all item affix slots as a stacked list instead of hiding them in dropdowns" nextRow() + + local leftColumnMaxY = currentY -- store left column height + + -- Check for two column layout + if useTwoColumns then + currentY = startingY -- reset height back to top + currentX = columnWidth + end + + -- Build-related Option Section starts drawSectionHeader("build", "Build-related options") - controls.showThousandsSeparators = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT"}, { defaultLabelPlacementX, currentY, 20 }, "^7Show thousands separators:", function(state) + controls.showThousandsSeparators = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT"}, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show thousands separators:", function(state) self.showThousandsSeparators = state end) controls.showThousandsSeparators.state = self.showThousandsSeparators nextRow() - controls.thousandsSeparator = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 30, 20 }, self.thousandsSeparator, nil, "%w", 1, function(buf) + controls.thousandsSeparator = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 30, 20 }, self.thousandsSeparator, nil, "%w", 1, function(buf) self.thousandsSeparator = buf end) controls.thousandsSeparatorLabel = new("LabelControl", { "RIGHT", controls.thousandsSeparator, "LEFT" }, { defaultLabelSpacingPx, 0, 92, 16 }, "^7Thousands separator:") nextRow() - controls.decimalSeparator = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 30, 20 }, self.decimalSeparator, nil, "%w", 1, function(buf) + controls.decimalSeparator = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 30, 20 }, self.decimalSeparator, nil, "%w", 1, function(buf) self.decimalSeparator = buf end) controls.decimalSeparatorLabel = new("LabelControl", { "RIGHT", controls.decimalSeparator, "LEFT" }, { defaultLabelSpacingPx, 0, 92, 16 }, "^7Decimal separator:") nextRow() - controls.titlebarName = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show build name in window title:", function(state) + controls.titlebarName = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show build name in window title:", function(state) self.showTitlebarName = state end) nextRow() - controls.defaultGemQuality = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 80, 20 }, self.defaultGemQuality, nil, "%D", 2, function(gemQuality) + controls.defaultGemQuality = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 80, 20 }, self.defaultGemQuality, nil, "%D", 2, function(gemQuality) self.defaultGemQuality = m_min(tonumber(gemQuality) or 0, 23) end) controls.defaultGemQuality.tooltipText = "Set the default quality that can be overwritten by build-related quality settings in the skill panel." controls.defaultGemQualityLabel = new("LabelControl", { "RIGHT", controls.defaultGemQuality, "LEFT" }, { defaultLabelSpacingPx, 0, 0, 16 }, "^7Default gem quality:") nextRow() - controls.defaultItemQuality = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 80, 20 }, self.defaultItemQuality, nil, "%D", 2, function(itemQuality) + controls.defaultItemQuality = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 80, 20 }, self.defaultItemQuality, nil, "%D", 2, function(itemQuality) self.defaultItemQuality = m_min(tonumber(itemQuality) or 0, 20) end) controls.defaultItemQuality.tooltipText = "Set the default quality that will be applied to newly created or pasted items." controls.defaultItemQualityLabel = new("LabelControl", { "RIGHT", controls.defaultItemQuality, "LEFT" }, { defaultLabelSpacingPx, 0, 0, 16 }, "^7Default item quality:") nextRow() - controls.defaultCharLevel = new("EditControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 80, 20 }, self.defaultCharLevel, nil, "%D", 3, function(charLevel) + controls.defaultCharLevel = new("EditControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 80, 20 }, self.defaultCharLevel, nil, "%D", 3, function(charLevel) self.defaultCharLevel = m_min(m_max(tonumber(charLevel) or 1, 1), 100) end) controls.defaultCharLevel.tooltipText = "Set the default level of your builds. If this is higher than 1, manual level mode will be enabled by default in new builds." controls.defaultCharLevelLabel = new("LabelControl", { "RIGHT", controls.defaultCharLevel, "LEFT" }, { defaultLabelSpacingPx, 0, 0, 16 }, "^7Default character level:") nextRow() - controls.defaultItemAffixQualitySlider = new("SliderControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 200, 20 }, function(value) + controls.defaultItemAffixQualitySlider = new("SliderControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 200, 20 }, function(value) self.defaultItemAffixQuality = round(value, 2) controls.defaultItemAffixQualityValue.label = (self.defaultItemAffixQuality * 100) .. "%" end) @@ -1113,33 +1118,33 @@ function main:OpenOptionsPopup(savedState) controls.defaultItemAffixQualityValue.label = (self.defaultItemAffixQuality * 100) .. "%" nextRow() - controls.showWarnings = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show build warnings:", function(state) + controls.showWarnings = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show build warnings:", function(state) self.showWarnings = state end) controls.showWarnings.state = self.showWarnings nextRow() - controls.slotOnlyTooltips = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show tooltips only for affected slots:", function(state) + controls.slotOnlyTooltips = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show tooltips only for affected slots:", function(state) self.slotOnlyTooltips = state end, "Shows comparisons in tooltips only for the slot you are currently placing the item in, instead of all slots.") controls.slotOnlyTooltips.state = self.slotOnlyTooltips nextRow() - controls.migrateAugments = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Copy augments onto display item:", function(state) + controls.migrateAugments = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Copy augments onto display item:", function(state) self.migrateAugments = state end) controls.migrateAugments.tooltipText = "Apply augments and anoints from current gear when comparing new gear, given they are possible to add to the new item." controls.migrateAugments.state = self.migrateAugments nextRow() - controls.notSupportedModTooltips = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Show tooltip for unsupported mods :", function(state) + controls.notSupportedModTooltips = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Show tooltip for unsupported mods :", function(state) self.notSupportedModTooltips = state end) controls.notSupportedModTooltips.tooltipText = "Show ^8(Not supported in PoB yet) ^7next to unsupported mods\nRequires PoB to restart for it to take effect" controls.notSupportedModTooltips.state = self.notSupportedModTooltips nextRow() - controls.invertSliderScrollDirection = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Invert slider scroll direction:", function(state) + controls.invertSliderScrollDirection = new("CheckBoxControl", { "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 20 }, "^7Invert slider scroll direction:", function(state) self.invertSliderScrollDirection = state end) controls.invertSliderScrollDirection.tooltipText = "Default scroll direction is:\nScroll Up = Move right\nScroll Down = Move left" @@ -1161,31 +1166,6 @@ function main:OpenOptionsPopup(savedState) controls.showFlavourText.state = self.showFlavourText controls.showAnimations.state = self.showAnimations controls.showAllItemAffixes.state = self.showAllItemAffixes - local initialNodePowerTheme = self.nodePowerTheme - local initialColorPositive = self.colorPositive - local initialColorNegative = self.colorNegative - local initialColorHighlight = self.colorHighlight - local initialThousandsSeparatorDisplay = self.showThousandsSeparators - local initialTitlebarName = self.showTitlebarName - local initialThousandsSeparator = self.thousandsSeparator - local initialDecimalSeparator = self.decimalSeparator - local initialBetaTest = self.betaTest - local initialEdgeSearchHighlight = self.edgeSearchHighlight - local initialDefaultGemQuality = self.defaultGemQuality or 0 - local initialDefaultItemQuality = self.defaultGemQuality or 20 - local initialDefaultCharLevel = self.defaultCharLevel or 1 - local initialDefaultItemAffixQuality = self.defaultItemAffixQuality or 0.5 - local initialShowWarnings = self.showWarnings - local initialSlotOnlyTooltips = self.slotOnlyTooltips - local initialMigrateAugments = self.migrateAugments - local initialNotSupportedModTooltips = self.notSupportedModTooltips - local initialInvertSliderScrollDirection = self.invertSliderScrollDirection - local initialDisableDevAutoSave = self.disableDevAutoSave - --local initialShowPublicBuilds = self.showPublicBuilds - local initialShowFlavourText = self.showFlavourText - local initialShowAnimations = self.showAnimations - local initialShowAllItemAffixes = self.showAllItemAffixes - local initialDpiScaleOverridePercent = self.dpiScaleOverridePercent -- Adjust height in case of two-column layout currentY = m_max(leftColumnMaxY, currentY) @@ -1220,34 +1200,34 @@ function main:OpenOptionsPopup(savedState) main:SaveSettings() end) controls.cancel = new("ButtonControl", { "BOTTOM", nil, "BOTTOM" }, {45, -10, 80, 20}, "Cancel", function() - self.nodePowerTheme = initialNodePowerTheme - self.colorPositive = initialColorPositive + self.nodePowerTheme = savedState.initialNodePowerTheme + self.colorPositive = savedState.initialColorPositive updateColorCode("POSITIVE", self.colorPositive) - self.colorNegative = initialColorNegative + self.colorNegative = savedState.initialColorNegative updateColorCode("NEGATIVE", self.colorNegative) - self.colorHighlight = initialColorHighlight + self.colorHighlight = savedState.initialColorHighlight updateColorCode("HIGHLIGHT", self.colorHighlight) - self.showThousandsSeparators = initialThousandsSeparatorDisplay - self.thousandsSeparator = initialThousandsSeparator - self.decimalSeparator = initialDecimalSeparator - self.showTitlebarName = initialTitlebarName - self.betaTest = initialBetaTest - self.edgeSearchHighlight = initialEdgeSearchHighlight - self.defaultGemQuality = initialDefaultGemQuality - self.defaultItemQuality = initialDefaultItemQuality - self.defaultCharLevel = initialDefaultCharLevel - self.defaultItemAffixQuality = initialDefaultItemAffixQuality - self.showWarnings = initialShowWarnings - self.slotOnlyTooltips = initialSlotOnlyTooltips - self.migrateAugments = initialMigrateAugments - self.notSupportedModTooltips = initialNotSupportedModTooltips - self.invertSliderScrollDirection = initialInvertSliderScrollDirection - self.disableDevAutoSave = initialDisableDevAutoSave - self.showPublicBuilds = initialShowPublicBuilds - self.showFlavourText = initialShowFlavourText - self.showAnimations = initialShowAnimations - self.showAllItemAffixes = initialShowAllItemAffixes - self.dpiScaleOverridePercent = initialDpiScaleOverridePercent + self.showThousandsSeparators = savedState.initialThousandsSeparatorDisplay + self.thousandsSeparator = savedState.initialThousandsSeparator + self.decimalSeparator = savedState.initialDecimalSeparator + self.showTitlebarName = savedState.initialTitlebarName + self.betaTest = savedState.initialBetaTest + self.edgeSearchHighlight = savedState.initialEdgeSearchHighlight + self.defaultGemQuality = savedState.initialDefaultGemQuality + self.defaultItemQuality = savedState.initialDefaultItemQuality + self.defaultCharLevel = savedState.initialDefaultCharLevel + self.defaultItemAffixQuality = savedState.initialDefaultItemAffixQuality + self.showWarnings = savedState.initialShowWarnings + self.slotOnlyTooltips = savedState.initialSlotOnlyTooltips + self.migrateAugments = savedState.initialMigrateAugments + self.notSupportedModTooltips = savedState.initialNotSupportedModTooltips + self.invertSliderScrollDirection = savedState.initialInvertSliderScrollDirection + self.disableDevAutoSave = savedState.initialDisableDevAutoSave + self.showPublicBuilds = savedState.initialShowPublicBuilds + self.showFlavourText = savedState.initialShowFlavourText + self.showAnimations = savedState.initialShowAnimations + self.showAllItemAffixes = savedState.initialShowAllItemAffixes + self.dpiScaleOverridePercent = savedState.initialDpiScaleOverridePercent SetDPIScaleOverridePercent(self.dpiScaleOverridePercent) main:ClosePopup() end) From 618822638ef8f7fe3149cf85a536979f3b6076b7 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 25 May 2026 23:30:23 +1000 Subject: [PATCH 4/6] Fix names --- src/Modules/Main.lua | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 4b071da0fd..a3f4d85dd4 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -1200,34 +1200,34 @@ function main:OpenOptionsPopup(savedState) main:SaveSettings() end) controls.cancel = new("ButtonControl", { "BOTTOM", nil, "BOTTOM" }, {45, -10, 80, 20}, "Cancel", function() - self.nodePowerTheme = savedState.initialNodePowerTheme - self.colorPositive = savedState.initialColorPositive + self.nodePowerTheme = savedState.nodePowerTheme + self.colorPositive = savedState.colorPositive updateColorCode("POSITIVE", self.colorPositive) - self.colorNegative = savedState.initialColorNegative + self.colorNegative = savedState.colorNegative updateColorCode("NEGATIVE", self.colorNegative) - self.colorHighlight = savedState.initialColorHighlight + self.colorHighlight = savedState.colorHighlight updateColorCode("HIGHLIGHT", self.colorHighlight) - self.showThousandsSeparators = savedState.initialThousandsSeparatorDisplay - self.thousandsSeparator = savedState.initialThousandsSeparator - self.decimalSeparator = savedState.initialDecimalSeparator - self.showTitlebarName = savedState.initialTitlebarName - self.betaTest = savedState.initialBetaTest - self.edgeSearchHighlight = savedState.initialEdgeSearchHighlight - self.defaultGemQuality = savedState.initialDefaultGemQuality - self.defaultItemQuality = savedState.initialDefaultItemQuality - self.defaultCharLevel = savedState.initialDefaultCharLevel - self.defaultItemAffixQuality = savedState.initialDefaultItemAffixQuality - self.showWarnings = savedState.initialShowWarnings - self.slotOnlyTooltips = savedState.initialSlotOnlyTooltips - self.migrateAugments = savedState.initialMigrateAugments - self.notSupportedModTooltips = savedState.initialNotSupportedModTooltips - self.invertSliderScrollDirection = savedState.initialInvertSliderScrollDirection - self.disableDevAutoSave = savedState.initialDisableDevAutoSave - self.showPublicBuilds = savedState.initialShowPublicBuilds - self.showFlavourText = savedState.initialShowFlavourText - self.showAnimations = savedState.initialShowAnimations - self.showAllItemAffixes = savedState.initialShowAllItemAffixes - self.dpiScaleOverridePercent = savedState.initialDpiScaleOverridePercent + self.showThousandsSeparators = savedState.showThousandsSeparators + self.thousandsSeparator = savedState.thousandsSeparator + self.decimalSeparator = savedState.decimalSeparator + self.showTitlebarName = savedState.showTitlebarName + self.betaTest = savedState.betaTest + self.edgeSearchHighlight = savedState.edgeSearchHighlight + self.defaultGemQuality = savedState.defaultGemQuality + self.defaultItemQuality = savedState.defaultItemQuality + self.defaultCharLevel = savedState.defaultCharLevel + self.defaultItemAffixQuality = savedState.defaultItemAffixQuality + self.showWarnings = savedState.showWarnings + self.slotOnlyTooltips = savedState.slotOnlyTooltips + self.migrateAugments = savedState.migrateAugments + self.notSupportedModTooltips = savedState.notSupportedModTooltips + self.invertSliderScrollDirection = savedState.invertSliderScrollDirection + self.disableDevAutoSave = savedState.disableDevAutoSave + self.showPublicBuilds = savedState.showPublicBuilds + self.showFlavourText = savedState.showFlavourText + self.showAnimations = savedState.showAnimations + self.showAllItemAffixes = savedState.showAllItemAffixes + self.dpiScaleOverridePercent = savedState.dpiScaleOverridePercent SetDPIScaleOverridePercent(self.dpiScaleOverridePercent) main:ClosePopup() end) From 3d737f53e3917e217e49d54f030b3eaf2bdd602d Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Tue, 26 May 2026 00:05:56 +1000 Subject: [PATCH 5/6] Fix typo --- src/Modules/Main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index a3f4d85dd4..101244b578 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -866,7 +866,7 @@ function main:OpenOptionsPopup(savedState) betaTest = self.betaTest, edgeSearchHighlight = self.edgeSearchHighlight, defaultGemQuality = self.defaultGemQuality or 0, - initialDefaultItemQuality = self.defaultGemQuality or 20, + defaultItemQuality = self.defaultItemQuality or 20, defaultCharLevel = self.defaultCharLevel or 1, defaultItemAffixQuality = self.defaultItemAffixQuality or 0.5, showWarnings = self.showWarnings, From 7dbe3b53f8fef84905ec76ca81f4ee74ac951fae Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Tue, 26 May 2026 00:18:43 +1000 Subject: [PATCH 6/6] Fix Augment typo --- src/Modules/Main.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 101244b578..a9e86a5a8b 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -638,6 +638,9 @@ function main:LoadSettings(ignoreBuild) if node.attrib.slotOnlyTooltips then self.slotOnlyTooltips = node.attrib.slotOnlyTooltips == "true" end + if node.attrib.migrateAugments then + self.migrateAugments = node.attrib.migrateAugments == "true" + end if node.attrib.notSupportedModTooltips then self.notSupportedModTooltips = node.attrib.notSupportedModTooltips == "true" end @@ -871,7 +874,7 @@ function main:OpenOptionsPopup(savedState) defaultItemAffixQuality = self.defaultItemAffixQuality or 0.5, showWarnings = self.showWarnings, slotOnlyTooltips = self.slotOnlyTooltips, - initialMigrateAugments = self.migrateAugments, + migrateAugments = self.migrateAugments, notSupportedModTooltips = self.notSupportedModTooltips, invertSliderScrollDirection = self.invertSliderScrollDirection, disableDevAutoSave = self.disableDevAutoSave,