Quantcast

Lots of updates. Can resize, move frame. 4 collumns in a row now

Petr Grabovoy [05-27-16 - 07:32]
Lots of updates. Can resize, move frame. 4 collumns in a row now
Filename
VarrenDevTool.lua
VarrenDevTool.xml
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