WoWInterface SVN RaidWatch2

[/] [trunk/] [RaidWatch_Plugins/] [Controller.lua] - Rev 22

Compare with Previous | Blame | View Log

----------------------------------
-- Create plugin
local RW = LibStub("AceAddon-3.0"):GetAddon("Raid Watch")
local plugin = RW:Plugin("Controller")
if not plugin then return end

----------------------------------
-- Locals 

local L = LibStub("AceLocale-3.0"):GetLocale("RW2-Plugin-Controller")
local LB = LibStub("AceLocale-3.0"):GetLocale("RW2-Plugin-Base")
local LBB = LibStub("AceLocale-3.0"):GetLocale("RW2-Base")
local LSM = LibStub("LibSharedMedia-3.0")
local AGU = LibStub("AceGUI-3.0")
local LGT = LibStub("LibGroupTalents-1.0")
local UIF

local db
local Utils = RW.Utils

local Window, BossWindow, ConfigWindow, BossConfigButton, Anchor
local dragStart, dragStop, BossFrameUpdate
local Party
local CurrentRole = "Unknown Spec"
local CurrentSpec = "Unknown Spec"
local pGUID = UnitGUID("player")

local defaults = {
        profile = {
                PluginEnabled = true,
                x = 0, 
                y = 0,
                Width = 300,
                
                ShowOnEngage = true,
                ShowOnLoad = true,
                ShowOnZone = true,
                ShowOnJoin = true,
                
                PulloutSide = "TOP",
                ContentSide = "BOTTOM",
                
                Font = "accid",
                FontSize = 16,
                FontFlags = "NONE",
                FontColor = {1, 1, 1, 1},
        }
}

----------------------------------
-- Init

function plugin:OnRegister()
        self.db = RW.db:RegisterNamespace(self:GetName(), defaults)
        db = self.db.profile
        
        self.db.RegisterCallback(self, "OnProfileChanged", "Reset")
        self.db.RegisterCallback(self, "OnProfileCopied", "Reset")
        self.db.RegisterCallback(self, "OnProfileReset", "Reset")
end

function plugin:PluginEnable()
        if not db.PluginEnabled then
                self:Disable()
                return
        end
        
        UIF = LibStub("LibGUIFactory-1.0"):GetFactory("RW")
        UIF:SetValuesChangedCallback(function()
                if ConfigWindow and ConfigWindow.frame:IsShown() then
                        ConfigWindow:ReleaseChildren()
                        ConfigWindow:AddChild(plugin:GetGUI())
                end
        end)
        
        LGT.RegisterCallback(self, "LibGroupTalents_RoleChange", "RoleChanged")
        LGT.RegisterCallback(self, "LibGroupTalents_Update", "SpecChanged")
        CurrentRole = LGT:GetUnitRole("player") or ""
        Party = RW.Party
        
        self:RegisterCallback("BossEngaged")
        self:RegisterCallback("BossDisengaged")

        self:RegisterCallback("ConfigMode")
        self:RegisterCallback("EnteringEnabledZone")
        self:RegisterCallback("LeavingEnabledZone")
        self:RegisterCallback("ToggleController")
        
        if db.ShowOnLoad then
                self:CreateWindow()
                Utils.FadeIn(Window)
        end
end

function plugin:PluginDisable()
end

function plugin:Reset()
        db = self.db.profile
        self:ApplySettings()
end

function UpdateTitle(...)
        local str = ""
        if BossWindow and BossWindow.currentBoss then
                str = RW.LBB[BossWindow.currentBoss:GetName()] or BossWindow.currentBoss:GetName()
        else
                str = date("%H:%M:%S")
        end
        local partyType = Party:GetPartyType()
        if partyType == "raid" or partyType == "party" then
                str = ("%s - %d %s"):format(str, Utils:InstanceSize(), (Utils:IsHeroic() and "Heroic" or "Normal"))
        end
        Window:SetTitle(str)
end

function plugin:RoleChanged(event, guid, unit, newRole, oldRole)
        if guid == pGUID then
                CurrentRole = newRole
        end
end

function plugin:SpecChanged(event, guid, unit, spec, tree1, tree2, tree3, oldSpec)
        if guid == pGUID then
                CurrentSpec = spec
        end
end

