Quantcast

Huge refactoring. Color change menu added

Petr Grabovoy [06-15-16 - 07:27]
Huge refactoring. Color change menu added
Filename
Modules/ViragDevToolEvents.lua
Modules/ViragDevToolFunctionLogger.lua
Modules/ViragDevToolHistory.lua
Modules/ViragDevToolModulesCore.lua
ViragDevTool.lua
ViragDevTool.toc
ViragDevTool.xml
ViragDevToolMappings.lua
ViragDevToolOptions.lua
ViragDevToolOptions.xml
diff --git a/Modules/ViragDevToolEvents.lua b/Modules/ViragDevToolEvents.lua
new file mode 100644
index 0000000..0195db7
--- /dev/null
+++ b/Modules/ViragDevToolEvents.lua
@@ -0,0 +1,93 @@
+local ViragDevTool = ViragDevTool
+
+-----------------------------------------------------------------------------------------------
+-- EVENTS
+-----------------------------------------------------------------------------------------------
+function ViragDevTool:GetListenerFrame()
+    if (self.listenerFrame == nil) then
+        self.listenerFrame = CreateFrame("Frame", "ViragDevToolListenerFrame", UIParent);
+    end
+    return self.listenerFrame
+end
+
+function ViragDevTool:StartMonitorEvent(event, unit)
+    if not event then return end
+
+    local tEvent = self:GetMonitoredEvent(event, unit)
+
+    if not tEvent then
+        tEvent = { event = event, unit = unit, active = true }
+        table.insert(self.settings.events, tEvent)
+    end
+
+    local f = self:GetListenerFrame()
+
+    if type(unit) == "string" then
+        f:RegisterUnitEvent(event, unit)
+    else
+        f:RegisterEvent(event)
+    end
+
+    tEvent.active = true
+
+    local eventName = event
+    if unit then eventName = eventName .. " " .. tostring(unit) end
+    self:print(self.colors.green .. "Start" .. self.colors.white .. " event monitoring: " .. self.colors.lightblue .. eventName)
+end
+
+function ViragDevTool:StopMonitorEvent(event, unit)
+    if not event then return end
+    local tEvent = self:GetMonitoredEvent(event, unit)
+
+    if tEvent and tEvent.active then
+        local f = self:GetListenerFrame()
+        f:UnregisterEvent(event)
+        tEvent.active = false
+
+        local eventName = event
+        if unit then eventName = eventName .. " " .. tostring(unit) end
+
+        self:print(self.colors.red .. "Stop" .. self.colors.white .. " event monitoring: " .. self.colors.lightblue .. eventName)
+    end
+end
+
+function ViragDevTool:ToggleMonitorEvent(tEvent)
+    if tEvent then
+        if tEvent.active then
+            self:StopMonitorEvent(tEvent.event, tEvent.unit)
+        else
+            self:StartMonitorEvent(tEvent.event, tEvent.unit)
+        end
+    end
+end
+
+function ViragDevTool:SetMonitorEventScript()
+    local f = self:GetListenerFrame()
+
+    f:SetScript("OnEvent", function(this, ...)
+        local args = { ... }
+        local event = args[1]
+        if ViragDevTool:GetMonitoredEvent(event) then
+            if #args == 1 then args = args[1] end
+            ViragDevTool:Add(args, date("%X") .. " " .. event)
+        end
+    end);
+end
+
+function ViragDevTool:GetMonitoredEvent(event, args)
+
+    if self.settings == nil or self.settings.events == nil then return end
+
+    local found
+
+    for _, tEvent in pairs(self.settings.events) do
+        if tEvent.event == event then
+            found = tEvent
+            break
+        end
+    end
+
+    if found then
+        return found
+    end
+end
diff --git a/Modules/ViragDevToolFunctionLogger.lua b/Modules/ViragDevToolFunctionLogger.lua
new file mode 100644
index 0000000..5749253
--- /dev/null
+++ b/Modules/ViragDevToolFunctionLogger.lua
@@ -0,0 +1,154 @@
+local ViragDevTool = ViragDevTool
+
+
+-----------------------------------------------------------------------------------------------
+-- FUNCTION LOGGIN
+-----------------------------------------------------------------------------------------------
+function ViragDevTool:StartLogFunctionCalls(strParentPath, strFnToLog)
+    --for now you have to tell exect table name can be _G can be something like ViragDevTool.table.table
+    if strParentPath == nil then return end
+
+    local savedInfo = self:GetLogFunctionCalls(strParentPath, strFnToLog)
+
+    if savedInfo == nil then
+
+
+        local tParent = self:FromStrToObject(strParentPath)
+        if tParent == nil then
+            self:print(self.colors.red .. "Error: " .. self.colors.white ..
+                    "Cannot add function monitoring: " .. self.colors.lightblue .. "_G." .. tostring(strParentPath) .. " == nil")
+            return
+        end
+
+        savedInfo = {
+            parentTableName = strParentPath,
+            fnName = strFnToLog,
+            active = false
+        }
+
+        table.insert(self.settings.logs, savedInfo)
+    end
+
+    self:ActivateLogFunctionCalls(savedInfo)
+end
+
+
+function ViragDevTool:ActivateLogFunctionCalls(info)
+    if info.active then return end
+
+    local tParent = self:FromStrToObject(info.parentTableName) or {}
+
+    local shrinkFn = function(table)
+        if #table == 1 then
+            return table[1]
+        elseif #table == 0 then
+            return nil
+        end
+        return table
+    end
+
+    for fnName, oldFn in pairs(tParent) do
+        if type(oldFn) == "function" and
+                (info.fnName == nil or fnName == info.fnName) then
+            local savedOldFn = self:GetOldFn(tParent, fnName, oldFn)
+
+            if savedOldFn == nil then
+                self:SaveOldFn(tParent, fnName, oldFn)
+                savedOldFn = self:GetOldFn(tParent, fnName, oldFn)
+            end
+
+            tParent[fnName] = function(...)
+                local result = { savedOldFn(...) }
+                local args = { ... }
+
+                local fnNameWitArgs = ViragDevTool.colors.lightgreen .. fnName ..
+                        ViragDevTool.colors.white .. "(" .. self:argstostring(args) .. ")" ..
+                        ViragDevTool.colors.lightblue
+
+                ViragDevTool_AddData({
+                    OUT = shrinkFn(result),
+                    IN = shrinkFn(args)
+                }, fnNameWitArgs)
+
+                return unpack(result)
+            end
+        end
+    end
+
+    self:print(self.colors.green .. "Start" .. self.colors.white .. " function monitoring: " .. self.colors.lightblue .. self:LogFunctionCallText(info))
+    info.active = true
+end
+
+function ViragDevTool:DeactivateLogFunctionCalls(info)
+    if not info.active then return end
+
+    local tParent = self:FromStrToObject(info.parentTableName) or {}
+    for fnName, oldFn in pairs(tParent) do
+        if type(oldFn) == "function" and
+                (info.fnName == nil or fnName == info.fnName) then
+            tParent[fnName] = self:GetOldFn(tParent, fnName, oldFn)
+        end
+    end
+
+    self:print(self.colors.red .. "Stop" .. self.colors.white .. " function monitoring: " .. self.colors.lightblue .. self:LogFunctionCallText(info))
+    info.active = false
+end
+
+function ViragDevTool:ToggleFnLogger(info)
+    if info.active then
+        self:DeactivateLogFunctionCalls(info)
+    else
+        self:ActivateLogFunctionCalls(info)
+    end
+end
+
+function ViragDevTool:GetOldFn(tParent, fnName, oldFn)
+    if self.tempOldFns and
+            self.tempOldFns[tParent] and
+            self.tempOldFns[tParent][fnName] then
+        return self.tempOldFns[tParent][fnName]
+    end
+end
+
+function ViragDevTool:SaveOldFn(tParent, fnName, oldFn)
+    if self.tempOldFns == nil then
+        self.tempOldFns = {}
+    end
+
+    -- tParent is actual parent an not string name
+    if self.tempOldFns[tParent] == nil then
+        self.tempOldFns[tParent] = {}
+    end
+
+    -- clear
+    if oldFn == nil then
+        self.tempOldFns[tParent][fnName] = nil
+    end
+
+    --else save only if it doesn't exists
+    if self.tempOldFns[tParent][fnName] == nil then
+        self.tempOldFns[tParent][fnName] = oldFn
+    end
+end
+
+function ViragDevTool:GetLogFunctionCalls(strParentTableName, strFnName)
+    for _, v in pairs(self.settings.logs) do
+        if v.parentTableName == strParentTableName
+                and strFnName == v.fnName then
+            return v
+        end
+    end
+end
+
+function ViragDevTool:LogFunctionCallText(info)
+    if info == nil then return "" end
+
+    local tableName = info.parentTableName == "_G" and "_G" or "_G." .. tostring(info.parentTableName)
+
+    if info.fnName then
+        return info.fnName .. " fn in " .. tableName
+
+    else
+        return "ALL fn in " .. tableName
+    end
+end
\ No newline at end of file
diff --git a/Modules/ViragDevToolHistory.lua b/Modules/ViragDevToolHistory.lua
new file mode 100644
index 0000000..3719fd4
--- /dev/null
+++ b/Modules/ViragDevToolHistory.lua
@@ -0,0 +1,47 @@
+local ViragDevTool = ViragDevTool
+
+
+-----------------------------------------------------------------------------------------------
+-- HISTORY
+-----------------------------------------------------------------------------------------------
+function ViragDevTool:AddToHistory(strValue)
+    if self.settings and self.settings.history then
+        local hist = self.settings.history
+
+        -- if already contains value then just move it to top
+        for k, v in pairs(hist or {}) do
+            if v == strValue then
+                table.remove(hist, k)
+                table.insert(hist, 1, strValue)
+                self:UpdateSideBarUI()
+                return
+            end
+        end
+
+        table.insert(hist, 1, strValue)
+
+        local maxSize = self.default_settings.MAX_HISTORY_SIZE
+        if self.settings and self.settings.MAX_HISTORY_SIZE then
+            maxSize = self.settings.MAX_HISTORY_SIZE
+        end
+
+        while #hist > maxSize do -- can have only 10 values in history
+        table.remove(hist, maxSize)
+        end
+
+        self:UpdateSideBarUI()
+    end
+end
+
+
+function ViragDevTool:FindIn(parent, strName, fn)
+    local resultTable = {}
+
+    for k, v in pairs(parent or {}) do
+        if fn(k, strName) then
+            resultTable[k] = v
+        end
+    end
+
+    return resultTable
+end
\ No newline at end of file
diff --git a/Modules/ViragDevToolModulesCore.lua b/Modules/ViragDevToolModulesCore.lua
new file mode 100644
index 0000000..6b68c5c
--- /dev/null
+++ b/Modules/ViragDevToolModulesCore.lua
@@ -0,0 +1,35 @@
+local ViragDevTool = ViragDevTool
+
+--TODO not implemented yet just an idea
+--- This class handles modules that can be registered in this addon.
+-- if you want to create custom module it has to implement following methods
+-- module lifecicle is
+-- 1) Register your module
+-- local newModule = ...
+-- ViragDevTool:AddModule(newModule)
+-- 2) for now every module gets module:Init() on startup
+-- 3) every module gets module:Load() if user clics on module tab
+-- 4) module:UnLoad() if user clicks on some other tab other then your modules
+-- 5) module:UpdateModuleUI(sideFrame) can be called at any time
+--    and here you have to update sidebar scroll list items
+-- 6) module:UpdateRow(rowFrame, numRowId) can be called at any time
+--    and here you have to update given raw for mait scrollframe table
+-- 7) module:ProcessMsg(msg) can be called at any time
+--    and myou have to handle message from ui
+--local ViragDevToolModule = {}
+--function ViragDevToolModule:GetName() end
+--function ViragDevToolModule:Init() end
+--function ViragDevToolModule:Load() end
+--function ViragDevToolModule:UnLoad() end
+--function ViragDevToolModule:UpdateModuleUI(sideFrame) end
+--function ViragDevToolModule:UpdateRow(rowFrame, numRowId) end
+--function ViragDevToolModule:ProcessMsg(msg) end
+--[[
+function ViragDevTool:AddModule(module)
+    if self.modules == nil then
+        self.modules = {}
+    end
+
+    table.insert(self.modules, module)
+end
+]]--
\ No newline at end of file
diff --git a/ViragDevTool.lua b/ViragDevTool.lua
index 6bfdc93..3802855 100644
--- a/ViragDevTool.lua
+++ b/ViragDevTool.lua
@@ -98,17 +98,10 @@ ViragDevTool = {
         VDT_RESET_WND = function(msg2, msg3)
             ViragDevToolFrame:ClearAllPoints()
             ViragDevToolFrame:SetPoint("CENTER", UIParent)
-            ViragDevToolFrame:SetSize(600, 200)
+            ViragDevToolFrame:SetSize(635, 200)
         end
     },

