Skip to content

Commit 359f900

Browse files
committed
refactor(weighted-score): unify Edit Weights affordance via dropdown action entry
Replace per-surface Edit Weights buttons (TreeTab heatmap, ItemDB unique sort) with a shared action entry appended to any sort/heatmap dropdown that exposes Weighted Score. NotableDB anoint sort gains the same affordance (no Edit Weights button before). Why: the ItemDB pane is 360 px wide; the previous Edit Weights button shared the same anchor as the League dropdown and forced a mutually exclusive show/hide between League filter and Edit Weights. A user who wanted to filter by League and sort by Weighted Score could not do both. WeightedScore.appendEditWeightsAction(list, openEditor) sentinel-checks for any entry with isWeightedScore and appends a single action entry. Each consumer dropdown selFunc gates on value.isAction: invokes value.action() then restores the prior selection via SelByValue. Tests: 2 new specs in TestWeightedScore_spec (no-op without WS, append plus invocable callback when WS present). Peer-reviewed by Codex (approved, no blocking findings).
1 parent 2282461 commit 359f900

5 files changed

Lines changed: 86 additions & 26 deletions

File tree

‎spec/System/TestWeightedScore_spec.lua‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,33 @@ describe("WeightedScore — tree integration", function()
379379
assert.is_not_nil(found, "WeightedScore entry should appear in fallbackWeightsList candidates")
380380
assert.is_function(found.getValue, "getValue must be propagated into the dropdown entry")
381381
end)
382+
383+
-- appendEditWeightsAction -----------------------------------------------
384+
385+
it("appendEditWeightsAction is a no-op when the list has no WeightedScore entry", function()
386+
local list = {
387+
{ label = "Sort by Name", sortMode = "name" },
388+
{ label = "Sort by Life", sortMode = "Life" },
389+
}
390+
local called = false
391+
WeightedScore.appendEditWeightsAction(list, function() called = true end)
392+
assert.are.equal(2, #list)
393+
assert.is_false(called)
394+
end)
395+
396+
it("appendEditWeightsAction appends an action entry when WeightedScore is present", function()
397+
local list = {
398+
{ label = "Sort by Name", sortMode = "name" },
399+
{ label = "Sort by Weighted Score", sortMode = "WeightedScore", isWeightedScore = true },
400+
}
401+
local opened = false
402+
WeightedScore.appendEditWeightsAction(list, function() opened = true end)
403+
assert.are.equal(3, #list)
404+
local entry = list[3]
405+
assert.is_true(entry.isAction)
406+
assert.is_function(entry.action)
407+
assert.is_string(entry.label)
408+
entry.action()
409+
assert.is_true(opened, "calling entry.action must invoke the openEditor callback")
410+
end)
382411
end)

‎src/Classes/ItemDBControl.lua‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,16 @@ local ItemDBClass = newClass("ItemDBControl", "ListControl", function(self, anch
3636
end)
3737
if dbType == "UNIQUE" then
3838
self.controls.sort = new("DropDownControl", {"BOTTOMLEFT",self,"TOPLEFT"}, {0, baseY + 20, 179, 18}, self.sortDropList, function(index, value)
39-
self:SetSortMode(value.sortMode)
39+
if value.isAction then
40+
value.action()
41+
self.controls.sort:SelByValue(self.sortMode, "sortMode")
42+
else
43+
self:SetSortMode(value.sortMode)
44+
end
4045
end)
4146
self.controls.league = new("DropDownControl", {"LEFT",self.controls.sort,"RIGHT"}, {2, 0, 179, 18}, self.leagueList, function(index, value)
4247
self.listBuildFlag = true
4348
end)
44-
self.controls.editWeights = new("ButtonControl", {"LEFT",self.controls.sort,"RIGHT"}, {2, 0, 179, 18}, "Edit Weights...", function()
45-
local tq = self.itemsTab.tradeQuery
46-
if tq then
47-
tq:SetStatWeights(nil, function() self.listBuildFlag = true end)
48-
end
49-
end)
50-
self.controls.league.shown = function() return self.sortMode ~= "WeightedScore" end
51-
self.controls.editWeights.shown = function() return self.sortMode == "WeightedScore" end
5249
self.controls.requirement = new("DropDownControl", {"LEFT",self.controls.sort,"BOTTOMLEFT"}, {0, 11, 179, 18}, { "Any requirements", "Current level", "Current attributes", "Current useable" }, function(index, value)
5350
self.listBuildFlag = true
5451
end)
@@ -210,6 +207,12 @@ function ItemDBClass:BuildSortOrder()
210207
})
211208
end
212209
end
210+
WeightedScore.appendEditWeightsAction(self.sortDropList, function()
211+
local tq = self.itemsTab.tradeQuery
212+
if tq then
213+
tq:SetStatWeights(nil, function() self.listBuildFlag = true end)
214+
end
215+
end)
213216
wipeTable(self.sortOrder)
214217
if self.controls.sort then
215218
self.controls.sort:CheckDroppedWidth(true)

