Quantcast

Move to AddonCore and add version to About box

James Whitehead II [05-31-11 - 15:22]
Move to AddonCore and add version to About box

Fixes 22
Filename
AddonCore.lua
TomTom.lua
TomTom.toc
TomTom_Config.lua
diff --git a/AddonCore.lua b/AddonCore.lua
new file mode 100644
index 0000000..a765133
--- /dev/null
+++ b/AddonCore.lua
@@ -0,0 +1,277 @@
+--[[-------------------------------------------------------------------------
+-- AddonCore.lua
+--
+-- This is a very simple, bare-minimum core for addon development. It provide
+-- methods to register events, call initialization functions, and sets up the
+-- localization table so it can be used elsewhere. This file is designed to be
+-- loaded first, as it has no further dependencies.
+--
+-- Events registered:
+--   * ADDON_LOADED - Watch for saved variables to be loaded, and call the
+--       'Initialize' function in response.
+--   * PLAYER_LOGIN - Call the 'Enable' method once the major UI elements
+--       have been loaded and initialized.
+-------------------------------------------------------------------------]]--
+
+local addonName, addon = ...
+
+-- Set global name of addon
+_G[addonName] = addon
+
+-- Extract version information from TOC file
+addon.version = GetAddOnMetadata(addonName, "Version")
+if addon.version == "@project-version" or addon.version == "wowi:version" then
+    addon.version = "SCM"
+end
+
+--[[-------------------------------------------------------------------------
+--  Debug support
+-------------------------------------------------------------------------]]--
+
+local EMERGENCY_DEBUG = false
+if EMERGENCY_DEBUG then
+    local private = {}
+    for k,v in pairs(addon) do
+        rawset(private, k, v)
+        rawset(addon, k, nil)
+    end
+
+    setmetatable(addon, {
+        __index = function(t, k)
+            local value = rawget(private, k)
+            if type(value) == "function" then
+                print("CALL", addonName .. "." .. tostring(k))
+            end
+            return value
+        end,
+        __newindex = function(t, k, v)
+            print(addonName, "NEWINDEX", k, v)
+            rawset(private, k, v)
+        end,
+    })
+end
+
+--[[-------------------------------------------------------------------------
+--  Print/Printf support
+-------------------------------------------------------------------------]]--
+
+local printHeader = "|cFF33FF99%s|r: "
+
+function addon:Printf(msg, ...)
+    msg = printHeader .. msg
+    local success, txt = pcall(string.format, msg, addonName, ...)
+    if success then
+        print(txt)
+    else
+        error(string.gsub(txt, "'%?'", string.format("'%s'", "Printf")), 3)
+    end
+end
+
+--[[-------------------------------------------------------------------------
+--  Event registration and dispatch
+-------------------------------------------------------------------------]]--
+
+addon.eventFrame = CreateFrame("Frame", addonName .. "EventFrame", UIParent)
+local eventMap = {}
+
+function addon:RegisterEvent(event, handler)
+    assert(eventMap[event] == nil, "Attempt to re-register event: " .. tostring(event))
+    eventMap[event] = handler and handler or event
+    addon.eventFrame:RegisterEvent(event)
+end
+
+function addon:UnregisterEvent(event)
+    assert(type(event) == "string", "Invalid argument to 'UnregisterEvent'")
+    eventMap[event] = nil
+    addon.eventFrame:UnregisterEvent(event)
+end
+
+addon.eventFrame:SetScript("OnEvent", function(frame, event, ...)
+    local handler = eventMap[event]
+    local handler_t = type(handler)
+    if handler_t == "function" then
+        handler(event, ...)
+    elseif handler_t == "string" and addon[handler] then
+        addon[handler](addon, event, ...)
+    end
+end)
+
+--[[-------------------------------------------------------------------------
+--  Message support
+-------------------------------------------------------------------------]]--
+
+local messageMap = {}
+
+function addon:RegisterMessage(name, handler)
+    assert(messageMap[name] == nil, "Attempt to re-register message: " .. tostring(name))
+    messageMap[name] = handler and handler or name
+end
+
+function addon:UnregisterMessage(name)
+    assert(type(event) == "string", "Invalid argument to 'UnregisterMessage'")
+    messageMap[name] = nil
+end
+
+function addon:FireMessage(name, ...)
+    assert(type(name) == "string", "Invalid argument to 'FireMessage'")
+    local handler = messageMap[name]
+    local handler_t = type(handler)
+    if handler_t == "function" then
+        handler(name, ...)
+    elseif handler_t == "string" and addon[handler] then
+        addon[handler](addon, event, ...)
+    end
+end
+
+--[[-------------------------------------------------------------------------
+--  Setup Initialize/Enable support
+-------------------------------------------------------------------------]]--
+
+addon:RegisterEvent("PLAYER_LOGIN", "Enable")
+addon:RegisterEvent("ADDON_LOADED", function(event, ...)
+    if ... == addonName then
+        addon:UnregisterEvent("ADDON_LOADED")
+        if type(addon["Initialize"]) == "function" then
+            addon["Initialize"](addon)
+        end
+
+        -- If this addon was loaded-on-demand, trigger 'Enable' as well
+        if IsLoggedIn() and type(addon["Enable"]) == "function" then
+            addon["Enable"](addon)
+        end
+    end
+end)
+
+--[[-------------------------------------------------------------------------
+--  Support for deferred execution (when in-combat)
+-------------------------------------------------------------------------]]--
+
+local deferframe = CreateFrame("Frame")
+deferframe.queue = {}
+
+local function runDeferred(thing)
+    local thing_t = type(thing)
+    if thing_t == "string" and addon[thing] then
+        addon[thing](addon)
+    elseif thing_t == "function" then
+        thing(addon)
+    end
+end
+
+-- This method will defer the execution of a method or function until the
+-- player has exited combat. If they are already out of combat, it will
+-- execute the function immediately.
+function addon:Defer(...)
+    for i = 1, select("#", ...) do
+        local thing = select(i, ...)
+        local thing_t = type(thing)
+        if thing_t == "string" or thing_t == "function" then
+            if InCombatLockdown() then
+                deferframe.queue[#deferframe.queue + 1] = select(i, ...)
+            else
+                runDeferred(thing)
+            end
+        else
+            error("Invalid object passed to 'Defer'")
+        end
+    end
+end
+
+deferframe:RegisterEvent("PLAYER_REGEN_ENABLED")
+deferframe:SetScript("OnEvent", function(self, event, ...)
+    for idx, thing in ipairs(deferframe.queue) do
+        runDeferred(thing)
+    end
+    table.wipe(deferframe.queue)
+end)
+
+--[[-------------------------------------------------------------------------
+--  Localization
+-------------------------------------------------------------------------]]--
+
+addon.L = addon.L or setmetatable({}, {
+    __index = function(t, k)
+        rawset(t, k, k)
+        return k
+    end,
+    __newindex = function(t, k, v)
+        if v == true then
+            rawset(t, k, k)
+        else
+            rawset(t, k, v)
+        end
+    end,
+})
+
+function addon:RegisterLocale(locale, tbl)
+    if locale == "enUS" or locale == GetLocale() then
+        for k,v in pairs(tbl) do
+            if v == true then
+                self.L[k] = k
+            elseif type(v) == "string" then
+                self.L[k] = v
+            else
+                self.L[k] = k
+            end
+        end
+    end
+end
+
+--[[-------------------------------------------------------------------------
+--  Addon 'About' Dialog for Interface Options
+--
+--  Some of this code was taken from/inspired by tekKonfigAboutPanel
+-------------------------------------------------------------------------]]--
+
+local about = CreateFrame("Frame", addonName .. "AboutPanel", InterfaceOptionsFramePanelContainer)
+about.name = addonName
+about:Hide()
+
+function about.OnShow(frame)
+    local fields = {"Version", "Author", "X-Category", "X-License", "X-Email", "X-Website", "X-Credits"}
+	local notes = GetAddOnMetadata(addonName, "Notes")
+
+    local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
+
+	title:SetPoint("TOPLEFT", 16, -16)
+	title:SetText(addonName)
+
+	local subtitle = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	subtitle:SetHeight(32)
+	subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
+	subtitle:SetPoint("RIGHT", about, -32, 0)
+	subtitle:SetNonSpaceWrap(true)
+	subtitle:SetJustifyH("LEFT")
+	subtitle:SetJustifyV("TOP")
+	subtitle:SetText(notes)
+
+	local anchor
+	for _,field in pairs(fields) do
+		local val = GetAddOnMetadata(addonName, field)
+		if val then
+			local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
+			title:SetWidth(75)
+			if not anchor then title:SetPoint("TOPLEFT", subtitle, "BOTTOMLEFT", -2, -8)
+			else title:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -6) end
+			title:SetJustifyH("RIGHT")
+			title:SetText(field:gsub("X%-", ""))
+
+			local detail = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+			detail:SetPoint("LEFT", title, "RIGHT", 4, 0)
+			detail:SetPoint("RIGHT", -16, 0)
+			detail:SetJustifyH("LEFT")
+			detail:SetText(val)
+
+			anchor = title
+		end
+	end
+
+    -- Clear the OnShow so it only happens once
+	frame:SetScript("OnShow", nil)
+end
+
+addon.optpanels = addon.optpanels or {}
+addon.optpanels.ABOUT = about
+
+about:SetScript("OnShow", about.OnShow)
+InterfaceOptions_AddCategory(about)
diff --git a/TomTom.lua b/TomTom.lua
index 177f6c0..2d7c8e6 100755
--- a/TomTom.lua
+++ b/TomTom.lua
@@ -10,32 +10,8 @@ local ldb = LibStub("LibDataBroker-1.1")
 local astrolabe = DongleStub("TTAstrolabe-1.0")
 local lmd = LibStub("LibMapData-1.0")