-
-
-
-    -- mapping table is used to store searches and diferent values that are frequently used
-    -- for example we may need some api or some variable so we can add it here
-    mapping = {},
-
     -- Default settings
     -- this variable will be used only on first load so it is just default init with empty values.
     -- will be replaced with ViragDevTool_Settings at 2-nd start
@@ -140,6 +133,22 @@ ViragDevTool = {

         -- stores arguments for fcunction calls --todo implement
         tArgs = {},
+        colors = {
+            white = "|cFFFFFFFF",
+            gray = "|cFFBEB9B5",
+            lightblue = "|cFF96C0CE",
+            lightgreen = "|cFF98FB98",
+            red = "|cFFFF0000",
+            green = "|cFF00FF00",
+            darkred = "|cFFC25B56",
+            parent = "|cFFBEB9B5",
+            error = "|cFFFF0000",
+            ok = "|cFF00FF00",
+            table = { 0.41, 0.80, 0.94, 1 },
+            string = { 0.67, 0.83, 0.45, 1 },
+            number = { 1, 0.96, 0.41, 1 },
+            default = { 1, 1, 1, 1 },
+        },

         -- events to monitor
         -- format ({event = "EVENT_NAME", unit = "player", active = true}, ...)
@@ -161,33 +170,14 @@ ViragDevTool = {
         },
     }
 }
-
 -- just remove global reference so it is easy to read with my ide
 local ViragDevTool = ViragDevTool

 -----------------------------------------------------------------------------------------------
--- ViragDevTool.colors
+-- ViragDevTool.colors additional setup
 -----------------------------------------------------------------------------------------------
--- todo refactore this
-ViragDevTool.colors = {
-    white = "|cFFFFFFFF",
-    gray = "|cFFBEB9B5",
-    lightblue = "|cFF96C0CE",
-    lightgreen = "|cFF98FB98",
-    red = "|cFFFF0000",
-    green = "|cFF00FF00",
-    darkred = "|cFFC25B56",
-    parent = "|cFFBEB9B5",
-    error = "|cFFFF0000",
-    ok = "|cFF00FF00",
-}
-
---this colors are used in main table text
-ViragDevTool.colors["table"] = { 0.41, 0.80, 0.94, 1 }
-ViragDevTool.colors["string"] = { 0.67, 0.83, 0.45, 1 }
-ViragDevTool.colors["number"] = { 1, 0.96, 0.41, 1 }
-ViragDevTool.colors["function"] = { 1, 0.49, 0.04, 1 }
-ViragDevTool.colors["default"] = { 1, 1, 1, 1 }
+ViragDevTool.default_settings.colors["function"] = { 1, 0.49, 0.04, 1 }
+ViragDevTool.colors = ViragDevTool.default_settings.colors --shortcut

 -----------------------------------------------------------------------------------------------
 -- ViragDevToolLinkedList == ViragDevTool.list
@@ -493,6 +483,63 @@ function ViragDevTool:SetVisible(view, isVisible)
     end
 end

