Apply changes from https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2/pull/1147 (#8669)
Co-authored-by: Blitz54 <Blitz54@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
0395117a4e
commit
5cae9084e8
@@ -346,10 +346,12 @@ function ListClass:OnKeyDown(key, doubleClick)
|
||||
newSelect = index
|
||||
end
|
||||
else
|
||||
local scrollOffsetH = self.controls.scrollBarH.offset
|
||||
for colIndex, column in ipairs(self.colList) do
|
||||
local relX = cursorX - (x + 2)
|
||||
local relY = cursorY - (y + 2)
|
||||
local mOver = relX >= column._offset and relX <= column._offset + column._width and relY >= 0 and relY <= 18
|
||||
local adjustedRelX = relX + scrollOffsetH
|
||||
local mOver = adjustedRelX >= column._offset and adjustedRelX <= column._offset + column._width and relY >= 0 and relY <= 18
|
||||
if self:GetColumnProperty(column, "sortable") and mOver and self.ReSort then
|
||||
self:ReSort(colIndex)
|
||||
end
|
||||
|
||||
@@ -4,9 +4,27 @@
|
||||
-- Dat list control.
|
||||
--
|
||||
local DatListClass = newClass("DatListControl", "ListControl", function(self, anchor, rect)
|
||||
self.ListControl(anchor, rect, 14, "VERTICAL", false, main.datFileList)
|
||||
self.originalList = main.datFileList
|
||||
self.searchBuf = ""
|
||||
self.filteredList = self.originalList
|
||||
self.ListControl(anchor, rect, 14, "VERTICAL", false, self.filteredList)
|
||||
end)
|
||||
|
||||
function DatListClass:BuildFilteredList()
|
||||
local search = self.searchBuf:lower()
|
||||
if search == "" then
|
||||
self.filteredList = self.originalList
|
||||
else
|
||||
self.filteredList = {}
|
||||
for _, file in ipairs(self.originalList) do
|
||||
if file.name:lower():find(search, 1, true) then
|
||||
table.insert(self.filteredList, file)
|
||||
end
|
||||
end
|
||||
end
|
||||
self.list = self.filteredList
|
||||
end
|
||||
|
||||
function DatListClass:GetRowValue(column, index, datFile)
|
||||
if column == 1 then
|
||||
return "^7"..datFile.name
|
||||
|
||||
@@ -9,6 +9,7 @@ local t_insert = table.insert
|
||||
local RowListClass = newClass("RowListControl", "ListControl", function(self, anchor, rect)
|
||||
self.ListControl(anchor, rect, 14, "HORIZONTAL", false, { })
|
||||
self.colLabels = true
|
||||
self._autoSizeToggleState = {} -- internal toggle memory, not saved to spec
|
||||
end)
|
||||
|
||||
function RowListClass:BuildRows(filter)
|
||||
@@ -44,13 +45,19 @@ end
|
||||
|
||||
function RowListClass:BuildColumns()
|
||||
wipeTable(self.colList)
|
||||
self.colList[1] = { width = 50, label = "#", font = "FIXED" }
|
||||
self.colList[1] = { width = 50, label = "#", font = "FIXED", sortable = true }
|
||||
for _, specCol in ipairs(main.curDatFile.spec) do
|
||||
t_insert(self.colList, { width = specCol.width, label = specCol.name, font = function() return IsKeyDown("CTRL") and "FIXED" or "VAR" end })
|
||||
t_insert(self.colList, {
|
||||
width = specCol.width,
|
||||
specColRef = specCol, -- Link to the original data
|
||||
label = specCol.name,
|
||||
font = function() return IsKeyDown("ALT") and "FIXED" or "VAR" end,
|
||||
sortable = true
|
||||
})
|
||||
end
|
||||
local short = main.curDatFile.rowSize - main.curDatFile.specSize
|
||||
if short > 0 then
|
||||
t_insert(self.colList, { width = short * DrawStringWidth(self.rowHeight, "FIXED", "00 "), font = "FIXED" })
|
||||
t_insert(self.colList, { width = short * DrawStringWidth(self.rowHeight, "FIXED", "00 "), font = "FIXED", sortable = true })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -58,7 +65,7 @@ function RowListClass:GetRowValue(column, index, row)
|
||||
if column == 1 then
|
||||
return string.format("%5d", row)
|
||||
end
|
||||
if not main.curDatFile.spec[column - 1] or IsKeyDown("CTRL") then
|
||||
if not main.curDatFile.spec[column - 1] or IsKeyDown("ALT") then
|
||||
local out = { main.curDatFile:ReadCellRaw(row, column - 1) }
|
||||
for i, b in ipairs(out) do
|
||||
out[i] = string.format("%02X", b)
|
||||
@@ -76,3 +83,280 @@ function RowListClass:GetRowValue(column, index, row)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RowListClass:Draw(viewPort)
|
||||
local x, y = self:GetPos()
|
||||
local width, height = self:GetSize()
|
||||
local rowHeight = self.rowHeight
|
||||
local list = self.list
|
||||
|
||||
local colOffset = 0
|
||||
for index, column in ipairs(self.colList) do
|
||||
column._offset = colOffset
|
||||
column._width = self:GetColumnProperty(column, "width") or (index == #self.colList and self.scroll and width - 20 or width - colOffset) or 0
|
||||
colOffset = colOffset + column._width
|
||||
end
|
||||
|
||||
local scrollBarV = self.controls.scrollBarV
|
||||
local rowRegion = self:GetRowRegion()
|
||||
scrollBarV:SetContentDimension(#list * rowHeight, rowRegion.height)
|
||||
local scrollOffsetV = scrollBarV.offset
|
||||
local scrollBarH = self.controls.scrollBarH
|
||||
local lastCol = self.colList[#self.colList]
|
||||
scrollBarH:SetContentDimension(lastCol._offset + lastCol._width, rowRegion.width)
|
||||
local scrollOffsetH = scrollBarH.offset
|
||||
|
||||
local cursorX, cursorY = GetCursorPos()
|
||||
|
||||
local label = self:GetProperty("label")
|
||||
if label then
|
||||
DrawString(x + self.labelPositionOffset[1], y - 20 + self.labelPositionOffset[2], "LEFT", 16, self.font, label)
|
||||
end
|
||||
if self.hasFocus then
|
||||
SetDrawColor(1, 1, 1)
|
||||
else
|
||||
SetDrawColor(0.5, 0.5, 0.5)
|
||||
end
|
||||
DrawImage(nil, x, y, width, height)
|
||||
SetDrawColor(0, 0, 0)
|
||||
DrawImage(nil, x + 1, y + 1, width - 2, height - 2)
|
||||
self:DrawControls(viewPort)
|
||||
|
||||
SetViewport(x + 2, y + 2, self.scroll and width - 20 or width, height - 4 - (self.scroll and self.scrollH and 16 or 0))
|
||||
local textOffsetY = self.showRowSeparators and 2 or 0
|
||||
local textHeight = rowHeight - textOffsetY * 2
|
||||
local minIndex = math.floor(scrollOffsetV / rowHeight + 1)
|
||||
local maxIndex = math.min(math.floor((scrollOffsetV + height) / rowHeight + 1), #list)
|
||||
for colIndex, column in ipairs(self.colList) do
|
||||
local colFont = self:GetColumnProperty(column, "font") or "VAR"
|
||||
local clipWidth = DrawStringWidth(textHeight, colFont, "...")
|
||||
colOffset = column._offset - scrollOffsetH
|
||||
local colWidth = column._width
|
||||
local relX = cursorX - (x + 2)
|
||||
local relY = cursorY - (y + 2)
|
||||
for index = minIndex, maxIndex do
|
||||
local lineY = rowHeight * (index - 1) - scrollOffsetV + (self.colLabels and 18 or 0)
|
||||
local value = list[index]
|
||||
local text = self:GetRowValue(colIndex, index, value)
|
||||
local textWidth = DrawStringWidth(textHeight, colFont, text)
|
||||
if textWidth > colWidth - 2 then
|
||||
local clipIndex = DrawStringCursorIndex(textHeight, colFont, text, colWidth - clipWidth - 2, 0)
|
||||
text = text:sub(1, clipIndex - 1) .. "..."
|
||||
textWidth = DrawStringWidth(textHeight, colFont, text)
|
||||
end
|
||||
if self.showRowSeparators then
|
||||
if self.hasFocus and value == self.selValue then
|
||||
SetDrawColor(1, 1, 1)
|
||||
else
|
||||
SetDrawColor(0.5, 0.5, 0.5)
|
||||
end
|
||||
DrawImage(nil, colOffset, lineY, not self.scroll and colWidth - 4 or colWidth, rowHeight)
|
||||
if index % 2 == 0 then
|
||||
SetDrawColor(0.05, 0.05, 0.05)
|
||||
else
|
||||
SetDrawColor(0, 0, 0)
|
||||
end
|
||||
DrawImage(nil, colOffset, lineY + 1, not self.scroll and colWidth - 4 or colWidth, rowHeight - 2)
|
||||
elseif value == self.selValue then
|
||||
if self.hasFocus and value == self.selValue then
|
||||
SetDrawColor(1, 1, 1)
|
||||
else
|
||||
SetDrawColor(0.5, 0.5, 0.5)
|
||||
end
|
||||
DrawImage(nil, colOffset, lineY, not self.scroll and colWidth - 4 or colWidth, rowHeight)
|
||||
SetDrawColor(0.15, 0.15, 0.15)
|
||||
DrawImage(nil, colOffset, lineY + 1, not self.scroll and colWidth - 4 or colWidth, rowHeight - 2)
|
||||
end
|
||||
if not self.SetHighlightColor or not self:SetHighlightColor(index, value) then
|
||||
SetDrawColor(1, 1, 1)
|
||||
end
|
||||
DrawString(colOffset, lineY + textOffsetY, "LEFT", textHeight, colFont, text)
|
||||
end
|
||||
if self.colLabels then
|
||||
local mOver = relX >= colOffset and relX <= colOffset + colWidth and relY >= 0 and relY <= 18
|
||||
|
||||
local isSelected = (colIndex - 1) == main.curSpecColIndex
|
||||
local outerColor
|
||||
if mOver then
|
||||
outerColor = {1, 1, 1}
|
||||
elseif isSelected then
|
||||
outerColor = {1, 0.3, 0.2}
|
||||
else
|
||||
outerColor = {0.5, 0.5, 0.5}
|
||||
end
|
||||
local innerColor = isSelected and {0.6, 0.25, 0.2} or (mOver and self:GetColumnProperty(column, "sortable") and {0.33, 0.33, 0.33} or {0.15, 0.15, 0.15})
|
||||
|
||||
SetDrawColor(unpack(outerColor))
|
||||
DrawImage(nil, colOffset, 1, colWidth, 18)
|
||||
SetDrawColor(unpack(innerColor))
|
||||
DrawImage(nil, colOffset + 1, 2, colWidth - 2, 16)
|
||||
|
||||
local label = self:GetColumnProperty(column, "label")
|
||||
if label and #label > 0 then
|
||||
SetDrawColor(1, 1, 1)
|
||||
DrawString(colOffset + colWidth/2, 4, "CENTER_X", 12, "VAR", label)
|
||||
end
|
||||
end
|
||||
end
|
||||
if #self.list == 0 and self.defaultText then
|
||||
SetDrawColor(1, 1, 1)
|
||||
DrawString(2, 2, "LEFT", 14, self.font, self.defaultText)
|
||||
end
|
||||
SetViewport()
|
||||
end
|
||||
|
||||
function RowListClass:ReSort(colIndex)
|
||||
local asc = true
|
||||
if self.lastSortedCol == colIndex then
|
||||
asc = not self.sortAsc
|
||||
end
|
||||
|
||||
table.sort(self.list, function(a, b)
|
||||
local valA = self:GetRowValue(colIndex, nil, a)
|
||||
local valB = self:GetRowValue(colIndex, nil, b)
|
||||
|
||||
local isBlankA = valA == nil or valA == "" or tostring(valA):match("^%s*$")
|
||||
local isBlankB = valB == nil or valB == "" or tostring(valB):match("^%s*$")
|
||||
|
||||
-- Always put blank items at the bottom
|
||||
if isBlankA and not isBlankB then
|
||||
return false
|
||||
elseif not isBlankA and isBlankB then
|
||||
return true
|
||||
elseif isBlankA and isBlankB then
|
||||
return false
|
||||
end
|
||||
|
||||
local numA = tonumber(valA)
|
||||
local numB = tonumber(valB)
|
||||
|
||||
if numA and numB then
|
||||
if asc then
|
||||
return numA < numB
|
||||
else
|
||||
return numA > numB
|
||||
end
|
||||
else
|
||||
valA = tostring(valA or "")
|
||||
valB = tostring(valB or "")
|
||||
if asc then
|
||||
return valA < valB
|
||||
else
|
||||
return valA > valB
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
self.lastSortedCol = colIndex
|
||||
self.sortAsc = asc
|
||||
end
|
||||
|
||||
function RowListClass:OnKeyUp(key, doubleClick)
|
||||
if not self:IsShown() or not self:IsEnabled() then
|
||||
return
|
||||
end
|
||||
|
||||
local function isScrollKey(k)
|
||||
if k == "WHEELUP" then return true, -1, 10 end
|
||||
if k == "WHEELDOWN" then return true, 1, -10 end
|
||||
return false, 0, 0
|
||||
end
|
||||
|
||||
local mOverControl = self:GetMouseOverControl()
|
||||
if mOverControl and mOverControl.OnKeyDown then
|
||||
return mOverControl:OnKeyDown(key)
|
||||
end
|
||||
|
||||
if not self:IsMouseOver() and key:match("BUTTON") then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get cursor info
|
||||
local x, y = self:GetPos()
|
||||
local cursorX, cursorY = GetCursorPos()
|
||||
local scrollOffsetH = self.controls.scrollBarH and self.controls.scrollBarH.offset or 0
|
||||
local relX = cursorX - (x + 2)
|
||||
local relY = cursorY - (y + 2)
|
||||
local adjustedRelX = relX + scrollOffsetH
|
||||
|
||||
-- Middle-click resets column width
|
||||
if key == "MIDDLEBUTTON" then
|
||||
for colIndex, column in ipairs(self.colList) do
|
||||
local colOffset = column._offset
|
||||
local colWidth = column.width or column._width
|
||||
if colOffset and colWidth then
|
||||
local mOver = adjustedRelX >= colOffset and adjustedRelX <= colOffset + colWidth and relY >= 0 and relY <= 18
|
||||
if mOver then
|
||||
-- Initialize if not present
|
||||
self._autoSizeToggleState[colIndex] = not self._autoSizeToggleState[colIndex]
|
||||
|
||||
local newWidth
|
||||
if self._autoSizeToggleState[colIndex] then
|
||||
-- First toggle: size to contents
|
||||
local maxWidth = 0
|
||||
for _, rowIndex in ipairs(self.list) do
|
||||
local val = self:GetRowValue(colIndex, nil, rowIndex)
|
||||
if val ~= nil then
|
||||
local width = DrawStringWidth(self.rowHeight, "FIXED", tostring(val))
|
||||
maxWidth = math.max(maxWidth, width)
|
||||
end
|
||||
end
|
||||
local labelWidth = DrawStringWidth(self.rowHeight, "FIXED", tostring(column.label or ""))
|
||||
newWidth = math.max(40, math.max(maxWidth, labelWidth) + 10)
|
||||
else
|
||||
-- Second toggle: reset to label or 150, whichever is greater
|
||||
local labelWidth = DrawStringWidth(self.rowHeight, "FIXED", tostring(column.label or ""))
|
||||
newWidth = math.max(150, labelWidth + 10)
|
||||
end
|
||||
|
||||
column.width = newWidth
|
||||
|
||||
if column.specColRef then
|
||||
column.specColRef.width = newWidth
|
||||
main.curSpecCol = column.specColRef
|
||||
main.controls.colWidth:SetText(newWidth)
|
||||
end
|
||||
|
||||
self:BuildColumns()
|
||||
return self
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
-- Scroll behavior
|
||||
local isScroll, scrollStep, colDelta = isScrollKey(key)
|
||||
if isScroll then
|
||||
local overColumnHeader = false
|
||||
for _, column in ipairs(self.colList) do
|
||||
local colOffset = column._offset
|
||||
local colWidth = column.width or column._width
|
||||
if colOffset and colWidth then
|
||||
local mOver = adjustedRelX >= colOffset and adjustedRelX <= colOffset + colWidth and relY >= 0 and relY <= 18
|
||||
if mOver then
|
||||
-- Widen column if hovering over it
|
||||
overColumnHeader = true
|
||||
local newWidth = math.max(40, colWidth + colDelta)
|
||||
column.width = newWidth
|
||||
if column.specColRef then
|
||||
column.specColRef.width = newWidth
|
||||
main.curSpecCol = column.specColRef
|
||||
main.controls.colWidth:SetText(newWidth)
|
||||
end
|
||||
self:BuildColumns()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Scroll vertically or horizontally if not resizing column
|
||||
if not overColumnHeader then
|
||||
if self.scroll and self.scrollH and IsKeyDown("SHIFT") then
|
||||
self.controls.scrollBarH:Scroll(scrollStep)
|
||||
else
|
||||
self.controls.scrollBarV:Scroll(scrollStep)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -15,6 +15,9 @@ end
|
||||
|
||||
function ScriptListClass:OnSelClick(index, script, doubleClick)
|
||||
if doubleClick then
|
||||
if main.controls.clearAutoClearOutput.state then
|
||||
wipeTable(main.scriptOutput)
|
||||
end
|
||||
local errMsg = PLoadModule("Scripts/"..script..".lua")
|
||||
if errMsg then
|
||||
print(errMsg)
|
||||
|
||||
@@ -205,8 +205,10 @@ function main:Init()
|
||||
return #self.scriptOutput > 0
|
||||
end
|
||||
}
|
||||
|
||||
self.controls.helpText = new("LabelControl", {"TOPLEFT",self.controls.clearOutput,"BOTTOMLEFT"}, {0, 12, 100, 16}, "Press Ctrl+F5 to re-export\ndata from the game")
|
||||
self.controls.clearAutoClearOutput = new("CheckBoxControl", { "TOPLEFT", self.controls.clearOutput, "BOTTOMLEFT" }, { 120, 10, 20, 20 }, "Auto Clear Output:", function(state)
|
||||
self.clearAutoClearOutput = state
|
||||
end, nil, false)
|
||||
self.controls.helpText = new("LabelControl", {"TOPLEFT",self.controls.clearOutput,"BOTTOMLEFT"}, {0, 42, 100, 16}, "Press Ctrl+F5 to re-export\ndata from the game")
|
||||
|
||||
self.controls.scriptList = new("ScriptListControl", nil, {270, 35, 100, 300}) {
|
||||
shown = function()
|
||||
@@ -219,7 +221,12 @@ function main:Init()
|
||||
end
|
||||
}
|
||||
|
||||
self.controls.datList = new("DatListControl", nil, {10, 70, 250, function() return self.screenH - 70 end})
|
||||
self.controls.datSearch = new("EditControl", {"TOPLEFT", self.controls.datSource, "BOTTOMLEFT"}, {0, 2, 250, 18}, nil, "^7Search", nil, nil, function(buf)
|
||||
self.controls.datList.searchBuf = buf
|
||||
self.controls.datList:BuildFilteredList()
|
||||
end, nil, nil, true)
|
||||
|
||||
self.controls.datList = new("DatListControl", {"TOPLEFT",self.controls.datSearch,"BOTTOMLEFT"}, {0, 2, 250, function() return self.screenH - 100 end})
|
||||
|
||||
self.controls.specEditToggle = new("ButtonControl", nil, {270, 10, 100, 18}, function() return self.editSpec and "Done <<" or "Edit >>" end, function()
|
||||
self.editSpec = not self.editSpec
|
||||
@@ -316,6 +323,7 @@ function main:Init()
|
||||
}
|
||||
self.controls.filter.tooltipText = "Takes a Lua expression that returns true or false for a row.\nE.g. `Id:match(\"test\")` or for a key column, `Col and Col.Id:match(\"test\")`"
|
||||
self.controls.filterError = new("LabelControl", {"LEFT",self.controls.filter,"RIGHT"}, {4, 2, 0, 14}, "")
|
||||
self.controls.showRaw = new("LabelControl", {"LEFT",self.controls.filter,"RIGHT"}, {600, 2, 0, 14}, "^7Hold ALT to show raw data.")
|
||||
|
||||
self.controls.rowList = new("RowListControl", nil, {270, 0, 0, 0}) {
|
||||
y = function()
|
||||
@@ -428,6 +436,19 @@ function main:OnFrame()
|
||||
end
|
||||
|
||||
function main:OnKeyDown(key, doubleClick)
|
||||
-- Ctrl+F shortcut for focusing dat file Search
|
||||
if key == "f" and IsKeyDown("CTRL") then
|
||||
if self.controls and self.controls.datSearch and self.SelectControl then
|
||||
self:SelectControl(self.controls.datSearch)
|
||||
end
|
||||
return
|
||||
-- ESC key closes Dat window so that the script menu is shown.
|
||||
elseif key == "ESCAPE" then
|
||||
if self.controls and self.controls.scripts and self.SelectControl then
|
||||
self:SetCurrentDat()
|
||||
end
|
||||
return
|
||||
end
|
||||
t_insert(self.inputEvents, { type = "KeyDown", key = key, doubleClick = doubleClick })
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user