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 @@
<Ui>
<Script file="VarrenDevTool.lua"/>
- <Frame name="MyModEntryTemplate" virtual="true">
+ <Font name="MyModDefaultFont" inherits="SystemFont_Small" justifyH="LEFT" virtual="true"/>
+ <Font name="MyModTableFont" inherits="MyModDefaultFont" virtual="true">
+ <Color r="0.41" g="0.80" b="0.94"/>
+ </Font>
+ <Font name="MyModStringFont" inherits="MyModDefaultFont" virtual="true">
+ <Color r="0.67" g="0.83" b="0.45"/>
+ </Font>
+ <Font name="MyModNumberFont" inherits="MyModDefaultFont" virtual="true">
+ <Color r="1.0" g="0.96" b="0.41"/>
+ </Font>
+ <Font name="MyModFunctionFont" inherits="MyModDefaultFont" virtual="true">
+ <Color r="1.0" g="0.49" b="0.04"/>
+ </Font>
+ <Font name="MyModBaseFont" inherits="MyModDefaultFont" virtual="true">
+ <Color r="1.0" g="1.0" b="1.0"/>
+ </Font>
+ <Font name="MyModMetatableFont" inherits="MyModDefaultFont" virtual="true">
+ <Color r="1.0" g="1.0" b="1.0"/>
+ </Font>
+
+
+ <Button text="Test" name="MyModTopButton" inherits="UIPanelButtonTemplate" virtual="true">
+ <Size>
+ <AbsDimension x="150" y="25"/>
+ </Size>
+ <NormalFont style="GameFontHighlightLeft"/>
+ </Button>
+ <Frame name="MyModEntryTemplate" virtual="true">
<Anchors>
<Anchor point="TOPLEFT"/>
</Anchors>
<Size>
- <AbsDimension x="700" y="16"/>
+ <AbsDimension x="1200" y="12"/>
</Size>
<Frames>
- <Button text="Test Text" name="$parentButton" parentKey="mainButton" >
+ <Button text="table" name="$parentRowCellCount" parentKey="rowNumberButton">
+ <Size>
+ <AbsDimension x="50"/>
+ </Size>
+ <Anchors>
+ <Anchor point="TOP"/>
+ <Anchor point="BOTTOM"/>
+ <Anchor point="LEFT"/>
+ </Anchors>
+
+ <NormalFont style="MyModDefaultFont"/>
+ </Button>
+ <Button text="123456" name="$parentRowType" parentKey="typeButton">
+ <Size>
+ <AbsDimension x="50"/>
+ </Size>
+ <Anchors>
+ <Anchor point="TOP"/>
+ <Anchor point="BOTTOM"/>
+ <Anchor point="LEFT" relativeTo="$parentRowCellCount" relativePoint="RIGHT">
+ </Anchor>
+ </Anchors>
+
+ <NormalFont style="MyModDefaultFont"/>
+ </Button>
+
+ <Button text="Test Text" name="$parentNameRow" parentKey="nameButton">
+ <Size>
+ <AbsDimension x="400"/>
+ </Size>
+ <Anchors>
+ <Anchor point="TOP"/>
+ <Anchor point="BOTTOM"/>
+ <Anchor point="LEFT" relativeTo="$parentRowCellCount" relativePoint="RIGHT"/>
+ </Anchors>
+
+ <NormalFont style="MyModDefaultFont"/>
+ </Button>
+ <Button text="Test Text" name="$parentValueRow" parentKey="valueButton">
+ <Size>
+ <AbsDimension x="700"/>
+ </Size>
<Anchors>
- <Anchor point="TOPLEFT"/>
- <Anchor point="BOTTOMRIGHT"/>
+ <Anchor point="TOP"/>
+ <Anchor point="BOTTOM"/>
+ <Anchor point="RIGHT"/>
+ <Anchor point="LEFT" relativeTo="$parentNameRow" relativePoint="RIGHT"/>
+
</Anchors>
- <NormalFont style="GameFontHighlightLeft"/>
+ <NormalFont style="MyModDefaultFont"/>
</Button>
</Frames>
</Frame>
- <Frame name="MyMod" parent="UIParent" enableMouse="true" movable="true">
+ <Frame name="MyMod" parent="UIParent" enableMouse="true" movable="true" resizable="true">
<Size>
- <AbsDimension x="700" y="700"/>
+ <AbsDimension x="1200" y="600"/>
</Size>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
<Scripts>
- <OnLoad function="MyMod_OnLoad"/>
+ <OnLoad>
+ self:RegisterForDrag("LeftButton");
+ HybridScrollFrame_CreateButtons(self.scrollFrame, "MyModEntryTemplate", 0, -2)
+ </OnLoad>
<OnShow function="MyModScrollBar_Update"/>
+ <OnDragStart>self:StartSizing()</OnDragStart>
+ <OnReceiveDrag>
+ HybridScrollFrame_CreateButtons(self.scrollFrame, "MyModEntryTemplate", 0, -2);
+ MyModScrollBar_Update()
+ </OnReceiveDrag>
+ <OnDragStop>self:StopMovingOrSizing();</OnDragStop>
</Scripts>
- <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background"
+ <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\Tooltips\UI-Tooltip-Border"
tile="true">
<BackgroundInsets>
<AbsInset left="4" right="4" top="4" bottom="4"/>
@@ -42,12 +122,13 @@
<AbsValue val="16"/>
</EdgeSize>
</Backdrop>
+
<Frames>
- <ScrollFrame name="MyModScrollBar" inherits="HybridScrollFrameTemplate" parentKey="scrollFrame" >
+ <ScrollFrame name="$parentScrollFrame" inherits="HybridScrollFrameTemplate" parentKey="scrollFrame">
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
- <AbsDimension x="0" y="-8"/>
+ <AbsDimension x="8" y="-8"/>
</Offset>
</Anchor>
<Anchor point="BOTTOMRIGHT">
@@ -56,7 +137,9 @@
</Offset>
</Anchor>
</Anchors>
-
+ <Scripts>
+ <OnLoad> self.update = MyModScrollBar_Update </OnLoad>
+ </Scripts>
<Frames>
<Slider name="$parentScrollBar" inherits="HybridScrollBarTemplate">
<Anchors>
@@ -66,24 +149,69 @@
</Slider>
</Frames>
</ScrollFrame>
- <Button text="Undo" name="MyMod_Back_Button" inherits="UIPanelButtonTemplate">
+ <Frame name="$parentTopBar" parent="MyMod" enableMouse="true">
<Size>
- <AbsDimension x="150" y="16"/>
+ <AbsDimension y="25"/>
</Size>
- <NormalFont style="GameFontHighlightLeft"/>
<Scripts>
- <OnClick>
- MyMod_Back_Button_Click();
- </OnClick>
+ <OnLoad>
+ self:RegisterForDrag("LeftButton");
+ </OnLoad>
+ <OnDragStart>self:GetParent():StartMoving()</OnDragStart>
+ <OnReceiveDrag>MyModScrollBar_Update()</OnReceiveDrag>
+ <OnDragStop>self:GetParent():StopMovingOrSizing();</OnDragStop>
</Scripts>
+
+ <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background"
+ tile="true">
+
+ <TileSize>
+ <AbsValue val="16"/>
+ </TileSize>
+ <EdgeSize>
+ <AbsValue val="16"/>
+ </EdgeSize>
+ </Backdrop>
<Anchors>
- <Anchor point="TOPLEFT" relativeTo="MyModScrollBar" relativePoint="TOPLEFT">
- <Offset>
- <AbsDimension x="8" y="30"/>
- </Offset>
- </Anchor>
+ <Anchor point="LEFT"/>
+ <Anchor point="RIGHT"/>
+ <Anchor point="BOTTOM" relativeTo="$parent" relativePoint="TOP"/>
</Anchors>
- </Button>
+ <Frames>
+ <Button text="CLEAR" name="$parentClearButton" inherits="MyModTopButton">
+ <Scripts>
+ <OnClick>
+ MyMod_ClearData()
+ </OnClick>
+ </Scripts>
+ <Anchors>
+ <Anchor point="TOPLEFT" />
+ </Anchors>
+ </Button>
+ <Button text="_G" name="$parentAddGlobalButton" inherits="MyModTopButton">
+ <Scripts>
+ <OnClick>
+ MyMod_AddData(_G, "_G")
+ </OnClick>
+ </Scripts>
+ <Anchors>
+ <Anchor point="LEFT" relativeTo="$parentClearButton" relativePoint="RIGHT"/>
+ </Anchors>
+ </Button>
+ <Button text="Unit" name="$parentAddPlayerInfoButton" inherits="MyModTopButton">
+ <Scripts>
+ <OnClick>
+ local name, realm = UnitFullName("player")
+ MyMod_AddData(UnitGUID("player"), name .. "-" .. realm)
+ </OnClick>
+ </Scripts>
+ <Anchors>
+ <Anchor point="LEFT" relativeTo="$parentAddGlobalButton" relativePoint="RIGHT"/>
+ </Anchors>
+ </Button>
+ </Frames>
+ </Frame>
+
</Frames>
</Frame>
</Ui>
\ No newline at end of file