From dca36ad3de71ff96138255b9f0bff91ad4b8a8a3 Mon Sep 17 00:00:00 2001 From: Petr Grabovoy Date: Fri, 27 May 2016 10:32:30 +0300 Subject: [PATCH] Lots of updates. Can resize, move frame. 4 collumns in a row now --- VarrenDevTool.lua | 338 +++++++++++++++++++++++++++++++++-------------------- VarrenDevTool.xml | 178 ++++++++++++++++++++++++---- 2 files changed, 366 insertions(+), 150 deletions(-) diff --git a/VarrenDevTool.lua b/VarrenDevTool.lua index 2523550..178e4ca 100644 --- a/VarrenDevTool.lua +++ b/VarrenDevTool.lua @@ -1,192 +1,280 @@ -local MyModData = {} -local MyMODEVariablesToTrack = {} -- format{[0] = {table = someTable, }} -local MyModChildFrames = {} +local MyModData = { size = 0; first = nil, last = nil } -local ipairs, pairs, next, tonumber, tostring, type, print, string = ipairs, pairs, next, tonumber, tostring, type, print, string +function MyModData:GetInfoAtPosition(position) + if self.size < position or self.first == nil then + return nil + end -local _G = _G + local node = self.first + while position > 1 do + node = node.next + position = position - 1 + end -local MyMod_MEATATABLE_KEY = "$mt " - -function MyMod_OnLoad(self) - print("load") - MyMod_LoadData(_G) - local prevButton; - self.scrollFrame.update = MyModScrollBar_Update; - --[[ - for i = 1, (700 / 16) do - local frame = CreateFrame("FRAME", "MyModEntry" .. i, self, "MyModEntryTemplate"); - if i == 1 then - frame:SetPoint("TOPLEFT", MyModScrollBar, "TOPLEFT", 8, 0) - else - frame:SetPoint("TOPLEFT", MyModChildFrames[i - 1], "BOTTOMLEFT") + return node +end + +function MyModData:AddNodeAfter(node, prevNode) + local tempNext = node.next + node.next = prevNode + prevNode.next = tempNext + self.size = self.size + 1; +end + +function MyModData:AddNodesAfter(nodeList, parentNode) + local tempNext = parentNode.next + local currNode = parentNode; + + for _, node in pairs(nodeList) do + currNode.next = node + currNode = node + self.size = self.size + 1; + end + + currNode.next = tempNext + + if tempNext == nil then + self.last = currNode + end +end + +function MyModData:AddNode(data, dataName) + local node = self:NewNode(data, dataName) + + if self.first == nil then + self.first = node + self.last = node + else + if self.last ~= nil then + self.last.next = node end + self.last = node + end - --MyModChildFrames[i] = frame - end--]] + self.size = self.size + 1; +end - HybridScrollFrame_CreateButtons(self.scrollFrame, "MyModEntryTemplate", 0, -2); - MyModScrollBar:Show() +function MyModData:NewNode(data, dataName, padding, parent) + return { + name = dataName, + value = data, + next = nil, + padding = padding == nil and 0 or padding, + parent = parent + } end -function MyMod_LoadData(data, saveParent) - local i = 1 +function MyModData:RemoveChildNodes(node) + local currNode = node - local NewMyModData = {} + while true do + currNode = currNode.next - for k, v in pairs(data) do - if k ~= 0 then -- skip userdata - NewMyModData[i] = k - i = i + 1 - else - NewMyModData[i] = "$__userdata" .. tostring(v) + if currNode == nil then + node.next = nil + self.last = node + break end - end - local mt = getmetatable(data) - if mt then - for k, v in pairs(mt.__index) do - NewMyModData[i] = MyMod_MEATATABLE_KEY .. k - i = i + 1 + if currNode.padding <= node.padding then + node.next = currNode + break end - end - function bykey(a, b) - return tostring(a) < tostring(b) + self.size = self.size - 1 end +end - table.sort(NewMyModData, bykey) +function MyModData:Clear() + self.size = 0 + self.first = nil + self.last = nil +end - NewMyModData.count = table.getn(NewMyModData) +local ipairs, pairs, next, tonumber, tostring, type, print, string, getmetatable, table,pcall = ipairs, pairs, next, tonumber, tostring, type, print, string, getmetatable, table,pcall - if saveParent then - NewMyModData["parent"] = MyModData - end +local _G = _G + +function MyMod_ExpandCell(info) - if mt then - NewMyModData["meta"] = mt.__index + local nodeList = {} + local padding = info.padding + 1 + local couner = 0 + for k, v in pairs(info.value) do + if type(v) ~= "userdata" then + + nodeList[couner] = MyModData:NewNode(v, tostring(k), padding, info) + else + local mt = getmetatable(info.value) + if mt then + nodeList[couner] = MyModData:NewNode(mt.__index, "$metatable", padding, info) + end + end + couner = couner + 1 end - NewMyModData["src"] = data - MyModData = NewMyModData + table.sort(nodeList, function(a, b) + return a.name < b.name + end) - print(#MyModData .. " == " .. MyModData.count) + MyModData:AddNodesAfter(nodeList, info) + info.expanded = true + MyModScrollBar_Update() end -function MyMod_Table_Length(T) - local count = 0 - for _ in pairs(T) do count = count + 1 end - return count +function MyMod_ColapseCell(info) + MyModData:RemoveChildNodes(info) + info.expanded = nil + print("size: " .. MyModData.size) + MyModScrollBar_Update() +end + +function MyMod_AddData(data, dataName) + MyModData:AddNode(data, dataName) + MyModScrollBar_Update() +end +function MyMod_ClearData() + MyModData:Clear() + MyModScrollBar_Update() end function MyModScrollBar_Update() - print("ok: " ) - local lineplusoffset ; -- an index into our data calculated from the scroll offset + local scrollFrame = MyModScrollFrame - local scrollFrame = MyModScrollBar local buttons = scrollFrame.buttons; local offset = HybridScrollFrame_GetOffset(scrollFrame) + local totalRowsCount = MyModData.size + local lineplusoffset; -- an index into our data calculated from the scroll offset - for k, v in pairs(buttons) do + local nodeInfo = MyModData:GetInfoAtPosition(offset) + for k, view in pairs(buttons) do lineplusoffset = k + offset; - if lineplusoffset <= MyModData.count then - MyMod_UpdateListItem(v, MyModData[lineplusoffset]) - - v:Show(); + -- print("ok: " .. lineplusoffset .. " " .. offset .. " " .. k .. " " .. (nodeInfo ~= nil and nodeInfo.name or "nil")) + if lineplusoffset <= totalRowsCount then + MyMod_UpdateListItem(view, nodeInfo, lineplusoffset) + nodeInfo = nodeInfo.next + view:Show(); else - v:Hide(); + view:Hide(); end end - HybridScrollFrame_Update(scrollFrame, MyModData.count * 16, 700); + HybridScrollFrame_Update(scrollFrame, totalRowsCount * buttons[1]:GetHeight(), scrollFrame:GetHeight()); - print("UPDATED") end -function MyMod_Back_Button_Click() - print("und0") - if MyModData.parent then - print("undo") - MyModData = MyModData.parent - MyModScrollBar_Update() - end -end -function MyModEntry_ValueForKey(key) - local value = MyModData["src"][key] - local fromMT = false - if not value and MyModData["meta"] then -- and key~= nil and string.len(key)> string.len(MyMod_MEATATABLE_KEY) + 1 then - key = string.sub(key, string.len(MyMod_MEATATABLE_KEY) + 1) - value = MyModData["meta"][key] - fromMT = true - end - --print(key .." ".. string.sub(key, string.len(MyMod_MEATATABLE_KEY))) - - return value, fromMT -end -function MyMod_UpdateListItem(node, key) - local button = node.mainButton; +function MyMod_UpdateListItem(node, info, id) + local nameButton = node.nameButton; + local typeButton = node.typeButton + local valueButton = node.valueButton + local rowNumberButton = node.rowNumberButton + local value = info.value + local name = info.name + local padding = info.padding - local value, fromMT = MyModEntry_ValueForKey(key) - + nameButton:SetPoint("LEFT", node.typeButton, "RIGHT", 20 * padding, 0) + local valueType = type(value) + valueButton:SetText(tostring(value)) + nameButton:SetText(tostring(name)) + typeButton:SetText(valueType) + rowNumberButton:SetText(tostring(id)) - local valueType = type(value) - --local valueTypeStr = valueType - --node:SetText(valueTypeStr .. ": " .. tostring(key)); + local color = "MyModBaseFont" if valueType == "table" then + if name ~= "$metatable" then + if value.GetObjectType then + if value.IsForbidden and value:IsForbidden() then + else + valueButton:SetText(value:GetObjectType() .. " " .. tostring(value)) + end + end + color = "MyModTableFont"; + else + color = "MyModMetatableFont"; + end + local resultStringName = tostring(name) + local MAX_STRING_SIZE = 60 + if #resultStringName >= MAX_STRING_SIZE then + resultStringName = string.sub(resultStringName, 0, MAX_STRING_SIZE) .. "..." + end + local function tablelength(T) + local count = 0 + for _ in pairs(T) do count = count + 1 end + return count + end - -- print("function info: " .. tostring(type(info))) + nameButton:SetText(resultStringName .. " (" .. tablelength(value) .. ") "); - button:SetText(MyMod_Table_Length(value) .. " table " .. ": " .. tostring(key)); - button:SetNormalFontObject("GameFontGreen"); elseif valueType == "userdata" then - button:SetText(valueType .. ": " .. tostring(key)); - button:SetNormalFontObject("GameFontDisable"); - elseif valueType == "number" then - button:SetText(valueType .. ": " .. tostring(key) .. " = " .. tostring(value)); - button:SetNormalFontObject("NumberFontNormalYellow"); + color = "MyModTableFont"; elseif valueType == "string" then - button:SetText(valueType .. ": " .. tostring(key)); - button:SetNormalFontObject("GameFontRed"); + valueButton:SetText(string.gsub(string.gsub(tostring(value), "|n", ""), "\n", "")) + color = "MyModStringFont"; + elseif valueType == "number" then + color = "MyModNumberFont"; elseif valueType == "function" then - - button:SetText(valueType .. ": " .. tostring(key) .. " = " .. tostring(value)); - button:SetNormalFontObject("GameFontWhite"); - else - button:SetText(valueType .. ": " .. tostring(key) .. " = " .. tostring(value)); - button:SetNormalFontObject("GameFontDisable"); + color = "MyModFunctionFont"; end - if valueType == "table" or valueType == "userdata" then - button:SetScript("OnMouseUp", function(self, button, down) + node.nameButton:SetNormalFontObject(color); + node.typeButton:SetNormalFontObject(color) + node.valueButton:SetNormalFontObject(color) + node.rowNumberButton:SetNormalFontObject(color) + + if valueType == "table" then + nameButton:SetScript("OnMouseUp", function(self, button, down) print("click") - -- local info = getmetatable(value) - MyMod_LoadData(value, true) - MyModScrollBar:SetVerticalScroll(0) - MyModScrollBar_Update() + if info.expanded then + MyMod_ColapseCell(info) + else + MyMod_ExpandCell(info) + end end) elseif valueType == "function" then - button:SetScript("OnMouseUp", function(self, button, down) + nameButton:SetScript("OnMouseUp", function(self, button, down) print("click") - local result = value() - local resultType = type(result) - local additionalInfo = "" - if resultType == "string" or resultType == "number" then - additionalInfo = tostring(result) - end - - print("returns: " .. resultType .. " " .. additionalInfo) + MyMod_TryCallFunction(info) end) else - button:SetScript("OnMouseUp", nil) + nameButton:SetScript("OnMouseUp", nil) end end + +function MyMod_TryCallFunction(info) + local value = info.value + + local ok, result = pcall(value) + if ok then + local resultType = type(result) + local additionalInfo = "" + if resultType == "string" or resultType == "number" then + additionalInfo = tostring(result) + end + + print("returns: " .. resultType .. " " .. additionalInfo) + else + local parent = info.parent + if parent then + if parent.name == "$metatable" then + parent = parent.parent + print("found metatable" .. info.name) + end + + local ok, result = pcall(parent.value[info.name], parent.value) + local resultType = type(result) + local additionalInfo = tostring(result) + + print(parent.name ..":".. info.name .."() returns: " .. additionalInfo.. " ("..resultType ..")" ) + end + end +end \ No newline at end of file diff --git a/VarrenDevTool.xml b/VarrenDevTool.xml index c559848..e1d3ce3 100644 --- a/VarrenDevTool.xml +++ b/VarrenDevTool.xml @@ -1,36 +1,116 @@