diff --git a/spec/System/TestGemSelectControl_spec.lua b/spec/System/TestGemSelectControl_spec.lua new file mode 100644 index 0000000000..2c45e9494b --- /dev/null +++ b/spec/System/TestGemSelectControl_spec.lua @@ -0,0 +1,72 @@ +describe("GemSelectControl", function() + local function makeControl() + local change + local skillsTab = { + showSupportGemTypes = "ALL", + defaultGemLevel = 20, + build = { + characterLevel = 100, + data = { gems = { } }, + }, + } + local control = new("GemSelectControl", nil, { 0, 0, 300, 20 }, skillsTab, 1, function(...) + change = { ... } + end) + control.gems = { + ["Default:Arc"] = { name = "Arc", grantedEffect = { } }, + ["Default:Fireball"] = { name = "Fireball", grantedEffect = { } }, + } + control.sortCache = { + canSupport = { }, + dps = { + ["Default:Arc"] = 2, + ["Default:Fireball"] = 1, + }, + } + control.skillsTab.sortGemsByDPS = true + control.list = { "Default:Fireball", "Default:Arc" } + control.searchStr = "" + control.ScrollSelIntoView = function() end + return control, function() return change end + end + + it("keeps the selected gem aligned with a lazy DPS sort", function() + local control = makeControl() + control.buf = "Fireball" + + control:SortCurrentList() + + assert.are.equal("Default:Arc", control.list[1]) + assert.are.equal(2, control.selIndex) + end) + + it("restores and releases focus on a cancelled outside click", function() + local control, getChange = makeControl() + control.buf = "Arc" + control.initialBuf = "Fireball" + control.dropped = true + control.IsShown = function() return true end + control.IsEnabled = function() return true end + control.IsMouseOver = function() return false end + + assert.is_nil(control:OnKeyDown("LEFTBUTTON")) + assert.are.equal("Fireball", control.buf) + assert.are.equal(2, control.selIndex) + assert.are.same({ "Fireball", false, true, true }, getChange()) + end) + + it("allows click-through after selecting a gem", function() + local control, getChange = makeControl() + control.buf = "Fireball" + control.initialBuf = "Fireball" + control.dropped = true + control.hoverSel = 2 + control.IsShown = function() return true end + control.IsEnabled = function() return true end + control.IsMouseOver = function() return true end + + assert.is_nil(control:OnKeyDown("LEFTBUTTON")) + assert.are.equal("Arc", control.buf) + assert.are.same({ "Arc", true, nil, true }, getChange()) + end) +end) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 75de66341c..f3534f0204 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -383,6 +383,24 @@ function GemSelectClass:SortGemList(gemList) end) end +function GemSelectClass:SyncSelection() + self.selIndex = 0 + for index, gemId in ipairs(self.list) do + if self.gems[gemId] and self.gems[gemId].name:lower() == self.buf:lower() then + self.selIndex = index + self:ScrollSelIntoView() + break + end + end +end + +function GemSelectClass:SortCurrentList() + if #self.searchStr == 0 then + self:SortGemList(self.list) + self:SyncSelection() + end +end + function GemSelectClass:DPSBuilder() local sortCache = self.sortCache if not sortCache or not sortCache.pendingGems then return end @@ -409,9 +427,7 @@ function GemSelectClass:DPSBuilder() end local now = GetTime() if now - start > 50 then - if #self.searchStr == 0 then - self:SortGemList(self.list) - end + self:SortCurrentList() if self.dpsBuilderCallback then self.dpsBuilderCallback(m_floor(index/#pending*100)) end @@ -420,9 +436,7 @@ function GemSelectClass:DPSBuilder() end end - if #self.searchStr == 0 then - self:SortGemList(self.list) - end + self:SortCurrentList() sortCache.pendingGems = nil end @@ -685,27 +699,23 @@ end function GemSelectClass:OnFocusGained() self.EditControl:OnFocusGained() self.dropped = true - self.selIndex = 0 self:UpdateSortCache() self:BuildList("") - for index, gemId in pairs(self.list) do - if self.gems[gemId] and self.gems[gemId].name == self.buf then - self.selIndex = index - self:ScrollSelIntoView() - break - end - end + self:SyncSelection() self.initialBuf = self.buf - self.initialIndex = self.selIndex +end + +function GemSelectClass:CancelSelection() + self.dropped = false + self.buf = self.initialBuf + self:BuildList("") + self:SyncSelection() + self:UpdateGem(false, true, true) end function GemSelectClass:OnFocusLost() if self.dropped then - self.dropped = false - if self.noMatches then - self:SetText("") - end - self:UpdateGem(true,true, true) + self:CancelSelection() end end @@ -739,6 +749,7 @@ function GemSelectClass:OnKeyDown(key, doubleClick) end if self.dropped then if key:match("BUTTON") and not self:IsMouseOver() then + self:CancelSelection() return end if key == "LEFTBUTTON" then @@ -761,11 +772,7 @@ function GemSelectClass:OnKeyDown(key, doubleClick) self:UpdateGem(true, true, true) return elseif key == "ESCAPE" then - self.dropped = false - self:BuildList("") - self.buf = self.initialBuf - self.selIndex = self.initialIndex - self:UpdateGem(false,true, true) + self:CancelSelection() return elseif self.controls.scrollBar:IsScrollUpKey(key) then self.controls.scrollBar:Scroll(-1) @@ -793,7 +800,6 @@ function GemSelectClass:OnKeyDown(key, doubleClick) elseif key == "RETURN" or key == "RIGHTBUTTON" then self.dropped = true self:UpdateSortCache() - self.initialIndex = self.selIndex self.initialBuf = self.buf return self end