Mercurial > wow > reaction
view classes/ReAction_ActionDisplay.lua @ 9:650f75d08952
Version 0.32
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 20 Mar 2007 21:35:57 +0000 |
parents | c05fd3e18b4f |
children | f3a7bfebc283 |
line wrap: on
line source
-- The ReAction.ActionDisplay mixin defines 'regular' action button display functionality -- and is an implementation of the ReAction.IDisplay and ReAction.ActionType.IDisplay interfaces. -- -- This Mixin assumes that it has been mixed in with a ReAction-derived class which implements -- the ReAction.IActionType and ReAction.IColorScheme interfaces. -- -- This mixin uses properties of self.config to define display elements: -- -- self.config = { -- keyBindLoc = "POSITION", -- keybind anchor location -- stackCountLoc = "POSITION", -- stack count anchor location -- showKeyBind = true/false, -- show keybind labels -- showStackCount = true/false, -- show stack count labels -- showMacroText = true/false, -- show macro name labels -- showGrid = true/false, -- always show empty buttons -- hideCooldown = true/false, -- hide the cooldown timer -- hideGlobalCooldown = true/false, -- hide cooldown timers if duration < 1.5 seconds (global) -- opacity = { -- default = 0-100 [100], -- button opacity when the action is usable (default opacity) -- notUsable = 0-100 [100], -- button opacity when the action is not usable -- oom = 0-100 [notUsable], -- button opacity when the action is not usable due to OOM -- ooRange = 0-100 [notUsable], -- button opacity when the action is not usable due to out of range -- empty = 0-100 [0], -- button opacity when the action slot is empty -- }, -- hideEmptySlots = true/false, -- show/hide empty buttons rather than change opacity to 0 -- } -- local AceOO = AceLibrary("AceOO-2.0") ReAction.ActionDisplay = AceOO.Mixin { -- ReAction.IDisplay interface "SetupDisplay", "UpdateDisplay", "TempShow", "GetActionFrame", "GetBaseButtonSize", "DisplayID", "DisplayHotkey", -- ReAction.ActionType.IDisplay interface "DisplayUsable", "DisplayEquipped", "DisplayAutoRepeat", "DisplayInUse", "DisplayIcon", "DisplayName", "DisplayCount", "DisplayCooldown", -- Event handlers "PostClick", "OnDragStart", "OnReceiveDrag", "OnEnter", "OnLeave", "OnUpdate", -- internal functions "ApplyLayout", "ApplyStyle", "StartFlash", "StopFlash", "IsFlashing", "DisplayVisibility", } local RAAD = ReAction.ActionDisplay -- private constants local _G = getfenv(0) local equippedActionBorderColor = { r=0.00, g=1.00, b=0.00, a=0.35 } -- transparent green local actionIDColor = { r=1.00, g=0.82, b=0.00, a=1.00 } -- gold -- private functions -- extract and return color fields from a table, to be fed into SetVertexColor()/SetTextColor() local function tcolor(c) return c.r, c.g, c.b, c.a end ----------------------------------- -- Interface Implementation Methods ----------------------------------- function RAAD:SetupDisplay( name ) -- create the button widget local b = CreateFrame("CheckButton", name, nil, "SecureActionButtonTemplate, ActionButtonTemplate") -- store references to the various sub-frames of ActionButtonTemplate so we don't have to look it up all the time self.frames = { button = b, hotkey = _G[name.."HotKey"], count = _G[name.."Count"], cooldown = _G[name.."Cooldown"], macro = _G[name.."Name"], icon = _G[name.."Icon"], border = _G[name.."Border"], flash = _G[name.."Flash"], normalTexture = _G[name.."NormalTexture"], actionID = nil, -- defer creating actionID font string until it's actually requested } -- ??? odd: why do we have to increment the cooldown frame level to get it to show? -- (otherwise it's behind the icon). The default UI doesn't have to (or at least I can't -- find where it does) but for some reason we have to here. self.frames.cooldown:SetFrameLevel(self.frames.cooldown:GetFrameLevel() + 1) b:EnableMouse() b:RegisterForDrag("LeftButton", "RightButton") b:RegisterForClicks("AnyUp") b:SetScript("PostClick", function(arg1) self:PostClick(arg1) end) b:SetScript("OnDragStart", function(arg1) self:OnDragStart(arg1) end) b:SetScript("OnReceiveDrag", function() self:OnReceiveDrag() end) b:SetScript("OnEnter", function() self:OnEnter() end) b:SetScript("OnLeave", function() self:OnLeave() end) -- defer setting OnUpdate until actions are actually attached self.tmpShow_ = 0 end function RAAD:UpdateDisplay() self:ApplyLayout() self:ApplyStyle() self:DisplayVisibility() -- refresh the action ID display if ReAction.showIDs_ then self:DisplayID(true) end end function RAAD:TempShow( visible ) visible = visible and true or false -- force data integrity self.showTmp_ = max(0, (self.showTmp_ or 0) + (visible and 1 or -1)) self:DisplayVisibility() end function RAAD:GetActionFrame() return self.frames.button end function RAAD:GetBaseButtonSize() return 36 end function RAAD:DisplayID( show ) local f = self.frames.actionID if show then if not f then -- create the actionID label f = self.frames.button:CreateFontString(nil,"ARTWORK","NumberFontNormalSmall") f:SetPoint("BOTTOMLEFT") f:SetTextColor( tcolor(actionIDColor) ) self.frames.actionID = f end f:SetText(tostring(self:GetID())) f:Show() elseif f then f:Hide() end end function RAAD:DisplayHotkey(txt) self.frames.hotkey:SetText(string.upper(txt or "")) self:UpdateUsable() end function RAAD:DisplayUsable( isUsable, notEnoughMana, outOfRange ) local f = self.frames f.icon:SetVertexColor( self:GetIconColor(isUsable, notEnoughMana, outOfRange) ) f.button:GetNormalTexture():SetVertexColor( self:GetBorderColor(isUsable, notEnoughMana, outOfRange) ) f.hotkey:SetTextColor( self:GetHotkeyColor(isUsable, notEnoughMana, outOfRange, f.hotkey:GetText()) ) local o if isUsable then o = self.config.opacity and self.config.opacity.usable or 1 else o = self.config.opacity and self.config.opacity.notUsable or 1 if notEnoughMana then o = self.config.opacity and self.config.opacity.oom or o elseif outOfRange then o = self.config.opacity and self.config.opacity.ooRange or o end end self.currentOpacity = o -- store for use in DisplayVisibility self:DisplayVisibility() end function RAAD:DisplayEquipped( equipped ) local b = self.frames.border if equipped then b:Show() else b:Hide() end end function RAAD:DisplayAutoRepeat( r ) if r then self:StartFlash() else self:StopFlash() end end function RAAD:DisplayInUse( inUse ) self.frames.button:SetChecked( inUse and 1 or 0 ) end function RAAD:DisplayIcon( texture ) local f = self.frames.button local icon = self.frames.icon if texture then icon:SetTexture(texture) icon:Show() self.rangeTimer = -1 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") if f:GetScript("OnUpdate") == nil then f:SetScript("OnUpdate", function(frame, elapsed) self:OnUpdate(elapsed) end) end else icon:Hide() self.rangeTimer = nil f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot") f:SetScript("OnUpdate",nil) end self:DisplayVisibility() end function RAAD:DisplayCooldown( start, duration, enable ) enable = (enable > 0 ) and not self.config.hideCooldown and (not self.config.hideGlobalCooldown or duration > 1.5) and 1 or 0 CooldownFrame_SetTimer(self.frames.cooldown, start, duration, enable) end function RAAD:DisplayName( name ) self.frames.macro:SetText(name and tostring(name) or "") end function RAAD:DisplayCount( count ) self.frames.count:SetText(count and tostring(count) or "") end ---------------------- -- Event Handlers ---------------------- function RAAD:PostClick() self:UpdateInUse() end function RAAD:OnDragStart() if LOCK_ACTIONBAR ~= "1" or IsShiftKeyDown() then self:PickupAction() end end function RAAD:OnReceiveDrag() self:PlaceAction() end function RAAD:OnEnter() self:SetTooltip() -- from ReAction base class self.tooltipTime = TOOLTIP_UPDATE_TIME end function RAAD:OnLeave() self:ClearTooltip() -- from ReAction base class self.tooltipTime = nil end function RAAD:OnUpdate(elapsed) -- handle flashing if self:IsFlashing() then self.flashtime = self.flashtime - elapsed if self.flashtime <= 0 then local overtime = -self.flashtime if overtime >= ATTACK_BUTTON_FLASH_TIME then overtime = 0 end self.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime local f = self.frames.flash if f then if f:IsVisible() then f:Hide() else f:Show() end end end end -- Handle range indicator if self.rangeTimer then self.rangeTimer = self.rangeTimer - elapsed if self.rangeTimer <= 0 then self:UpdateUsable() self.rangeTimer = TOOLTIP_UPDATE_TIME end end -- handle tooltip update if self.tooltipTime then self.tooltipTime = self.tooltipTime - elapsed if self.tooltipTime <= 0 then if GameTooltip:IsOwned(self.frames.button) then self:UpdateTooltip() self.tooltipTime = TOOLTIP_UPDATE_TIME else self.tooltipTime = nil end end end end ---------------------- -- Internal methods ---------------------- local function placeLabel( label, anchor ) local top = string.match(anchor,"TOP") local bottom = string.match(anchor, "BOTTOM") label:ClearAllPoints() label:SetWidth(40) label:SetPoint(top or bottom or "CENTER",0,top and 2 or bottom and -2 or 0) local j if string.match(anchor,"LEFT") then j = "LEFT" elseif string.match(anchor,"RIGHT") then j = "RIGHT" else j = "CENTER" end label:SetJustifyH(j) end function RAAD:ApplyLayout() local f = self.frames if self.config.keyBindLoc then placeLabel(f.hotkey, self.config.keyBindLoc) end if self.config.stackCountLoc then placeLabel(f.count, self.config.stackCountLoc) end if self.config.showKeyBind then f.hotkey:Show() else f.hotkey:Hide() end if self.config.showStackCount then f.count:Show() else f.count:Hide() end if self.config.showMacroName then f.macro:Show() else f.macro:Hide() end end function RAAD:ApplyStyle() local f = self.frames -- for now, just a static style f.hotkey:SetFontObject(NumberFontNormal) f.count:SetFontObject(NumberFontNormalYellow) f.border:SetVertexColor( tcolor(equippedActionBorderColor) ) end function RAAD:StartFlash() self.flashing = true self.flashtime = 0 end function RAAD:StopFlash() self.flashing = false self.frames.flash:Hide() end function RAAD:IsFlashing() return self.flashing end function RAAD:DisplayVisibility() local b = self.frames.button if b:GetAttribute("statehidden") then -- can't hide/show in combat if not InCombatLockdown() then b:Hide() end elseif self.showTmp_ and self.showTmp_ > 0 then b:GetNormalTexture():SetAlpha(0.5) if self:IsActionEmpty() then self.frames.cooldown:Hide() if not InCombatLockdown() and not b:IsShown() then b:Show() end end b:SetAlpha(1) elseif not self:IsActionEmpty() then b:GetNormalTexture():SetAlpha(1.0) b:SetAlpha(self.currentOpacity or (self.config.opacity and self.config.opacity.usable) or 1) else if self.config.hideEmptySlots then if not InCombatLockdown() then b:Hide() end else b:SetAlpha(self.config.opacity and self.config.opacity.empty or 0) end end end