+-- i ddo manual resizing and not the defalt
+-- self:GetParent():StartSizing("BOTTOMRIGHT");
+-- self:GetParent():StopMovingOrSizing();
+-- BEACUSE i don't like default behaviur.
+function ViragDevTool:ResizeMainFrame(dragFrame)
+    local parentFrame = dragFrame:GetParent()
+
+    local left = dragFrame:GetParent():GetLeft()
+    local top = dragFrame:GetParent():GetTop()
+
+    local x, y = GetCursorPosition()
+    local s = parentFrame:GetEffectiveScale()
+    x = x / s
+    y = y / s
+
+    local maxX, maxY = parentFrame:GetMaxResize()
+    local minX, minY = parentFrame:GetMinResize()
+
+
+    parentFrame:SetSize(self:CalculatePosition(x - left, minX, maxX),
+        self:CalculatePosition(top - y, minY, maxY))
+end
+
+
+function ViragDevTool:DragResizeColumn(dragFrame, ignoreMousePosition)
+    local parentFrame = dragFrame:GetParent()
+
+    -- 150 and 50 are just const values. safe to change
+    local minX = 150
+    local maxX = parentFrame:GetWidth() - 50
+
+    local pos = dragFrame:GetLeft() - parentFrame:GetLeft()
+    pos = self:CalculatePosition(pos, minX, maxX)
+
+
+    if not ignoreMousePosition then
+        local x, y = GetCursorPosition()
+        local s = parentFrame:GetEffectiveScale()
+        x = x / s
+        y = y / s
+        if x <= (minX + parentFrame:GetLeft()) then pos = minX end
+        if x >= (maxX + parentFrame:GetLeft()) then pos = maxX end
+    end
+
+    dragFrame:ClearAllPoints()
+    dragFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", pos, -30) -- 30 is offset from above (top buttons)
+
+    -- save pos so we can restore it on reloda ui or logout
+    self.settings.collResizerPosition = pos
+end
+
+function ViragDevTool:CalculatePosition(pos, min, max)
+    if pos < min then pos = min end
+    if pos > max then pos = max end
+    return pos
+end
+
 -----------------------------------------------------------------------------------------------
 -- Main table UI
 -----------------------------------------------------------------------------------------------
@@ -500,6 +547,7 @@ function ViragDevTool:ForceUpdateMainTableUI()
     self:UpdateMainTableUI(true)
 end

+
 function ViragDevTool:UpdateMainTableUI(force)

     if not force then
@@ -534,7 +582,7 @@ end
 function ViragDevTool:UpdateMainTableUIOptimized()

     if (self.waitFrame == nil) then