--- Create the addon object
-TomTom = {
-    events = {},
-    eventFrame = CreateFrame("Frame"),
-    RegisterEvent = function(self, event, method)
-        self.eventFrame:RegisterEvent(event)
-        self.events[event] = method or event
-    end,
-    UnregisterEvent = function(self, event)
-        self.eventFrame:UnregisterEvent(event)
-        self.events[event] = nil
-    end,
-    version = GetAddOnMetadata("TomTom", "Version")
-}
-
-if TomTom.version == "wowi:revision" then TomTom.version = "SVN" end
-if TomTom.version == "@project-version@" then TomTom.version = "SCM" end
-
-TomTom.eventFrame:SetScript("OnEvent", function(self, event, ...)
-    local method = TomTom.events[event]
-    if method and TomTom[method] then
-        TomTom[method](TomTom, event, ...)
-    end
-end)
-
-TomTom:RegisterEvent("ADDON_LOADED")
+local addonName, addon = ...
+local TomTom = addon

 -- Local definitions
 local GetCurrentCursorPosition
@@ -47,158 +23,155 @@ local RoundCoords

 local waypoints = {}

-function TomTom:ADDON_LOADED(event, addon)
-    if addon == "TomTom" then
-        self:UnregisterEvent("ADDON_LOADED")
-        self.defaults = {
-            profile = {
-                general = {
-                    confirmremoveall = true,
-                    announce = false,
-                    corpse_arrow = true,
-                },
-                block = {
-                    enable = true,
-                    accuracy = 2,
-                    bordercolor = {1, 0.8, 0, 0.8},
-                    bgcolor = {0, 0, 0, 0.4},
-                    lock = false,
-                    height = 30,
-                    width = 100,
-                    fontsize = 12,
-                    throttle = 0.2,
-                },
-                mapcoords = {
-                    playerenable = true,
-                    playeraccuracy = 2,
-                    cursorenable = true,
-                    cursoraccuracy = 2,
-                },
-                arrow = {
-                    enable = true,
-                    goodcolor = {0, 1, 0},
-                    badcolor = {1, 0, 0},
-                    middlecolor = {1, 1, 0},
-                    arrival = 15,
-                    lock = false,
-                    noclick = false,
-                    showtta = true,
-                    autoqueue = true,
-                    menu = true,
-                    scale = 1.0,
-                    alpha = 1.0,
-                    title_width = 0,
-                    title_height = 0,
-                    title_scale = 1,
-                    title_alpha = 1,
-                    setclosest = true,
-                    enablePing = false,
-                },
-                minimap = {
-                    enable = true,
-                    otherzone = true,
-                    tooltip = true,
-                    menu = true,
-                },
-                worldmap = {
-                    enable = true,
-                    tooltip = true,
-                    otherzone = true,
-                    clickcreate = true,
-                    menu = true,
-                    create_modifier = "C",
-                },
-                comm = {
-                    enable = true,
-                    prompt = false,
-                },
-                persistence = {
-                    cleardistance = 10,
-                    savewaypoints = true,
-                },
-                feeds = {
-                    coords = false,
-                    coords_throttle = 0.3,
-                    coords_accuracy = 2,
-                    arrow = false,
-                    arrow_throttle = 0.1,
-                },
-                poi = {
-                    enable = true,
-                    modifier = "C",
-                    setClosest = false,
-                    arrival = 0,
-                },
+function TomTom:Initialize(event, addon)
+    self.defaults = {
+        profile = {
+            general = {
+                confirmremoveall = true,
+                announce = false,
+                corpse_arrow = true,
             },
-        }
-
-        self.waydefaults = {
-            global = {
-                converted = {
-                    ["*"] = {},
-                },
+            block = {
+                enable = true,
+                accuracy = 2,
+                bordercolor = {1, 0.8, 0, 0.8},
+                bgcolor = {0, 0, 0, 0.4},
+                lock = false,
+                height = 30,
+                width = 100,
+                fontsize = 12,
+                throttle = 0.2,
+            },
+            mapcoords = {
+                playerenable = true,
+                playeraccuracy = 2,
+                cursorenable = true,
+                cursoraccuracy = 2,
+            },
+            arrow = {
+                enable = true,
+                goodcolor = {0, 1, 0},
+                badcolor = {1, 0, 0},
+                middlecolor = {1, 1, 0},
+                arrival = 15,
+                lock = false,
+                noclick = false,
+                showtta = true,
+                autoqueue = true,
+                menu = true,
+                scale = 1.0,
+                alpha = 1.0,
+                title_width = 0,
+                title_height = 0,
+                title_scale = 1,
+                title_alpha = 1,
+                setclosest = true,
+                enablePing = false,
+            },
+            minimap = {
+                enable = true,
+                otherzone = true,
+                tooltip = true,
+                menu = true,
+            },
+            worldmap = {
+                enable = true,
+                tooltip = true,
+                otherzone = true,
+                clickcreate = true,
+                menu = true,
+                create_modifier = "C",
+            },
+            comm = {
+                enable = true,
+                prompt = false,
+            },
+            persistence = {
+                cleardistance = 10,
+                savewaypoints = true,
+            },
+            feeds = {
+                coords = false,
+                coords_throttle = 0.3,
+                coords_accuracy = 2,
+                arrow = false,
+                arrow_throttle = 0.1,
             },
-            profile = {
+            poi = {
+                enable = true,
+                modifier = "C",
+                setClosest = false,
+                arrival = 0,
+            },
+        },
+    }
+
+    self.waydefaults = {
+        global = {
+            converted = {
                 ["*"] = {},
             },
-        }
+        },
+        profile = {
+            ["*"] = {},
+        },
+    }

-        self.db = LibStub("AceDB-3.0"):New("TomTomDB", self.defaults, "Default")
-        self.waydb = LibStub("AceDB-3.0"):New("TomTomWaypointsMF", self.waydefaults)
+    self.db = LibStub("AceDB-3.0"):New("TomTomDB", self.defaults, "Default")
+    self.waydb = LibStub("AceDB-3.0"):New("TomTomWaypointsMF", self.waydefaults)

-        self.db.RegisterCallback(self, "OnProfileChanged", "ReloadOptions")
-        self.db.RegisterCallback(self, "OnProfileCopied", "ReloadOptions")
-        self.db.RegisterCallback(self, "OnProfileReset", "ReloadOptions")
-        self.waydb.RegisterCallback(self, "OnProfileChanged", "ReloadWaypoints")
-        self.waydb.RegisterCallback(self, "OnProfileCopied", "ReloadWaypoints")
-        self.waydb.RegisterCallback(self, "OnProfileReset", "ReloadWaypoints")
+    self.db.RegisterCallback(self, "OnProfileChanged", "ReloadOptions")
+    self.db.RegisterCallback(self, "OnProfileCopied", "ReloadOptions")
+    self.db.RegisterCallback(self, "OnProfileReset", "ReloadOptions")
+    self.waydb.RegisterCallback(self, "OnProfileChanged", "ReloadWaypoints")
+    self.waydb.RegisterCallback(self, "OnProfileCopied", "ReloadWaypoints")
+    self.waydb.RegisterCallback(self, "OnProfileReset", "ReloadWaypoints")

-        self.tooltip = CreateFrame("GameTooltip", "TomTomTooltip", nil, "GameTooltipTemplate")
-        self.tooltip:SetFrameStrata("DIALOG")
+    self.tooltip = CreateFrame("GameTooltip", "TomTomTooltip", nil, "GameTooltipTemplate")
+    self.tooltip:SetFrameStrata("DIALOG")

-        self.dropdown = CreateFrame("Frame", "TomTomDropdown", nil, "UIDropDownMenuTemplate")
+    self.dropdown = CreateFrame("Frame", "TomTomDropdown", nil, "UIDropDownMenuTemplate")

-        -- Both the waypoints and waypointprofile tables are going to contain subtables for each
-        -- of the mapids that might exist. Under these will be a hash of key/waypoint pairs consisting
-        -- of the waypoints for the given map file.
-        self.waypoints = waypoints
-        self.waypointprofile = self.waydb.profile
+    -- Both the waypoints and waypointprofile tables are going to contain subtables for each
+    -- of the mapids that might exist. Under these will be a hash of key/waypoint pairs consisting
+    -- of the waypoints for the given map file.
+    self.waypoints = waypoints
+    self.waypointprofile = self.waydb.profile

-        self:RegisterEvent("PLAYER_LEAVING_WORLD")
-        self:RegisterEvent("CHAT_MSG_ADDON")
+    self:RegisterEvent("PLAYER_LEAVING_WORLD")
+    self:RegisterEvent("CHAT_MSG_ADDON")

-        self:ReloadOptions()
-        self:ReloadWaypoints()
+    self:ReloadOptions()
+    self:ReloadWaypoints()

-        if self.db.profile.feeds.coords then
-            -- Create a data feed for coordinates
-            local feed_coords = ldb:NewDataObject("TomTom_Coords", {
-                type = "data source",
-                icon = "Interface\\Icons\\INV_Misc_Map_01",
-                text = "",
-            })
+    if self.db.profile.feeds.coords then
+        -- Create a data feed for coordinates
+        local feed_coords = ldb:NewDataObject("TomTom_Coords", {
+            type = "data source",
+            icon = "Interface\\Icons\\INV_Misc_Map_01",
+            text = "",
+        })

-            local coordFeedFrame = CreateFrame("Frame")
-            local throttle, counter = self.db.profile.feeds.coords_throttle, 0
-            function TomTom:_privateupdatecoordthrottle(x)
-                throttle = x
-            end
+        local coordFeedFrame = CreateFrame("Frame")
+        local throttle, counter = self.db.profile.feeds.coords_throttle, 0
+        function TomTom:_privateupdatecoordthrottle(x)
+            throttle = x
+        end

-            coordFeedFrame:SetScript("OnUpdate", function(self, elapsed)
-                counter = counter + elapsed
-                if counter < throttle then
-                    return
-                end
+        coordFeedFrame:SetScript("OnUpdate", function(self, elapsed)
+            counter = counter + elapsed
+            if counter < throttle then
+                return
+            end

-                counter = 0
-                local m, f, x, y = TomTom:GetCurrentPlayerPosition()
+            counter = 0
+            local m, f, x, y = TomTom:GetCurrentPlayerPosition()

-                if x and y then
-                    local opt = TomTom.db.profile.feeds
-                    feed_coords.text = string.format("%s", RoundCoords(x, y, opt.coords_accuracy))
-                end
-            end)
-        end
+            if x and y then
+                local opt = TomTom.db.profile.feeds
+                feed_coords.text = string.format("%s", RoundCoords(x, y, opt.coords_accuracy))
+            end
+        end)
     end
 end

diff --git a/TomTom.toc b/TomTom.toc
index b1f49f7..137bdbf 100755
--- a/TomTom.toc
+++ b/TomTom.toc
@@ -23,6 +23,8 @@ libs\AceDBOptions-3.0\AceDBOptions-3.0.xml
 libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
 libs\LibMapData-1.0\library.lua

+AddonCore.lua
+
 Localization.enUS.lua
 Localization.deDE.lua
 Localization.zhCN.lua
diff --git a/TomTom_Config.lua b/TomTom_Config.lua
index 892005e..8dbabc7 100644
--- a/TomTom_Config.lua
+++ b/TomTom_Config.lua
@@ -720,19 +720,6 @@ local options
 local function createBlizzOptions()
 	options = createconfig()

-	config:RegisterOptionsTable("TomTom-Bliz", {
-		name = L["TomTom"],
-		type = "group",
-		args = {
-			help = {
-				type = "description",
-				name = "TomTom is a simple navigation assistant",
-			},
-		},
-	})
-	dialog:SetDefaultSize("TomTom-Bliz", 600, 400)
-	dialog:AddToBlizOptions("TomTom-Bliz", "TomTom")
-
 	-- General Options
 	config:RegisterOptionsTable("TomTom-General", options.args.general)
 	local blizzPanel = dialog:AddToBlizOptions("TomTom-General", options.args.general.name, "TomTom")