function plugin:CreateWindow()
        local f = Utils:CreateAnchor(name, UIParent, "Controller")
        f.name = name
        f:SetScript("OnDragStart", dragStart)
        f:SetScript("OnDragStop", dragStop)
        f:SetPoint("CENTER", db.x, db.y)
        f:SetWidth(db.Width)    
        Anchor = f
        
        if not Window then      
                Window = Utils:CreateWindow("Controller", true, dragStart, dragStop)
                Window:HideContent()
                Window:SetPoint("BOTTOMLEFT", f, "TOPLEFT")
                Window:SetPoint("BOTTOMRIGHT", f, "TOPRIGHT")
                Window:ShowLeftIcon([[Interface\Icons\Ability_Mage_HotStreak]])
                Window:SetAlpha(0)
                Window:SetTitle("")
                Utils:RegisterOnUpdate(Window, UpdateTitle, 1)
                
                local b = Window:AddTitleButton("Close", nil, true)     
                b:AddClickHandler(function() 
                        Utils.FadeOut(Window)
                end)
                Utils:AddTooltip(b, LB.CLOSE)
                
                b = Window:AddPulloutButton("RangeCheck")       
                b:AddClickHandler(function() 
                        RW.Callbacks:Fire("RangeCheckShow", true, nil, true) 
                end)
                Utils:AddTooltip(b, "Show Range Check")
                
                b = Window:AddPulloutButton("DKP")      
                b:AddClickHandler(function() 
                        RW.Callbacks:Fire("DKPShow")                    
                end)
                Utils:AddTooltip(b, "Show DKP")
                
                b = Window:AddPulloutButton("Versioncheck")
                b:AddClickHandler(function()
                        RW.Callbacks:Fire("VersionsShow")                       
                end)
                Utils:AddTooltip(b, "Show Versions")
                
                b = Window:AddPulloutButton("Config")
                b:AddClickHandler( function()
                        plugin:OpenConfigWindow()
                end)
                Utils:AddTooltip(b, LB.CONFIGURE)
        end
        
        self:ApplySettings()
end

function plugin:CreateBossWindow()
        BossWindow = CreateFrame("Frame", nil, Window.content)
        BossWindow:SetPoint("BOTTOMLEFT", Window.content)
        BossWindow:SetPoint("BOTTOMRIGHT", Window.content)
        BossWindow:EnableMouse(true)
        BossWindow:SetScript("OnEnter", function() Utils.FadeIn(BossConfigButton) end)
        BossWindow:SetScript("OnLeave", function() Utils.FadeOut(BossConfigButton) end)
        
        local t = BossWindow:CreateFontString(nil, nil, "GameFontNormal")
        t:SetJustifyH("LEFT")
        t:SetPoint("TOPLEFT", 5, -5)
        BossWindow.timestr = t
        
        t = BossWindow:CreateFontString(nil, nil, "GameFontNormal")
        t:SetJustifyH("LEFT")
        t:SetPoint("TOPLEFT", BossWindow.timestr, "BOTTOMLEFT")
        BossWindow.partystatus = t
        
        local b = Window:AddTitleButton("Config")
        b:AddClickHandler(function(self, button, isDown)
                if not IsAddOnLoaded("RaidWatch_Options") and not RW:GetPlugin("Options") then
                        if not RWL:LoadAddOn("RaidWatch_Options") then
                                return
                        end
                end             
                local options = RW:GetPlugin("Options")
                if options then
                        local frame = UIF:Frame(RW.LBB[BossWindow.currentBoss:GetName()] or BossWindow.currentBoss:GetName())
                        frame:SetLayout("Fill")
                        frame:AddChild(options.SelectBoss(BossWindow.currentBoss, frame))
                        frame:Show()
                else
                        self:Meg("Options is enabled, options for "..(RW.LBB[BossWindow.currentBoss:GetName()] or BossWindow.currentBoss:GetName()).." cannot be shown")
                end
        end)
        b:SetPoint("RIGHT", BossWindow, -5, 0)
        b:SetParent(BossWindow)
        b:Hide()
        BossConfigButton = b
        self:ApplySettings()
end

function plugin:OpenConfigWindow(toggle)
        if not ConfigWindow then
                ConfigWindow = UIF:Frame(L.NAME)        
                ConfigWindow:SetHeight(800)
                ConfigWindow:SetCallback("OnClose", function()
                        ConfigWindow:ReleaseChildren()
                        ConfigWindow.frame:Hide()
                end)
                ConfigWindow:SetLayout("Fill")  
                ConfigWindow:Show()
                ConfigWindow:AddChildren(plugin:GetGUI())
                return
        end
        
        if toggle then
                if ConfigWindow.frame:IsShown() then
                        ConfigWindow:Hide()
                        ConfigWindow:Show()
                        ConfigWindow:AddChildren(plugin:GetGUI())
                end             
        else
                if ConfigWindow.frame:IsShown() then
                        ConfigWindow:Hide()
                else            
                        ConfigWindow:Show()
                        ConfigWindow:AddChildren(plugin:GetGUI())               
                end
        end     