-        self.waitFrame = CreateFrame("Frame", "WaitFrame", UIParent);
+        self.waitFrame = CreateFrame("Frame", "ViragDevToolWaitFrame", UIParent);
         self.waitFrame.lastUpdateTime = 0
         self.waitFrame:SetScript("onUpdate", function(self, elapse)

@@ -563,118 +611,117 @@ function ViragDevTool:ScrollBar_AddChildren(scrollFrame, strTemplate)
     end
 end

--- i ddo manual resizing and not the defalt
--- self:GetParent():StartSizing("BOTTOMRIGHT");
--- self:GetParent():StopMovingOrSizing();
--- BEACUSE i don't like default behaviur.
-function ViragDevTool:ResizeMainFrame(dragFrame)
-    local parentFrame = dragFrame:GetParent()
+function ViragDevTool:UIUpdateMainTableButton(node, info, id)
+    local color = self.colors[type(info.value)]
+    if not color then color = self.colors.default end
+    if type(info.value) == "table" and self:IsMetaTableNode(info) then
+        color = self.colors.default
+    end

-    local left = dragFrame:GetParent():GetLeft()
-    local top = dragFrame:GetParent():GetTop()
+    node.nameButton:SetPoint("LEFT", node.rowNumberButton, "RIGHT", 10 * info.padding - 10, 0)

-    local x, y = GetCursorPosition()
-    local s = parentFrame:GetEffectiveScale()
-    x = x / s
-    y = y / s
+    node.valueButton:SetText(self:ToUIString(info.value, info.name, true))
+    node.nameButton:SetText(tostring(info.name))
+    node.rowNumberButton:SetText(tostring(id))

-    local maxX, maxY = parentFrame:GetMaxResize()
-    local minX, minY = parentFrame:GetMinResize()
+    node.nameButton:GetFontString():SetTextColor(unpack(color))
+    node.valueButton:GetFontString():SetTextColor(unpack(color))
+    node.rowNumberButton:GetFontString():SetTextColor(unpack(color))

-
-    parentFrame:SetSize(self:CalculatePosition(x - left, minX, maxX),
-        self:CalculatePosition(top - y, minY, maxY))
+    self:SetMainTableButtonScript(node.nameButton, info)
+    self:SetMainTableButtonScript(node.valueButton, info)
 end

+function ViragDevTool:ToUIString(value, name, withoutLineBrakes)
+    local result
+    local valueType = type(value)

-function ViragDevTool:DragResizeColumn(dragFrame, ignoreMousePosition)
-    local parentFrame = dragFrame:GetParent()
+    if valueType == "table" then
+        result = self:GetObjectInfoFromWoWAPI(name, value) or tostring(value)
+        result = "(" .. self:tablelength(value) .. ") " .. result
+    else
+        result = tostring(value)
+    end

-    -- 150 and 50 are just const values. safe to change
-    local minX = 150
-    local maxX = parentFrame:GetWidth() - 50
+    if withoutLineBrakes then
+        result = string.gsub(string.gsub(tostring(result), "|n", ""), "\n", "")
+    end

-    local pos = dragFrame:GetLeft() - parentFrame:GetLeft()
-    pos = self:CalculatePosition(pos, minX, maxX)
+    return result
+end

+function ViragDevTool:GetObjectInfoFromWoWAPI(helperText, value)
+    local resultStr
+    local ok, objectType = self:TryCallAPIFn(value.GetObjectType, value)

-    if not ignoreMousePosition then
-        local x, y = GetCursorPosition()
-        local s = parentFrame:GetEffectiveScale()
-        x = x / s
-        y = y / s
-        if x <= (minX + parentFrame:GetLeft()) then pos = minX end
-        if x >= (maxX + parentFrame:GetLeft()) then pos = maxX end
-    end
+    -- try to get frame name
+    if ok then
+        local concat = function(str, before, after)
+            before = before or ""
+            after = after or ""
+            if str then
+                return resultStr .. " " .. before .. str .. after
+            end
+            return resultStr
+        end

-    dragFrame:ClearAllPoints()
-    dragFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", pos, -30) -- 30 is offset from above (top buttons)
+        local _, name = self:TryCallAPIFn(value.GetName, value)
+        local _, texture = self:TryCallAPIFn(value.GetTexture, value)
+        local _, text = self:TryCallAPIFn(value.GetText, value)

-    -- save pos so we can restore it on reloda ui or logout
-    self.settings.collResizerPosition = pos
-end
+        local hasSize, left, bottom, width, height = self:TryCallAPIFn(value.GetBoundsRect, value)

-function ViragDevTool:CalculatePosition(pos, min, max)
-    if pos < min then pos = min end
-    if pos > max then pos = max end
-    return pos
-end

-function ViragDevTool:UIUpdateMainTableButton(node, info, id)
-    local nameButton = node.nameButton;
-    --local typeButton = node.typeButton
-    local valueButton = node.valueButton
-    local rowNumberButton = node.rowNumberButton
+        resultStr = objectType or ""
+        if hasSize then
+            resultStr = concat(self.colors.white .. "[" ..
+                    tostring(self:round(left)) .. ", " ..
+                    tostring(self:round(bottom)) .. ", " ..
+                    tostring(self:round(width)) .. ", " ..
+                    tostring(self:round(height)) .. "]",
+                self.colors.lightblue)
+        end

-    local value = info.value
-    local name = info.name
-    local padding = info.padding

-    nameButton:SetPoint("LEFT", rowNumberButton, "RIGHT", 10 * padding - 10, 0)
+        if helperText ~= name then
+            resultStr = concat(name, self.colors.gray .. "<", ">" .. self.colors.white)
+        end

-    local valueType = type(value)
+        resultStr = concat(texture, self.colors.white, self.colors.white)
+        resultStr = concat(text, self.colors.white .. "'", "'")
+        resultStr = concat(tostring(value), self.colors.lightblue)
+    end

-    valueButton:SetText(tostring(value))
-    nameButton:SetText(tostring(name))
-    --typeButton:SetText(valueType)
-    rowNumberButton:SetText(tostring(id))
+    return resultStr
+end

-    -- local color = "ViragDevToolBaseFont"
-    local color = self.colors[valueType]
-    if not color then color = self.colors.default end
+function ViragDevTool:TryCallAPIFn(fn, value)
+    -- this function is helper fn to get table type from wow api.
+    -- if there is GetObjectType then we will return it.
+    -- returns Button, Frame or something like this

-    if valueType == "table" then
-        if not self:IsMetaTableNode(info) then
-            local objectType, optionalFrameName = self:GetObjectTypeFromWoWAPI(value)
-            if objectType then
-                if optionalFrameName and optionalFrameName ~= name then
-                    objectType = objectType .. " <" .. optionalFrameName .. ">"
-                end
+    -- VALIDATION
+    if type(value) ~= "table" then return
+    end

-                valueButton:SetText(objectType .. "  " .. tostring(value))
-            end
-        else
-            color = self.colors.default
-        end
+    -- VALIDATION FIX if __index is function we dont want to execute it
+    -- Example in ACP.L
+    local mt = getmetatable(value)
+    if mt and type(mt.__index) == "function" then return
+    end

-        local resultStringName = tostring(name)
-        local MAX_STRING_SIZE = 100
-        if #resultStringName >= MAX_STRING_SIZE then
-            resultStringName = string.sub(resultStringName, 0, MAX_STRING_SIZE) .. "..."
+    -- VALIDATION is forbidden from wow api
+    if value.IsForbidden then
+        local ok, forbidden = pcall(value.IsForbidden, value)
+        if not ok or (ok and forbidden) then return
         end
-
-        nameButton:SetText(resultStringName .. "   (" .. self:tablelength(value) .. ") ");
-    elseif valueType == "string" then
-        valueButton:SetText(string.gsub(string.gsub(tostring(value), "|n", ""), "\n", ""))
+    end
+    -- VALIDATION has WoW API
+    if not fn or type(fn) ~= "function" then return
     end

-    nameButton:GetFontString():SetTextColor(unpack(color))
-    -- typeButton:GetFontString():SetTextColor(unpack(color))
-    valueButton:GetFontString():SetTextColor(unpack(color))
-    rowNumberButton:GetFontString():SetTextColor(unpack(color))
-
-    self:SetMainTableButtonScript(nameButton, info)
-    self:SetMainTableButtonScript(valueButton, info)
+    -- MAIN PART:
+    return pcall(fn, value)
 end

 -----------------------------------------------------------------------------------------------
@@ -790,15 +837,14 @@ function ViragDevTool:UpdateSideBarRow(view, data, lineplusoffset)
     end
 end

-
-
 -----------------------------------------------------------------------------------------------
 -- Main table row button clicks setup
 -----------------------------------------------------------------------------------------------
 function ViragDevTool:SetMainTableButtonScript(button, info)
     --todo add left click = copy to chat
     local valueType = type(info.value)
-    local leftClickFn = function() end
+    local leftClickFn = function()
+    end

     if valueType == "table" then
         leftClickFn = function(this, button, down)
@@ -814,11 +860,13 @@ function ViragDevTool:SetMainTableButtonScript(button, info)
         end
     end

-    button:SetScript("OnMouseUp", function(this, button, down)
-        if button == "RightButton" then
-            ViragDevTool:print(info.name .. " - " .. tostring(info.value))
+    button:SetScript("OnMouseUp", function(this, mouseButton, down)
+        if mouseButton == "RightButton" then
+            local nameButton = this:GetParent().nameButton
+            local valueButton = this:GetParent().valueButton
+            ViragDevTool:print(nameButton:GetText() .. " - " .. valueButton:GetText())
         else
-            leftClickFn(this, button, down)
+            leftClickFn(this, mouseButton, down)
         end
     end)
 end
@@ -890,7 +938,8 @@ function ViragDevTool:ProcessCallFunctionData(ok, info, parent, args, results)
     local padding = info.padding + 1

     local stateStr = function(state)
-        if state then return C.ok .. "OK" end
+        if state then return C.ok .. "OK"
+        end
         return C.error .. "ERROR"
     end

@@ -929,18 +978,9 @@ function ViragDevTool:ProcessCallFunctionData(ok, info, parent, args, results)
     self:print(stateStr(ok) .. " " .. fnNameWithArgs .. C.gray .. " returns:" .. returnFormatedStr)
 end

--- type can be string or int or bool -- not table or userdata or function for now
-function ViragDevTool:SetArgForFunctionCall(arg, position, type)
-    if type == "number" then arg = tonumber(arg)
-    elseif type == "boolean" then arg = toboolean(arg)
-    elseif type == "nil" then arg = nil
-    elseif type == "string" then arg = tostring(arg)
-    else return
-    end -- cant handle this type of args
-
-    self.settings.tArgs[position] = arg
-end
-
+-----------------------------------------------------------------------------------------------
+-- BOTTOM PANEL Fn Arguments button  and arguments input eddit box
+-----------------------------------------------------------------------------------------------
 function ViragDevTool:SetArgForFunctionCallFromString(argStr)
     local args = self.split(argStr, ",") or {}

@@ -967,291 +1007,16 @@ function ViragDevTool:SetArgForFunctionCallFromString(argStr)
 end

 -----------------------------------------------------------------------------------------------
--- HISTORY
------------------------------------------------------------------------------------------------
-function ViragDevTool:AddToHistory(strValue)
-    if self.settings and self.settings.history then
-        local hist = self.settings.history
-
-        -- if already contains value then just move it to top
-        for k, v in pairs(hist or {}) do
-            if v == strValue then
-                table.remove(hist, k)
-                table.insert(hist, 1, strValue)
-                self:UpdateSideBarUI()
-                return
-            end
-        end
-
-        table.insert(hist, 1, strValue)
-
-        local maxSize = self.default_settings.MAX_HISTORY_SIZE
-        if self.settings and self.settings.MAX_HISTORY_SIZE then
-            maxSize = self.settings.MAX_HISTORY_SIZE
-        end
-
-        while #hist > maxSize do -- can have only 10 values in history
-        table.remove(hist, maxSize)
-        end
-
-        self:UpdateSideBarUI()
-    end
-end
-
-
------------------------------------------------------------------------------------------------
--- EVENTS
------------------------------------------------------------------------------------------------
-function ViragDevTool:GetListenerFrame()
-    if (self.listenerFrame == nil) then
-        self.listenerFrame = CreateFrame("Frame", "WaitFrame", UIParent);
-    end
-    return self.listenerFrame
-end
-
-function ViragDevTool:StartMonitorEvent(event, unit)
-    if not event then return end
-
-    local tEvent = self:GetMonitoredEvent(event, unit)
-
-    if not tEvent then
-        tEvent = { event = event, unit = unit, active = true }
-        table.insert(self.settings.events, tEvent)
-    end
-
-    local f = self:GetListenerFrame()
-
-    if type(unit) == "string" then
-        f:RegisterUnitEvent(event, unit)
-    else
-        f:RegisterEvent(event)
-    end
-
-    tEvent.active = true
-
-    local eventName = event
-    if unit then eventName = eventName .. " " .. tostring(unit) end
-    self:print(self.colors.green .. "Start" .. self.colors.white .. " event monitoring: " .. self.colors.lightblue .. eventName)
-end
-
-function ViragDevTool:StopMonitorEvent(event, unit)
-    if not event then return end
-    local tEvent = self:GetMonitoredEvent(event, unit)
-
-    if tEvent and tEvent.active then
-        local f = self:GetListenerFrame()
-        f:UnregisterEvent(event)
-        tEvent.active = false
-
-        local eventName = event
-        if unit then eventName = eventName .. " " .. tostring(unit) end
-
-        self:print(self.colors.red .. "Stop" .. self.colors.white .. " event monitoring: " .. self.colors.lightblue .. eventName)
-    end
-end
-
-function ViragDevTool:ToggleMonitorEvent(tEvent)
-    if tEvent then
-        if tEvent.active then
-            self:StopMonitorEvent(tEvent.event, tEvent.unit)
-        else
-            self:StartMonitorEvent(tEvent.event, tEvent.unit)
-        end
-    end
-end
-
-function ViragDevTool:SetMonitorEventScript()
-    local f = self:GetListenerFrame()
-
-    f:SetScript("OnEvent", function(this, ...)
-        local args = { ... }
-        local event = args[1]
-        if ViragDevTool:GetMonitoredEvent(event) then
-            if #args == 1 then args = args[1] end
-            ViragDevTool:Add(args, date("%X") .. " " .. event)
-        end
-    end);
-end
-
-function ViragDevTool:GetMonitoredEvent(event, args)
-
-    if self.settings == nil or self.settings.events == nil then return end
-
-    local found
-
-    for _, tEvent in pairs(self.settings.events) do
-        if tEvent.event == event then
-            found = tEvent
-            break
-        end
-    end
-
-    if found then
-        return found
-    end
-end
-
------------------------------------------------------------------------------------------------
--- FUNCTION LOGGIN
------------------------------------------------------------------------------------------------
-function ViragDevTool:StartLogFunctionCalls(strParentPath, strFnToLog)
-    --for now you have to tell exect table name can be _G can be something like ViragDevTool.table.table
-    if strParentPath == nil then return end
-
-    local savedInfo = self:GetLogFunctionCalls(strParentPath, strFnToLog)
-
-    if savedInfo == nil then
-
-
-        local tParent = self:FromStrToObject(strParentPath)
-        if tParent == nil then
-            self:print(self.colors.red .. "Error: " .. self.colors.white ..
-                    "Cannot add function monitoring: " .. self.colors.lightblue .. "_G." .. tostring(strParentPath) .. " == nil")
-            return
-        end
-
-        savedInfo = {
-            parentTableName = strParentPath,
-            fnName = strFnToLog,
-            active = false
-        }
-
-        table.insert(self.settings.logs, savedInfo)
-    end
-
-    self:ActivateLogFunctionCalls(savedInfo)
-end
-
-
-function ViragDevTool:ActivateLogFunctionCalls(info)
-    if info.active then return end
-
-    local tParent = self:FromStrToObject(info.parentTableName) or {}
-
-    local shrinkFn = function(table)
-        if #table == 1 then
-            return table[1]
-        elseif #table == 0 then
-            return nil
-        end
-        return table
-    end
-
-    for fnName, oldFn in pairs(tParent) do
-        if type(oldFn) == "function" and
-                (info.fnName == nil or fnName == info.fnName) then
-            local savedOldFn = self:GetOldFn(tParent, fnName, oldFn)
-
-            if savedOldFn == nil then
-                self:SaveOldFn(tParent, fnName, oldFn)
-                savedOldFn = self:GetOldFn(tParent, fnName, oldFn)
-            end
-
-            tParent[fnName] = function(...)
-                local result = { savedOldFn(...) }
-                local args = { ... }
-
-                local fnNameWitArgs = ViragDevTool.colors.lightgreen .. fnName ..
-                        ViragDevTool.colors.white .. "(" .. self:argstostring(args) .. ")" ..
-                        ViragDevTool.colors.lightblue
-
-                ViragDevTool_AddData({
-                    OUT = shrinkFn(result),
-                    IN = shrinkFn(args)
-                }, fnNameWitArgs)
-
-                return unpack(result)
-            end
-        end
-    end
-
-    self:print(self.colors.green .. "Start" .. self.colors.white .. " function monitoring: " .. self.colors.lightblue .. self:LogFunctionCallText(info))
-    info.active = true
-end
-
-function ViragDevTool:DeactivateLogFunctionCalls(info)
-    if not info.active then return end
-
-    local tParent = self:FromStrToObject(info.parentTableName) or {}
-    for fnName, oldFn in pairs(tParent) do
-        if type(oldFn) == "function" and
-                (info.fnName == nil or fnName == info.fnName) then
-            tParent[fnName] = self:GetOldFn(tParent, fnName, oldFn)
-        end
-    end
-
-    self:print(self.colors.red .. "Stop" .. self.colors.white .. " function monitoring: " .. self.colors.lightblue .. self:LogFunctionCallText(info))
-    info.active = false
-end
-
-function ViragDevTool:ToggleFnLogger(info)
-    if info.active then
-        self:DeactivateLogFunctionCalls(info)
-    else
-        self:ActivateLogFunctionCalls(info)
-    end
-end
-
-function ViragDevTool:GetOldFn(tParent, fnName, oldFn)
-    if self.tempOldFns and
-            self.tempOldFns[tParent] and
-            self.tempOldFns[tParent][fnName] then
-        return self.tempOldFns[tParent][fnName]
-    end
-end
-
-function ViragDevTool:SaveOldFn(tParent, fnName, oldFn)
-    if self.tempOldFns == nil then
-        self.tempOldFns = {}
-    end
-
-    -- tParent is actual parent an not string name
-    if self.tempOldFns[tParent] == nil then
-        self.tempOldFns[tParent] = {}
-    end
-
-    -- clear
-    if oldFn == nil then
-        self.tempOldFns[tParent][fnName] = nil
-    end
-
-    --else save only if it doesn't exists
-    if self.tempOldFns[tParent][fnName] == nil then
-        self.tempOldFns[tParent][fnName] = oldFn
-    end
-end
-
-function ViragDevTool:GetLogFunctionCalls(strParentTableName, strFnName)
-    for _, v in pairs(self.settings.logs) do
-        if v.parentTableName == strParentTableName
-                and strFnName == v.fnName then
-            return v
-        end
-    end
-end
-
-function ViragDevTool:LogFunctionCallText(info)
-    if info == nil then return "" end
-
-    local tableName = info.parentTableName == "_G" and "_G" or "_G." .. tostring(info.parentTableName)
-
-    if info.fnName then
-        return info.fnName .. " fn in " .. tableName
-
-    else
-        return "ALL fn in " .. tableName
-    end
-end
-
------------------------------------------------------------------------------------------------
 -- LIFECICLE
 -----------------------------------------------------------------------------------------------
 function ViragDevTool:OnLoad(mainFrame)
     self.wndRef = mainFrame

     self.wndRef:RegisterEvent("ADDON_LOADED")
-    self.wndRef:SetScript("OnEvent", function(this, event, ...)
-        ViragDevTool:OnEvent(this, event, ...); -- call one of the functions above
+    self.wndRef:SetScript("OnEvent", function(this, event, addonName, ...)
+        if event == "ADDON_LOADED" and addonName == self.ADDON_NAME then
+            self:OnAddonSettingsLoaded()
+        end
     end);

     --register update scrollFrame
@@ -1264,7 +1029,6 @@ function ViragDevTool:OnLoad(mainFrame)
         self:UpdateSideBarUI()
     end

-
     -- register slash cmd
     SLASH_VIRAGDEVTOOLS1 = '/vdt';
     function SlashCmdList.VIRAGDEVTOOLS(msg, editbox)
@@ -1276,17 +1040,13 @@ function ViragDevTool:OnLoad(mainFrame)
     end
 end

-function ViragDevTool:OnEvent(this, event, ...)
-    local arg = { ... }
-    if event == "ADDON_LOADED" and arg[1] == self.ADDON_NAME then
-        ViragDevTool_Settings = self:SetupForSettings(ViragDevTool_Settings)
-    end
-end
-
-function ViragDevTool:SetupForSettings(s)
+function ViragDevTool:OnAddonSettingsLoaded()
+    local s = ViragDevTool_Settings

+    self:Add(ViragDevTool_Settings.colors, "ViragDevTool_Settings.colors")
     if s == nil then
         s = self.default_settings
+        ViragDevTool_Settings = s
     else
         -- validating current settings and updating if version changed

@@ -1295,7 +1055,7 @@ function ViragDevTool:SetupForSettings(s)

             -- if setting is a table of size 0 or if value is nil set it to default
             -- for now we have only arrays in settings so its fine to use #table
-            if (type(savedValue) == "table" and #savedValue == 0)
+            if (type(savedValue) == "table" and self:tablelength(savedValue) == 0)
                     or savedValue == nil then

                 s[k] = defaultValue
@@ -1342,9 +1102,15 @@ function ViragDevTool:SetupForSettings(s)
     -- setup events part 2 set scripts on frame to listen registered events
     self:SetMonitorEventScript()

-    self.wndRef.columnResizer:SetPoint("TOPLEFT", self.wndRef, "TOPLEFT", s.collResizerPosition, -30)

-    return s
+    --we store colors not in saved settings for now
+    if s.colors then self.colors = s.colors
+    end
+    s.colors = self.colors
+
+    self:LoadInterfaceOptions()
+
+    self.wndRef.columnResizer:SetPoint("TOPLEFT", self.wndRef, "TOPLEFT", s.collResizerPosition, -30)
 end

 -----------------------------------------------------------------------------------------------
@@ -1362,6 +1128,14 @@ function ViragDevTool:split(sep)
     return fields
 end

+function ViragDevTool.starts(String, Start)
+    return string.sub(String, 1, string.len(Start)) == Start
+end
+
+function ViragDevTool.ends(String, End)
+    return End == '' or string.sub(String, -string.len(End)) == End
+end
+
 function ViragDevTool:tablelength(T)
     local count = 0
     for _ in pairs(T) do count = count + 1
@@ -1369,47 +1143,13 @@ function ViragDevTool:tablelength(T)
     return count
 end

-function ViragDevTool:GetObjectTypeFromWoWAPI(value)
-    -- this function is helper fn to get table type from wow api.
-    -- if there is GetObjectType then we will return it.
-    -- returns Button, Frame or something like this
-
-    -- VALIDATION
-    if type(value) ~= "table" then return end
-
-    -- VALIDATION FIX if __index is function we dont want to execute it
-    -- Example in ACP.L
-    local mt = getmetatable(value)
-    if mt and type(mt.__index) == "function" then return end
-
-    -- VALIDATION is forbidden from wow api
-    if value.IsForbidden then
-        local ok, forbidden = pcall(value.IsForbidden, value)
-        if not ok or (ok and forbidden) then return end
-    end
-    -- VALIDATION has WoW API
-    if not value.GetObjectType then return end
-
-    -- MAIN PART:
-    local ok, objectType = pcall(value.GetObjectType, value)
-    -- try to get frame name
-    if ok then
-        local name
-        if value.GetName then
-            ok, name = pcall(value.GetName, value)
-            name = ok and name or nil
-        end
-
-        return objectType, name
-    end
-end
-
 function ViragDevTool:argstostring(args)
     local strArgs = ""
     local found = false
     local delimiter = ""
     for i = 10, 1, -1 do
-        if args[i] ~= nil then found = true end
+        if args[i] ~= nil then found = true
+        end

         if found then
             strArgs = tostring(args[i]) .. delimiter .. strArgs
@@ -1418,3 +1158,22 @@ function ViragDevTool:argstostring(args)
     end
     return strArgs
 end
+
+function ViragDevTool:round(num, idp)
+    if num == nil then return nil end
+    local mult = 10 ^ (idp or 0)
+    return math.floor(num * mult + 0.5) / mult
+end
+
+function ViragDevTool:RGBPercToHex(r, g, b, a)
+    r = r <= 1 and r >= 0 and r or 0
+    g = g <= 1 and g >= 0 and g or 0
+    b = b <= 1 and b >= 0 and b or 0
+    a = a <= 1 and a >= 0 and a or 0
+    return string.format("%02x%02x%02x%02x", a * 255, r * 255, g * 255, b * 255)
+end
+
+local function HexToRGBPerc(hex)
+    local rhex, ghex, bhex = string.sub(hex, 1, 2), string.sub(hex, 3, 4), string.sub(hex, 5, 6)
+    return tonumber(rhex, 16) / 255, tonumber(ghex, 16) / 255, tonumber(bhex, 16) / 255
+end
diff --git a/ViragDevTool.toc b/ViragDevTool.toc
index 735b4fc..bee5154 100644
--- a/ViragDevTool.toc
+++ b/ViragDevTool.toc
@@ -4,5 +4,13 @@
 ## Version: 0.1
 ## SavedVariables: ViragDevTool_Settings
 ViragDevTool.lua
-ViragDevToolMappings.lua
+
+Modules/ViragDevToolModulesCore.lua
+Modules/ViragDevToolEvents.lua
+Modules/ViragDevToolFunctionLogger.lua
+Modules/ViragDevToolHistory.lua
+
 ViragDevTool.xml
+
+ViragDevToolOptions.xml
+ViragDevToolOptions.lua
\ No newline at end of file
diff --git a/ViragDevTool.xml b/ViragDevTool.xml
index c398b3f..1b1606a 100644
--- a/ViragDevTool.xml
+++ b/ViragDevTool.xml
@@ -1,7 +1,7 @@
 <Ui>
     <!--FONTS -->
-    <Font name="ViragDevToolDefaultFont" inherits="SystemFont_Small" justifyW="LEFT" justifyH="LEFT" virtual="true"/>
-    <Font name="ViragDevToolMediumFont" inherits="SystemFont_Med1" justifyW="LEFT" justifyH="LEFT" virtual="true"/>
+    <Font name="ViragDevToolDefaultFont" inherits="SystemFont_Small" justifyV="TOP" justifyH="LEFT" />
+    <Font name="ViragDevToolMediumFont" inherits="SystemFont_Med1" justifyV="TOP" justifyH="LEFT" virtual="true"/>

     <Texture name="ViragDevToolStrokeTexture" virtual="true">
         <Color r="0.1" g="0.1" b="0.1" a="1"/>
@@ -136,13 +136,6 @@
     <Button name="ViragDevToolBaseButtonTemplate" virtual="true">
         <Layers>
             <Layer level="BACKGROUND">
-                <Texture>
-                    <Anchors>
-                        <Anchor point="TOPRIGHT"/>
-                        <Anchor point="BOTTOMLEFT"/>
-                    </Anchors>
-                    <Color r="0" g="0" b="0.1" a="0.5"/>
-                </Texture>

                 <Texture>
                     <Size y="25"/>
@@ -150,7 +143,7 @@
                         <Anchor point="TOPRIGHT"/>
                         <Anchor point="LEFT"/>
                     </Anchors>
-                    <Color r="0.55" g="0" b="0" a="0.5"/>
+                    <Color r="0.55" g="0" b="0.1" a="0.5"/>
                 </Texture>
             </Layer>
         </Layers>
@@ -287,7 +280,7 @@
                     parentKey="nameButton">
                 <Anchors>
                     <Anchor point="LEFT" relativeTo="$parentCountColumn" relativePoint="RIGHT"/>
-                     <Anchor point="RIGHT" relativeTo="ViragDevToolFrameColumnResizeButton" relativePoint="LEFT" x="10"/>
+                    <Anchor point="RIGHT" relativeTo="ViragDevToolFrameColumnResizeButton" relativePoint="LEFT" x="10"/>
                 </Anchors>
             </Button>
             <!--COLUMN 3-->
@@ -300,6 +293,10 @@
             </Button>
         </Frames>
     </Button>
+
+
+
+
     <!--*********************************************************************************************************
                                                       MAIN UI  enableMouse="true"

@@ -316,7 +313,7 @@

                 ViragDevTool:OnLoad(self)
                 self:SetUserPlaced(true)
-                self:SetMinResize(600, 200);
+                self:SetMinResize(635, 200);
                 self:SetMaxResize(UIParent:GetWidth(), UIParent:GetHeight());
                 self:RegisterForDrag("LeftButton");
             </OnLoad>
@@ -379,7 +376,7 @@
                 <PushedTexture file="Interface\ChatFrame\UI-ChatIM-SizeGrabber-Down"/>
             </Button>
             <!--LABEL FOR FUNCTION ARGUMENTS-->
-            <Button text="Fn Arguments:" inherits="ViragDevToolButtonTemplate" name="$parentFNCallLabelButton"
+            <Button text="Arguments:" inherits="ViragDevToolButtonTemplate" name="$parentFNCallLabelButton"
                     parentKey="clearFnArgsButton">
                 <Anchors>
                     <Anchor point="BOTTOMLEFT" y="5" x="5"/>
@@ -477,6 +474,7 @@
                     </OnClick>
                 </Scripts>
             </Button>
+
             <!--CLOSE UI BUTTON -->
             <Button name="$parentCloseWndButton">
                 <Size x="25" y="25"/>
@@ -494,6 +492,40 @@
                 <HighlightTexture file="Interface/BUTTONS/UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
             </Button>

+            <!--SETTINGS BUTTON -->
+            <Button name="$parentSettingsButton" inherits="ViragDevToolOptionsToggleButton">
+
+
+
+
+            </Button>
+            <Button name="$parentSettingsButton" virtual="true">
+                <Size x="25" y="25"/>
+                <Scripts>
+                    <OnClick>
+                        ViragDevTool:ToggleOptions()
+                    </OnClick>
+                </Scripts>
+                <Anchors>
+                    <Anchor point="RIGHT" relativeTo="$parentCloseWndButton" relativePoint="LEFT" x="5"/>
+                </Anchors>
+                <Layers>
+                    <Layer level="BACKGROUND">
+                        <Texture parentKey="I" file="Interface\common\help-i">
+                            <Size x="25" y="25"/>
+                            <Anchors>
+                                <Anchor point="CENTER"/>
+                            </Anchors>
+                        </Texture>
+                    </Layer>
+                </Layers>
+                <HighlightTexture alphaMode="ADD" file="Interface\Minimap\UI-Minimap-ZoomButton-Highlight">
+                    <Size x="20" y="20"/>
+                    <Anchors>
+                        <Anchor point="CENTER" x="-1" y="1"/>
+                    </Anchors>
+                </HighlightTexture>
+            </Button>
             <!--MAIN SCROLL FRAME-->
             <ScrollFrame name="$parentScrollFrame" inherits="ViragDevToolScrollFrameTemplate" parentKey="scrollFrame">
                 <Anchors>
@@ -654,4 +686,6 @@
             </Frame>
         </Frames>
     </Frame>
+
+
 </Ui>
\ No newline at end of file
diff --git a/ViragDevToolMappings.lua b/ViragDevToolMappings.lua
deleted file mode 100644
index 3066a0a..0000000
--- a/ViragDevToolMappings.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-local ViragDevTool = ViragDevTool
-
---- this is just example demo how you can use this file to explore api.
--- lets suppose we want to look into default api
--- then we can add all variables manualy to some table and add tis table with ViragDevTool_AddData
--- but we could create this table dinamicaly if we know prefix name
-function ViragDevTool:AddToMapping(strName, containsSearch)
-    local fn = containsSearch and string.match or self.starts
-    self.mapping[strName] = self:FindIn(_G, strName, fn)
-end
-
-function ViragDevTool:FindIn(parent, strName, fn)
-    local resultTable = {}
-
-    for k, v in pairs(parent or {}) do
-        if fn(k, strName) then
-            resultTable[k] = v
-        end
-    end
-
-    return resultTable
-end
-
-function ViragDevTool.starts(String, Start)
-    return string.sub(String, 1, string.len(Start)) == Start
-end
-
-function ViragDevTool.ends(String, End)
-    return End == '' or string.sub(String, -string.len(End)) == End
-end
-
-
---here or in any other place you can change mappings
---ViragDevTool:AddToMapping("LFD")
---ViragDevTool:AddToMapping("LFR")
---ViragDevTool:AddToMapping("LFG")
---ViragDevTool:AddToMapping("Virag")
-
diff --git a/ViragDevToolOptions.lua b/ViragDevToolOptions.lua
new file mode 100644
index 0000000..2c6a54a
--- /dev/null
+++ b/ViragDevToolOptions.lua
@@ -0,0 +1,101 @@
+function ViragDevTool:ToggleOptions()
+    --   InterfaceOptionsFrame_OpenToCategory(ViragDevTool.ADDON_NAME);
+    self:LoadInterfaceOptions()
+    self:Toggle(self.wndRef.optionsFrame)
+end
+
+
+function ViragDevTool:LoadInterfaceOptions()
+    if not self.wndRef.optionsFrame then
+        local frame = CreateFrame("Frame", "ViragDevToolOptionsMainFrame", self.wndRef, "ViragDevToolFrameTemplate")
+        frame:SetPoint("BOTTOM", self.wndRef, "TOP")
+        frame:SetHeight(35)
+        frame:SetPoint("LEFT")
+        frame:SetPoint("RIGHT")
+        frame:Hide()
+        self:Add(frame, "ViragDevToolOptionsFrameRowTemplate")
+
+        self:CreateColorPickerFrame(frame)
+        self.wndRef.optionsFrame = frame
+        --self.wndRef.optionsFrame.name = self.ADDON_NAME;
+        --InterfaceOptions_AddCategory(frame);
+        --InterfaceAddOnsList_Update();
+        --InterfaceOptionsFrame_OpenToCategory(ViragDevTool.ADDON_NAME);
+    end
+end
+
+
+function ViragDevTool:CreateColorPickerFrame(parent)
+    local point = "TOPLEFT"
+    local relativeTo = parent
+    local relativePoint = "TOPLEFT"
+    local xOffset = 5
+    local yOffset = -5
+
+    local update = function(button, color)
+        button.colorTexture:SetTexture(unpack(self.colors[color]))
+        button:GetHighlightTexture():SetVertexColor(unpack(self.colors[color]))
+        button:GetFontString():SetTextColor(unpack(self.colors[color]))
+        ViragDevTool:UpdateMainTableUI()
+    end
+
+    local buttons = {}
+    for i, color in pairs({ "table", "function", "string", "number", "default" }) do
+        local f = CreateFrame("Button", "VDTColorPickerFrameItem" .. i, parent, "VDTColorPickerFrameItemTemplate")
+        f:SetPoint(point, relativeTo, relativePoint, xOffset, yOffset)
+        local button = f.picker
+        buttons[i] = button
+        button:SetText(color)
+
+        button:SetScript("OnMouseUp", function(this, mouseButton, down)
+            if mouseButton == "RightButton" then
+                ViragDevTool.colors[color] = ViragDevTool.default_settings.colors[color]
+                update(this, color)
+            elseif mouseButton == "LeftButton" then
+                self:ShowColorPicker(color, function()
+                    local r, g, b = ColorPickerFrame:GetColorRGB()
+                    ViragDevTool.colors[color] = { r, g, b, 1 }
+                    update(this, color)
+                end)
+            end
+
+        end)
+
+        update(button, color)
+
+        point = "LEFT"
+        relativeTo = f
+        relativePoint = "RIGHT"
+        yOffset = 0
+        xOffset = 5
+    end
+
+    local button = CreateFrame("Button", "VDTFrameColorReset", parent, "ViragDevToolButtonTemplate")
+    button:SetPoint(point, relativeTo, relativePoint, xOffset, yOffset)
+    button:SetPoint("TOP", parent, "TOP", -5, -5)
+    button:SetPoint("BOTTOM", parent, "BOTTOM", -5, 5)
+    button:SetText("Reset")
+    button:SetScript("OnMouseUp", function(this, mouseButton, down)
+        for _, button in pairs(buttons) do
+            local color = button:GetText()
+            ViragDevTool.colors[color] = ViragDevTool.default_settings.colors[color]
+            update(button, color)
+        end
+    end)
+end
+
+function ViragDevTool:ShowColorPicker(color, changedCallback)
+    local r, g, b, a = unpack(ViragDevTool.colors[color])
+
+    ColorPickerFrame.func = function() end
+    ColorPickerFrame:SetColorRGB(r, g, b);
+    ColorPickerFrame.func = changedCallback
+
+    ColorPickerFrame.cancelFunc = function()
+        ColorPickerFrame:SetColorRGB(r, g, b);
+        changedCallback()
+    end
+
+    ColorPickerFrame:Hide(); -- Need to run the OnShow handler.
+    ColorPickerFrame:Show();
+end
\ No newline at end of file
diff --git a/ViragDevToolOptions.xml b/ViragDevToolOptions.xml
new file mode 100644
index 0000000..7a37ce6
--- /dev/null
+++ b/ViragDevToolOptions.xml
@@ -0,0 +1,219 @@
+<Ui>
+
+
+
+    <Frame name="VDTColorPickerFrameItemTemplate" virtual="true">
+        <Size x="100" y="25"/>
+
+        <Frames>
+            <Button text="table" name="$parentButton" inherits="ViragDevToolButtonTemplate" parentKey="picker">
+                <Scripts>
+                    <OnLoad>
+                        local fontString = self:GetFontString()
+                        fontString:SetPoint("LEFT", self, "LEFT", 5, 0)
+                        fontString:SetPoint("CENTER", self, "CENTER", 0, 0)
+                    </OnLoad>
+                </Scripts>
+                <Anchors>
+                    <Anchor point="TOPRIGHT"/>
+                    <Anchor point="BOTTOMLEFT"/>
+                </Anchors>
+
+
+                <NormalFont style="GameFontHighlight"/>
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <Texture parentKey="colorTexture">
+                            <Size x="15"/>
+                            <Anchors>
+                                <Anchor point="TOPRIGHT" x="-5" y="-5"/>
+                                <Anchor point="BOTTOM" y="5"/>
+                            </Anchors>
+                            <Color r="0.5" g="0" b="0" a="1"/>
+                        </Texture>
+                    </Layer>
+                </Layers>
+            </Button>
+        </Frames>
+    </Frame>
+    <Layers>
+        <Layer level="ARTWORK">
+            <Texture>
+                <Anchors>
+                    <Anchor point="TOPRIGHT"/>
+                    <Anchor point="BOTTOMLEFT"/>
+                </Anchors>
+                <Color r="0" g="0.30" b="0.1" a="0.7"/>
+            </Texture>
+        </Layer>
+    </Layers>
+    <Frame name="ViragDevToolOptionsFrameRowTemplate" virtual="true">
+        <Layers>
+            <Layer level="BACKGROUND">
+                <Texture>
+                    <Anchors>
+                        <Anchor point="TOPRIGHT"/>
+                        <Anchor point="BOTTOMLEFT"/>
+                    </Anchors>
+                    <!-- <Color r="0.5" g="0.7" b="0.9" a="0.8"/>-->
+                    <Color r="0.5" g="0" b="0.1" a="0.5"/>
+                </Texture>
+            </Layer>
+        </Layers>
+    </Frame>
+
+    <Frame name="ViragDevToolOptionsFrameHeaderTemplate" virtual="true">
+        <Frames>
+            <Button text="Header" name="$parentButton" parentKey="header">
+                <Scripts>
+                    <OnLoad>
+                        local fontString = self:GetFontString()
+                        fontString:SetPoint("LEFT", self, "LEFT", 5, 0)
+                        fontString:SetPoint("CENTER", self, "CENTER", 0, 0)
+                    </OnLoad>
+                </Scripts>
+
+                <Anchors>
+                    <Anchor point="TOPRIGHT"/>
+                    <Anchor point="BOTTOMLEFT"/>
+                </Anchors>
+
+
+                <NormalFont style="GameFontHighlight"/>
+                <NormalTexture>
+                    <Size x="15"/>
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" x="-5" y="-5"/>
+                        <Anchor point="BOTTOM" y="5"/>
+                    </Anchors>
+                    <Color r="0.5" g="0" b="0" a="1"/>
+                </NormalTexture>
+            </Button>
+        </Frames>
+    </Frame>
+
+    <Frame name="ViragDevToolOptionsSectionTemplate" virtual="true">
+        <Size y="85"/>
+
+        <Anchors>
+            <Anchor point="RIGHT"/>
+            <Anchor point="LEFT"/>
+        </Anchors>
+        <Frames>
+            <Frame name="$parentCPHeader" inherits="ViragDevToolOptionsFrameHeaderTemplate" parentKey="header">
+                <Size y="35"/>
+                <Anchors>
+                    <Anchor point="TOPRIGHT" x="-5" y="-5"/>
+                    <Anchor point="LEFT" x="5"/>
+                </Anchors>
+                <Layers>
+                    <Layer level="ARTWORK">
+                        <Texture>
+                            <Anchors>
+                                <Anchor point="TOPRIGHT"/>
+                                <Anchor point="BOTTOMLEFT"/>
+                            </Anchors>
+                            <Color r="0.5" g="0" b="0" a="0.5"/>
+                        </Texture>
+                    </Layer>
+                </Layers>
+            </Frame>
+            <Frame name="$parentCPRow" inherits="ViragDevToolOptionsFrameRowTemplate" parentKey="row">
+                <Size y="35"/>
+                <Anchors>
+                    <Anchor point="TOP" relativeTo="$parentCPHeader" relativePoint="BOTTOM" y="-5"/>
+                    <Anchor point="RIGHT" x="-5"/>
+                    <Anchor point="LEFT" x="5"/>
+                </Anchors>
+            </Frame>
+        </Frames>
+
+        <Layers>
+            <Layer level="OVERLAY">
+                <Texture>
+                    <Size y="5"/>
+                    <Anchors>
+                        <Anchor point="TOPRIGHT"/>
+                        <Anchor point="LEFT"/>
+                    </Anchors>
+                    <Color r="0.5" g="0" b="0" a="0.5"/>
+                </Texture>
+                <Texture>
+                    <Size y="5"/>
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT"/>
+                        <Anchor point="LEFT"/>
+                    </Anchors>
+                    <Color r="0.5" g="0" b="0" a="0.5"/>
+                </Texture>
+                <Texture>
+                    <Size x="5"/>
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" y="-5"/>
+                        <Anchor point="BOTTOM" y="5"/>
+                    </Anchors>
+                    <Color r="0.5" g="0" b="0" a="0.5"/>
+                </Texture>
+                <Texture>
+                    <Size x="5"/>
+                    <Anchors>
+                        <Anchor point="TOPLEFT" y="-5"/>
+                        <Anchor point="BOTTOM" y="5"/>
+                    </Anchors>
+                    <Color r="0.5" g="0" b="0" a="0.5"/>
+                </Texture>
+                <Texture>
+                    <Anchors>
+                        <Anchor point="TOPRIGHT"/>
+                        <Anchor point="BOTTOMLEFT"/>
+                    </Anchors>
+                    <!-- <Color r="0.5" g="0.7" b="0.9" a="0.8"/>-->
+                    <Color r="0" g="0" b="0.1" a="0.5"/>
+                </Texture>
+            </Layer>
+
+
+        </Layers>
+    </Frame>
+
+    <Frame name="ViragDevToolOptionsFrame" virtual="true">
+        <Anchors>
+            <Anchor point="TOPRIGHT" x="-5" y="-5"/>
+            <Anchor point="LEFTBOTTOM" y="5" x="5"/>
+        </Anchors>
+        <Frames>
+            <Frame name="$parentCPSection" inherits="ViragDevToolOptionsSectionTemplate">
+                <Scripts>
+                    <OnLoad>
+                        ViragDevTool:CreateColorPickerFrame(self.row)
+                    </OnLoad>
+                </Scripts>
+                <Anchors>
+                    <Anchor point="TOP"/>
+                </Anchors>
+            </Frame>
+            <Frame name="$parentCPSection1" inherits="ViragDevToolOptionsSectionTemplate">
+                <Scripts>
+                    <OnLoad>
+                        --ViragDevTool:CreateColorPickerFrame(self.row)
+                    </OnLoad>
+                </Scripts>
+                <Anchors>
+                    <Anchor point="TOP" relativeTo="$parentCPSection" relativePoint="BOTTOM" y="-5"/>
+                </Anchors>
+            </Frame>
+        </Frames>
+
+        <Layers>
+            <Layer level="ARTWORK">
+                <Texture>
+                    <Anchors>
+                        <Anchor point="TOPRIGHT"/>
+                        <Anchor point="BOTTOMLEFT"/>
+                    </Anchors>
+                    <Color r="0.1" g="0.10" b="0.1" a="0.7"/>
+                </Texture>
+            </Layer>
+        </Layers>
+    </Frame>
+</Ui>
\ No newline at end of file