‎src/Classes/NotableDBControl.lua‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ local NotableDBClass = newClass("NotableDBControl", "ListControl", function(self
3434
self.sortOrder = { }
3535
self.sortMode = "NAME"
3636
self.controls.sort = new("DropDownControl", {"BOTTOMLEFT",self,"TOPLEFT"}, {0, -22, 360, 18}, self.sortDropList, function(index, value)
37-
self:SetSortMode(value.sortMode)
37+
if value.isAction then
38+
value.action()
39+
self.controls.sort:SelByValue(self.sortMode, "sortMode")
40+
else
41+
self:SetSortMode(value.sortMode)
42+
end
3843
end)
3944
self.controls.search = new("EditControl", {"BOTTOMLEFT",self,"TOPLEFT"}, {0, -2, 258, 18}, "", "Search", "%c", 100, function()
4045
self.listBuildFlag = true
@@ -100,6 +105,12 @@ function NotableDBClass:BuildSortOrder()
100105
})
101106
end
102107
end
108+
WeightedScore.appendEditWeightsAction(self.sortDropList, function()
109+
local tq = self.itemsTab.tradeQuery
110+
if tq then
111+
tq:SetStatWeights(nil, function() self.listBuildFlag = true end)
112+
end
113+
end)
103114
wipeTable(self.sortOrder)
104115
if self.controls.sort then
105116
self.controls.sort.selIndex = 1

‎src/Classes/TreeTab.lua‎

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,14 @@ local TreeTabClass = newClass("TreeTab", "ControlHost", function(self, build)
251251

252252
-- Control for selecting the power stat to sort by (Defense, DPS, etc)
253253
self.controls.treeHeatMapStatSelect = new("DropDownControl", { "LEFT", self.controls.nodePowerMaxDepthSelect, "RIGHT" }, { 8, 0, 150, 20 }, nil, function(index, value)
254-
self:SetPowerCalc(value)
254+
if value.isAction then
255+
value.action()
256+
if self.build.calcsTab.powerStat then
257+
self.controls.treeHeatMapStatSelect:SelByValue(self.build.calcsTab.powerStat.stat, "stat")
258+
end
259+
else
260+
self:SetPowerCalc(value)
261+
end
255262
end)
256263
self.controls.treeHeatMap.tooltipText = function()
257264
local offCol, defCol = main.nodePowerTheme:match("(%a+)/(%a+)")
@@ -264,26 +271,19 @@ local TreeTabClass = newClass("TreeTab", "ControlHost", function(self, build)
264271
t_insert(self.powerStatList, stat)
265272
end
266273
end
274+
WeightedScore.appendEditWeightsAction(self.powerStatList, function()
275+
local tq = self.build.itemsTab.tradeQuery
276+
if tq then
277+
tq:SetStatWeights(nil, function() self:SetPowerCalc(self.build.calcsTab.powerStat) end)
278+
end
279+
end)
267280

268281
-- Show/Hide Power Report Button
269282
self.controls.powerReport = new("ButtonControl", { "LEFT", self.controls.treeHeatMapStatSelect, "RIGHT" }, { 8, 0, 150, 20 },
270283
function() return self.controls.powerReportList.shown and "Hide Power Report" or "Show Power Report" end, function()
271284
self.controls.powerReportList.shown = not self.controls.powerReportList.shown
272285
end)
273286

274-
-- Edit Weights button (only shown when Weighted Score heatmap mode is active)
275-
self.controls.editWeights = new("ButtonControl",
276-
{ "LEFT", self.controls.powerReport, "RIGHT" }, { 8, 0, 130, 20 },
277-
"Edit Weights...",
278-
function()
279-
local tq = self.build.itemsTab.tradeQuery
280-
if tq then
281-
tq:SetStatWeights(nil, function() self:SetPowerCalc(self.build.calcsTab.powerStat) end)
282-
end
283-
end
284-
)
285-
self.controls.editWeights.shown = false
286-
287287
-- Power Report List
288288
local yPos = self.controls.treeHeatMap.y == 0 and self.controls.specSelect.height + 4 or self.controls.specSelect.height * 2 + 8
289289
self.controls.powerReportList = new("PowerReportListControl", { "TOPLEFT", self.controls.specSelect, "BOTTOMLEFT" }, { 0, yPos, 700, 170 }, function(selectedNode)
@@ -472,7 +472,6 @@ function TreeTabClass:Draw(viewPort, inputEvents)
472472

473473
self.controls.treeHeatMap.state = self.viewer.showHeatMap
474474
self.controls.treeHeatMapStatSelect.shown = self.viewer.showHeatMap
475-
self.controls.editWeights.shown = self.viewer.showHeatMap and self.build.calcsTab.powerStat and self.build.calcsTab.powerStat.isWeightedScore or false
476475
self.controls.treeHeatMapStatSelect.list = self.powerStatList
477476
self.controls.treeHeatMapStatSelect.selIndex = 1
478477
self.controls.treeHeatMapStatSelect:CheckDroppedWidth(true)
@@ -1055,7 +1054,6 @@ function TreeTabClass:SetPowerCalc(powerStat)
10551054
self.build.buildFlag = true
10561055
self.build.calcsTab.powerBuildFlag = true
10571056
self.build.calcsTab.powerStat = powerStat
1058-
self.controls.editWeights.shown = powerStat and powerStat.isWeightedScore or false
10591057
self.controls.powerReportList:SetReport(powerStat, nil)
10601058
-- Remove old toast and clear dismissed state so toast can show for new power report
10611059
if self.powerBuilderToastId then

‎src/Modules/WeightedScore.lua‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,23 @@ function WeightedScore.computeRatioScore(baseOutput, newOutput, weights)
7171
return meanStatDiff
7272
end
7373

74+
-- Append a contextual "Edit Weights..." action to a sort dropdown list when the
75+
-- list contains the WeightedScore entry. Lets every WS-aware sort surface share
76+
-- the same affordance without each one adding its own button.
77+
function WeightedScore.appendEditWeightsAction(sortDropList, openEditor)
78+
local hasWeightedScore = false
79+
for _, entry in ipairs(sortDropList) do
80+
if entry.isWeightedScore then
81+
hasWeightedScore = true
82+
break
83+
end
84+
end
85+
if not hasWeightedScore then return end
86+
table.insert(sortDropList, {
87+
label = colorCodes.TIP .. "Edit Weights...",
88+
isAction = true,
89+
action = openEditor,
90+
})
91+
end
92+
7493
return WeightedScore

0 commit comments

Comments
 (0)