end

function plugin:ApplySettings()
        self = plugin
        if Window then
                Anchor:SetWidth(db.Width)       
                Anchor:ClearAllPoints()
                Anchor:SetPoint("CENTER", db.x, db.y)
                Window:SetPulloutSide(db.PulloutSide)
                Window:SetContentSide(db.ContentSide)
        end
        
        if BossWindow then
                BossWindow.timestr:SetFont(LSM:Fetch("font", db.Font), db.FontSize, db.FontFlags)
                BossWindow.timestr:SetTextColor(unpack(db.FontColor))
                BossWindow.partystatus:SetFont(LSM:Fetch("font", db.Font), db.FontSize, db.FontFlags)
                BossWindow.partystatus:SetTextColor(unpack(db.FontColor))
                BossWindow.timestr:SetText("s")
                BossWindow:SetHeight(BossWindow.timestr:GetHeight() * 2 + 5 * 2)
        end
end

-- API ---------------------------------------
----------------------------------------------
function plugin:ToggleController()
        if not Window then self:CreateWindow() end
        
        if Window:IsShown() then Utils.FadeOut(Window)
        else Utils.FadeIn(Window) end
end

function plugin:BossEngaged(event, boss)
        if db.ShowOnEngage then
                if not Window then self:CreateWindow() end
                Window:Show()
        end
        
        if Window then          
                if not BossWindow then self:CreateBossWindow() end
                BossWindow.currentBoss = boss
                BossWindow:Show()
                BossWindow.start = 0
                Utils:RegisterOnUpdate(BossWindow, BossFrameUpdate, 0.5)
                Utils:AddTooltip(BossConfigButton, RW.LBB[BossWindow.currentBoss:GetName()] or BossWindow.currentBoss:GetName(),  "Open Config")
                Window:ShowLeftIcon(boss.BossIcon)
                Window:SetContentHeight(BossWindow:GetHeight())
        end
end

function plugin:BossDisengaged(event, boss, wipe)
        if Window then  
                Window:ShowLeftIcon([[Interface\Icons\Ability_Mage_HotStreak]])
                Window:HideContent()
                Utils:UnregisterOnUpdate(BossWindow, BossFrameUpdate)
                BossWindow:Hide()
                BossWindow.currentBoss = nil
                
                if not db.ShowOnZone and not db.ShowOnLoad then
                        Utils.FadeOut(Window)
                end
        end
end

function plugin:EnteringEnabledZone(event)
        if not db.ShowOnZone then return end
        if not Window then self:CreateWindow() end      
        Window:Show()
end

function plugin:LeavingEnabledZone(event)
        if db.ShowOnLoad then return end
        if Window then Utils.FadeOut(Window) end
end

function plugin:ConfigMode(event, show)
        if not Window then self:CreateWindow() end
        if not BossWindow then self:CreateBossWindow() end
        if show then
                Anchor:Show()
                Utils.FadeIn(Window)
                Utils.FadeIn(BossWindow)
                BossWindow.timestr:SetText("Elapsed time here")
                Window:SetContentHeight(BossWindow:GetHeight())
        else
                Anchor:Hide()
                if not BossWindow.currentBoss then
                        Utils.FadeOut(BossWindow)
                        Window:HideContent()
                end
        end
end

-- UI ----------------------------------------
----------------------------------------------
do
        function plugin:GetOptions()
                return LB.PLUGINS, L.NAME, self.GetGUI, [[Interface\Icons\Ability_Mage_HotStreak]]
        end
        
        local TabSelected
        local LastSelectedTab
        
        function plugin:GetGUI()
                self = plugin
                
                local scroll = AGU:Create("ScrollFrame")
                scroll:SetLayout("Flow")
                
                local label = UIF:MainTitleLabel(L.NAME)
                scroll:AddChild(label)  
                
                -- Information
                local infogroup = UIF:InlineGroup1()
                local label = UIF:Text1(L.DESC)
                label:SetImage([[Interface\Icons\Ability_Mage_HotStreak]])
                infogroup:AddChild(label)
                scroll:AddChild(infogroup)
                
                local group = UIF:InlineGroup1("Visible")
                scroll:AddChild(group)
                
                local checkbox
                group:AddChild(UIF:CheckBox(L.ALWAYS_SHOW, db, "ShowOnLoad", plugin.ApplySettings, L.ALWAYS_SHOW_DESC, 0.5, true))
                group:AddChild(UIF:CheckBox(L.SHOW_BOSSFIGHT, db, "ShowOnEngage", nil, L.SHOW_BOSSFIGHT_DESC, 0.5, true))
                group:AddChild(UIF:CheckBox(L.SHOW_ZONE, db, "ShowOnZone", nil, L.SHOW_ZONE_DESC, 0.5, true))
                group:AddChild(UIF:CheckBox(L.SHOW_JOIN_PARTY, db, "ShowOnJoin", nil, L.SHOW_JOIN_PARTY_DESC, 0.5, true))
                
                local tgroup = UIF:TabGroup1()
                scroll:AddChild(tgroup)
                tgroup:SetTabs(
                {
                        {text = LB.POSITION .." & " .. LB.SIZE, value = "Position"},
                        {text = LB.APPEARANCE, value = "Appearance"},
                        {text = LB.LAYOUT, value = "Layout"},
                })
                tgroup:SetCallback("OnGroupSelected", TabSelected)
                tgroup:SelectTab(LastSelectedTab or "Appearance")                               
                
                
                button = UIF:Button(LB.RESET, function() 
                        plugin.db:ResetProfile() 
                end)
                button:SetUserData("confirm", true)
                button:SetUserData("TriggerGlobalUpdate", true)
                scroll:AddChild(button)
                
                scroll:FixScroll()
                
                return scroll
        end
        
        TabSelected = function(self, event, tab)
                self:ReleaseChildren()
                LastSelectedTab = tab
                
                if tab == "Position" then
                        slider = UIF:Slider("X", db, "x", 
                                -floor(GetScreenWidth() * UIParent:GetEffectiveScale()), 
                                floor(GetScreenWidth() * UIParent:GetEffectiveScale()),
                                1, plugin.ApplySettings)
                        self:AddChild(slider)
                        
                        slider = UIF:Slider("Y", db, "y", 
                                -floor(GetScreenHeight() * UIParent:GetEffectiveScale()), 
                                floor(GetScreenHeight() * UIParent:GetEffectiveScale()),
                                1, plugin.ApplySettings)
                        self:AddChild(slider)
                        self:AddChild(UIF:Slider("Width", db, "Width", 10, 500, 1, plugin.ApplySettings))
                        
                elseif tab == "Appearance" then
                        self:AddChild(UIF:LSMDropdown("font", LB.FONT, db, "Font", plugin.ApplySettings))
                        self:AddChild(UIF:Spacer(20))
                        self:AddChild(UIF:Slider(LB.FONT_SIZE, db, "FontSize", 1, 50, 1, plugin.ApplySettings))
                        self:AddChild(UIF:NewLine())
                        self:AddChild(UIF:Dropdown(LB.FONT_OUTLINE, db, "FontFlags", plugin.ApplySettings, Utils.Constants.FontFlagList))
                        self:AddChild(UIF:Spacer(20))
                        self:AddChild(UIF:ColorSelect(LB.FONT_COLOR, db, "FontColor", plugin.ApplySettings, true))
                        
                elseif tab == "Layout" then
                        self:AddChild(UIF:Dropdown("Popup Position", db, "PulloutSide", plugin.ApplySettings, Utils.Constants.UpDownList))
                        self:AddChild(UIF:Dropdown("Content Position", db, "ContentSide", plugin.ApplySettings, Utils.Constants.UpDownList))
                end
                
                self.parent:DoLayout()
        end
end
-- Moving ------------------------------------
----------------------------------------------
dragStart = function(self)
        Anchor:StartMoving()
end

dragStop = function(self)
        Anchor:StopMovingOrSizing()
        local scale = Anchor:GetEffectiveScale() / UIParent:GetEffectiveScale()
        
        local x, y = Anchor:GetCenter()
        x, y = x * scale, y * scale
        
        x = x - GetScreenWidth()/2
        y = y - GetScreenHeight()/2
        x = x * scale
        y = y * scale   
        
        db.x, db.y = x, y
        
        RW.Callbacks:Fire("RefreshOptions")
        if ConfigWindow then
                plugin:OpenConfigWindow(true)
        end
end

BossFrameUpdate = function(self, elapsed)
        self.timestr:SetFormattedText(("%s: %s"):format(LB.DURATION, Utils:TimeToStringShort(self.start)))
        self.partystatus:SetText(("Status: %d / %d alive"):format(Party:GetNumAlive(), Party:GetPartySize()))
        
        self.start = self.start + elapsed
end

Compare with Previous | Blame