Mercurial > wow > reaction
changeset 122:a2d2f23137c8
- Rearranged and consolidated some files in modules directory
- Added 'classes' directory, moved Bar and Overlay there
- Added Button, ActionButton, and GridProxy classes, not in use yet
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Mon, 23 Feb 2009 18:56:57 +0000 |
parents | fb6c3a642ae3 |
children | 943eed2c7def |
files | Bindings.lua ReAction.lua ReAction.toc classes/ActionButton.lua classes/Bar.lua classes/Button.lua classes/GridProxy.lua classes/Overlay.lua classes/classes.xml modules/Bar.lua modules/Bindings.lua modules/LDB.lua modules/Overlay.lua modules/modules.xml |
diffstat | 14 files changed, 2117 insertions(+), 1048 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Bindings.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,7 @@ +local L = ReAction.L +local _G = _G + +_G["BINDING_HEADER_REACTION"] = L["ReAction"] + +_G["BINDING_NAME_REACTION_TOGGLELOCK"] = L["Toggle ReAction Bar Lock"] +_G["BINDING_NAME_REACTION_TOGGLEKEYBIND"] = L["ReAction Keybinding Mode"]
--- a/ReAction.lua Mon Feb 09 19:02:58 2009 +0000 +++ b/ReAction.lua Mon Feb 23 18:56:57 2009 +0000 @@ -522,3 +522,36 @@ StaticPopup_Show("REACTION_KB_WARN") end end + +-- Export ReAction launcher to LibDataBroker-aware displays +LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject( "ReAction", + { + type = "launcher", + icon = "Interface\\Icons\\INV_Qiraj_JewelEncased", + + OnClick = function( frame, button ) + if not InCombatLockdown() then + if IsAltKeyDown() then + ReAction:SetKeybindMode( not ReAction:GetKeybindMode() ) + elseif IsShiftKeyDown() then + ReAction:SetConfigMode( not ReAction:GetConfigMode() ) + elseif button == "RightButton" then + ReAction:ShowEditor() + else + ReAction:ShowConfig() + end + else + ReAction:UserError(L["ReAction: can't configure in combat"]) + end + end, + + -- this isn't included in the 'launcher' type LDB spec but it seems all launcher displays use it + OnTooltipShow = function( tooltip ) + tooltip:AddLine(format("|cffffffff%s|r %s",L["Click"],L["for global configuration"])) + tooltip:AddLine(format("|cffffd200%s|r %s",L["Right-click"],L["for bar editor dialog"])) + tooltip:AddLine(format("|cff00ff00%s|r %s",L["Shift-click"],L["to unlock bars"])) + tooltip:AddLine(format("|cff00cccc%s|r %s",L["Alt-click"],L["for keybind mode"])) + end, + + } +)
--- a/ReAction.toc Mon Feb 09 19:02:58 2009 +0000 +++ b/ReAction.toc Mon Feb 23 18:56:57 2009 +0000 @@ -12,5 +12,9 @@ lib\embeds.xml locale\locale.xml + ReAction.lua +bindings.lua + +classes\classes.xml modules\modules.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/ActionButton.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,693 @@ +local ReAction = ReAction +local L = ReAction.L +local _G = _G +local CreateFrame = CreateFrame +local GetBindingKey = GetBindingKey +local format = string.format +local IsUsableAction = IsUsableAction +local IsEquippedAction = IsEquippedAction +local IsConsumableAction = IsConsumableAction +local IsStackableAction = IsStackableAction +local GetActionText = GetActionText +local GetCVar = GetCVar +local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor +local IsCurrentAction = IsCurrentAction +local IsAutoRepeatAction = IsAutoRepeatAction +local IsUsableAction = IsUsableAction +local IsAttackAction = IsAttackAction +local CooldownFrame_SetTimer = CooldownFrame_SetTimer +local GetActionCooldown = GetActionCooldown +local GetActionTexture = GetActionTexture +local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME +local TOOLTIP_UPDATE_TIME = TOOLTIP_UPDATE_TIME +local IsActionInRange = IsActionInRange +local InCombatLockdown = InCombatLockdown +local HasAction = HasAction + +ReAction:UpdateRevision("$Revision: 154 $") + +-- +-- Secure snippets +-- These are run within the context of the bar's sandbox, as the +-- buttons themselves do not have their own sandbox. +-- +local _onstate_mc = -- function(self, stateid, newstate) +[[ + local oldMcVehicleState = mcVehicleState + mcVehicleState = newstate + control:ChildUpdate() + if oldMcVehicleState == "vehicle" or mcVehicleState == "vehicle" then + control:ChildUpdate("vehicle") + end +]] + +local _childupdate = -- function(self, snippetid, message) +[[ + local action = nil + if (doVehicle and mcVehicleState == "vehicle") or + (doMindControl and mcVehicleState == "mc") then + local idx = self:GetAttribute("bar-idx") + if idx and idx <= 12 then + action = 120 + idx + else + action = 0 + end + elseif page and state and page[state] then + action = self:GetAttribute("action-page"..page[state]) + else + action = self:GetAttribute("default-action") + end + + self:SetAttribute("action",action) + local hasaction = (action > 120) or self:GetAttribute("hasaction-"..action) + + if (self:GetAttribute("showgrid") + self:GetAttribute("showgrid-temp") == 0) and not hasaction then + self:Hide() + else + self:Show() + end +]] + +local _childupdate_vehicleExit = -- function(self, snippetid, message) +[[ + local show = (mcVehicleState == "vehicle") + if show then + self:SetAttribute("type","macro") + self:SetAttribute("macrotext","/run VehicleExit()") + self:Show() + else + self:SetAttribute("type","action") + end + control:CallMethod("ShowVehicleExit",show) +]] + +local _childupdate_showgrid = -- function(self, snippetid, message) +[[ + self:SetAttribute("showgrid-temp",message or 0) + local count = (message or 0) + (self:GetAttribute("showgrid") or 0) + if count == 0 then + local action = self:GetAttribute("action") + local hasaction = (action > 120) or self:GetAttribute("hasaction-"..action) + if hasaction then + self:Show() + else + self:Hide() + end + else + self:Show() + end +]] + +local _onDragStart = -- function(self, button, kind, value, ...) +[[ + if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then + return kind, value, ... + else + -- don't make any assumptions about hiding on grid show here, as we don't know if the + -- drag gets cancelled later. + return "action", self:GetAttribute("action") + end +]] + +local _onReceiveDrag = -- function(self, button, kind, value, ...) +[[ + if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then + return kind, value, ... + else + if kind == "spell" or kind == "item" or kind == "macro" then + -- assume it's a valid action + self:SetAttribute("hasaction-"..self:GetAttribute("action"),true) + end + return "action", self:GetAttribute("action") + end +]] + +-- +-- private +-- +local eventList = { + "PLAYER_REGEN_ENABLED", + "PLAYER_ENTERING_WORLD", + "ACTIONBAR_PAGE_CHANGED", + "ACTIONBAR_SLOT_CHANGED", + "UPDATE_BINDINGS", + "ACTIONBAR_UPDATE_STATE", + "ACTIONBAR_UPDATE_USABLE", + "ACTIONBAR_UPDATE_COOLDOWN", + "UPDATE_INVENTORY_ALERTS", + "PLAYER_TARGET_CHANGED", + "TRADE_SKILL_SHOW", + "TRADE_SKILL_CLOSE", + "PLAYER_ENTER_COMBAT", + "PLAYER_LEAVE_COMBAT", + "START_AUTOREPEAT_SPELL", + "STOP_AUTOREPEAT_SPELL", + "UNIT_ENTERED_VEHICLE", + "UNIT_EXITED_VEHICLE", + "COMPANION_UPDATE", +} + +-- +-- Action Button class +-- +local Super = ReAction.Button +local Action = setmetatable( { }, { __index = Super } ) +ReAction.Button.Action = Action + +function Action:New( idx, config, bar, idHint ) + self = Super.New( + self, + format("ReAction_%s_Action_%d",bar:GetName(),idx), + config, + bar, + idx, + "ActionButtonTemplate, SecureActionButtonTemplate" ) + + local f = self:GetFrame() + local barFrame = bar:GetFrame() + + local frames = { } + self.frames = frames + frames.icon = _G[name.."Icon"] + frames.flash = _G[name.."Flash"] + frames.hotkey = _G[name.."HotKey"] + frames.count = _G[name.."Count"] + frames.name = _G[name.."Name"] + frames.border = _G[name.."Border"] + frames.cooldown = _G[name.."Cooldown"] + frames.normalTexture = _G[name.."NormalTexture"] + + self.hotkey = frames.hotkey -- alias for Button methods + self.border = frames.border -- alias for Button methods + + self.rangeTimer = TOOLTIP_UPDATE_TIME + + -- set up the base action ID + self:SetActionIDPool("action",120) + config.actionID = self:AcquireActionID(config.actionID, idHint) + self.actionID = config.actionID + self.nPages = 1 + + -- attribute setup + f:SetAttribute("type","action") + f:SetAttribute("checkselfcast", true) + f:SetAttribute("checkfocuscast", true) + f:SetAttribute("useparent-unit", true) + f:SetAttribute("action", config.actionID) + f:SetAttribute("default-action", config.actionID) + f:SetAttribute("showgrid",0) + f:SetAttribute("showgrid-temp",0) + f:SetAttribute("bar-idx",idx) + + -- non secure scripts + f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end) + f:SetScript("OnEnter", function(frame) self:OnEnter() end) + f:SetScript("OnLeave", function(frame) self:OnLeave() end) + f:SetScript("OnAttributeChanged", function(frame, attr, value) self:OnAttributeChanged(attr, value) end) + f:SetScript("PostClick", function(frame, ...) self:PostClick(...) end) + f:SetScript("OnUpdate", function(frame, elapsed) self:OnUpdate(elapsed) end) + f:SetScript("OnDragStart", function(frame) self:OnDragStart() end) + f:SetScript("OnReceiveDrag", function(frame), self:OnReceiveDrag() end) + + -- secure handlers + f:SetAttribute("_childupate", _childupdate) + f:SetAttribute("_childupdate-showgrid",_childupdate_showgrid) + barFrame:WrapScript(f, "OnDragStart", _onDragStart) + barFrame:WrapScript(f, "OnReceiveDrag", _onReceiveDrag) + if idx == 7 then + -- install vehicle-exit button on 7th button (only) + f:SetAttribute("_childupdate-vehicle", _childupdate_vehicleExit) + local button = self + function barFrame:ShowVehicleExit(show) + button:ShowVehicleExit(show) + end + end + + -- event registration + f:RegisterForDrag("LeftButton", "RightButton") + f:RegisterForClicks("AnyUp") + for _, evt in pairs(eventList) do + f:RegisterEvent(evt) + end + + -- attach to skinner + bar:SkinButton(self) + + -- initial display + self:ShowGrid(not barFrame:GetConfig().hideEmpty) + if ReAction:GetConfigMode() then + self:ShowGrid(true) + end + + self:Refresh() +end + +function Action:Destroy() + local f = self:GetFrame() + + f:UnregisterAllEvents() + + f:SetAttribute("_childupdate-vehicle",nil) + + self:ReleaseActionID(config.actionID) + if self.config.pageactions then + for _, id in ipairs(self.config.pageactions) do + self:ReleaseActionID(id) + end + end + + Super:Destroy() +end + +function Action:Refresh() + self.bar:PlaceButton(self, 36, 36) + self:RefreshPages() + self:UpdateAction() +end + +function Action:UpdateAll() + self:UpdateActionIDLabel(ReAction:GetConfigMode()) + self:UpdateHotkey() + self:UpdateShowGrid() + self:UpdateIcon() + self:UpdateBorder() + self:UpdateMacroText() + self:UpdateCount() + self:UpdateTooltip() + self:UpdateCheckedState() + self:UpdateUsable() + self:UpdateCooldown() + self:UpdateFlash() +end + +function Action:UpdateAction() + local action = self:GetActionID() + if action ~= self.actionID then + self.actionID = action + self:UpdateAll() + end +end + +function Action:UpdateShowGrid() + -- this is a little bit complicated because there's no + -- secure driver to handle show/hide grid events. + if InCombatLockdown() then + self.showgridPending = true -- handle after combat + else + self.showgridPending = false + -- check if each action has an action or not, and flag an attribute + -- so that the showgrid secure handler can make decisions accordingly + local f = self:GetFrame() + f:SetAttribute("hasaction-"..self.config.actionID, HasAction(self.config.actionID)) + for i = 1, self.nPages do + f:SetAttribute("hasaction-"..self.config.pageactions[i], HasAction(self.config.pageactions[i]) + end + -- the following is an out-of-combat show/hide to supplement the secure + -- handling and clean up after it when it guesses + if HasAction(self.actionID) then + f:Show() + else + f:Hide() + end + end +end + +function Action:UpdateIcon() + local action = self.actionID + local texture = GetActionTexture(action) + local icon = self.frames.icon + local hotkey = self.frames.hotkey + local f = self:GetFrame() + if texture then + icon:SetTexture(texture) + icon:Show() + self.rangeTimer = -1 + f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") + hotkey:SetVertexColor(1.0, 1.0, 1.0) + else + icon:Hide() + self.frames.cooldown:Hide() + self.rangeTimer = nil + f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot") + hotkey:SetVertexColor(0.6, 0.6, 0.6) + end + end +end + +function Action:UpdateBorder() + local action = self.actionID + if ReAction:GetKeybindMode() then + self:UpdateKeybindModeDisplay(true) + elseif IsEquippedAction(action) then + self.frames.border:SetVertexColor(0, 1.0, 0, 0.35) + self.frames.border:Show() + else + self.frames.border:Hide() + end +end + +function Action:UpdateMacroText() + local action = self.actionID + if not IsConsumableAction(action) and not IsStackableAction(action) then + self.frames.name:SetText(GetActionText(action)) + else + self.frames.name:SetText("") + end +end + +function Action:UpdateCount() + local action = self.actionID + if IsConsumableAction(action) or IsStackableAction(action) then + self.frames.count:SetText(GetActionCount(action)) + else + self.frames.count:SetText("") + end +end + +function Action:UpdateTooltip() + local f = self:GetFrame() + if GameTooltip:GetOwner() == f then + self:SetTooltip() + end +end + +function Action:SetTooltip() + local f = self:GetFrame() + if GetCVar("UberTooltips") == "1" then + GameTooltip_SetDefaultAnchor(GameTooltip, f) + else + GameTooltip:SetOwner(f) + end + GameTooltip:SetAction(self.actionID) +end + +function Action:UpdateCheckedState() + local action = self.actionID + if IsCurrentAction(action) or IsAutoRepeatAction(action) then + self:GetFrame():SetChecked(1) + else + self:GetFrame():SetChecked(0) + end +end + +function Action:UpdateUsable() + local isUsable, notEnoughMana = IsUsableAction(self.actionID) + if isUsable then + self.frames.icon:SetVertexColor(1.0, 1.0, 1.0) + self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) + elseif notEnoughMana then + self.frames.icon:SetVertexColor(0.5, 0.5, 1.0) + self.frames.normalTexture:SetVertexColor(0.5, 0.5, 1.0) + else + self.frames.icon:SetVertexColor(0.4, 0.4, 0.4) + self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) + end +end + +function Action:UpdateCooldown() + CooldownFrame_SetTimer(self.frames.cooldown, GetActionCooldown(self.actionID)) +end + +function Action:UpdateFlash() + local action = self.actionID + self:SetFlash( (IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action) ) +end + +function Action:SetFlash(flash) + if self.flashing ~= flash then + self.flashing = flash + self.flashtime = 0 + if not flash then + self.frames.flash:Hide() + end + self:UpdateCheckedState() + end +end + +function Action:RunFlash(elapsed) + if self.flashing then + local flashtime = self.flashtime - elapsed + self.flashtime = flashtime + if flashtime <= 0 then + local overtime = -flashtime + if overtime >= ATTACK_BUTTON_FLASH_TIME then + overtime = 0 + end + flashtime = ATTACK_BUTTON_FLASH_TIME - overtime + local flash = self.frames.flash + if flash:IsShown() then + flash:Hide() + else + flash:Show() + end + end + end +end + +function Action:RunRangeFinder(elapsed) + local rangeTimer = self.rangeTimer + if rangeTimer then + rangeTimer = rangeTimer - elapsed + self.rangeTimer = rangeTimer + if rangeTimer <= 0 then + if IsActionInRange(self.actionID) == 0 then + self.frames.icon:SetVertexColor(1.0,0.1,0.1) + else + self:UpdateUsable() + end + frame.rangeTimer = TOOLTIP_UPDATE_TIME + end + end +end + +function Action:GetActionID(page) + if page == nil then + -- get the effective ID + return self:GetFrame():GetAttribute("action") + else + if page == 1 then + return self.config.actionID + else + return self.config.pageactions and self.config.pageactions[page] or self.config.actionID + end + end +end + +function Action:SetActionID( id, page ) + id = tonumber(id) + page = tonumber(page) + if id == nil or id < 1 or id > 120 then + error("Action:SetActionID - invalid action ID") + end + if page and page ~= 1 then + if not self.config.pageactions then + self.config.pageactions = { } + end + self:ReleaseActionID(self.config.pageactions[page]) + self.config.pageactions[page] = id + self:AcquireActionID(self.config.pageactions[page]) + self.frame:SetAttribute("action-page"..page,id) + else + self:ReleaseActionID(self.config.actionID) + self.config.actionID = id + self:AcquireActionID(self.config.actionID) + self.frame:SetAttribute("action",id) + self.frame:SetAttribute("default-action",id) + if self.config.pageactions then + self.config.pageactions[1] = id + self.frame:SetAttribute("action-page1",id) + end + end +end + +function Action:RefreshPages( force ) + local nPages = self.bar:GetConfig().nPages + if nPages and (nPages ~= self.nPages or force) then + local f = self:GetFrame() + local c = self.config.pageactions + if nPages > 1 and not c then + c = { } + self.config.pageactions = c + end + for i = 1, nPages do + if i > 1 then + c[i] = self:AcquireActionID(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons()) + else + c[i] = self.config.actionID -- page 1 is the same as the base actionID + end + f:SetAttribute(("action-page%d"):format(i),c[i]) + end + for i = nPages+1, #c do + self:ReleaseActionID(c[i]) + c[i] = nil + f:SetAttribute(("action-page%d"):format(i),nil) + end + self.nPages = nPages + end +end + +function Action:SetupBarHeader( bar ) -- call this as a static method + local f = bar:GetFrame() + local c = bar:GetConfig() + f:SetAttribute("mindcontrol",c.mindcontrol) + f:SetAttribute("vehicle",c.vehicle) + f:Execute( + [[ + doMindControl = self:GetAttribute("mindcontrol") + doVehicle = self:GetAttribute("vehicle") + control:ChildUpdate() + ]]) + + f:SetAttribute("_onstate-mc", _onstate_mc) + RegisterStateDriver(f, "mc", "[target=vehicle,exists] vehicle; [bonusbar:5] mc; none") + + f:SetAttribute("lockbuttons",c.lockButtons) + f:SetAttribute("lockbuttonscombat",c.lockButtonsCombat) + f:Execute( + [[ + lockButtons = self:GetAttribute("lockbuttons") + lockButtonsCombat = self:GetAttribute("lockbuttonscombat") + ]]) +end + + +function Action:ShowVehicleExit(show) + local f = self:GetFrame() + local tx = f.vehicleExitTexture + if show then + if not tx then + tx = f:CreateTexture(nil,"ARTWORK") + tx:SetAllPoints() + -- copied from Blizzard/VehicleMenuBar.lua SkinsData + tx:SetTexture("Interface\\Vehicles\\UI-Vehicles-Button-Exit-Up") + tx:SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375) + f.vehicleExitTexture = tx + end + tx:Show() + f.vehicleExitMode = true + elseif tx then + tx:SetTexCoord(0,1,0,1) + tx:Hide() + f.vehicleExitMode = false + end +end + +function Action:OnEnter( ) + self:SetTooltip() +end + +function Action:OnLeave( ) + GameTooltip:Hide() +end + +function Action:OnAttributeChanged( attr, value ) + self:UpdateAction() +end + +function Action:PostClick( ) + self:UpdateCheckedState() +end + +function Action:OnUpdate( elapsed ) + self:RunFlash(elapsed) + self:RunRangeFinder(elapsed) +end + +function Action:OnDragStart() + self:UpdateCheckedState() + self:UpdateFlash() +end + +function Action:OnReceiveDrag() + self:UpdateCheckedState() + self:UpdateFlash() +end + +function Action:OnEvent(event, ...) + if self[event] then + self[event](self, event, ...) + end +end + +function Action:ACTIONBAR_SLOT_CHANGED(event, action) + if action == 0 or action == self.actionID then + self:UpdateAction() + end +end + +function Action:PLAYER_ENTERING_WORLD() + self:UpdateAction() +end + +function Action:ACTIONBAR_PAGE_CHANGED() + self:UpdateAction() +end + +function Action:UPDATE_BONUS_ACTIONBAR() + self:UpdateAction() +end + +function Action:UPDATE_BINDINGS() + self:UpdateHotkey() +end + +function Action:PLAYER_TARGET_CHANGED() + self.rangeTimer = -1 +end + +function Action:ACTIONBAR_UPDATE_STATE() + self:UpdateCheckedState() +end +Action.TRADE_SKILL_SHOW = Action.ACTIONBAR_UPDATE_STATE +Action.TRADE_SKILL_CLOSE = Action.ACTIONBAR_UPDATE_STATE + +function Action:UNIT_ENTERED_VEHICLE(event,unit) + if unit == "player" then + self:UpdateCheckedState() + end +end +Action.UNIT_EXITED_VEHICLE = Action.UNIT_ENTERED_VEHICLE + +function Action:COMPANION_UPDATE(event,unit) + if unit == "mount" then + self:UpdateCheckedState() + end +end + +function Action:ACTIONBAR_UPDATE_USABLE() + self:UpdateUsable() +end + +function Action:ACTIONBAR_UPDATE_COOLDOWN() + self:UpdateCooldown() +end + +function Action:PLAYER_ENTER_COMBAT() + if IsAttackAction(self.actionID) then + self:SetFlash(true) + end +end + +function Action:PLAYER_LEAVE_COMBAT() + if IsAttackAction(self.actionID) then + self:SetFlash(false) + end +end + +function Action:START_AUTOREPEAT_SPELL() + if IsAutoRepeatAction(self.actionID) then + self:SetFlash(true) + end +end + +function Action:STOP_AUTOREPEAT_SPELL() + if not IsAttackAction(self.actionID) then + self:SetFlash(false) + end +end + +function Action:PLAYER_REGEN_ENABLED() + if self.showgridPending then + self:UpdateShowGrid() + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/Bar.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,259 @@ +local ReAction = ReAction +local L = ReAction.L +local _G = _G +local CreateFrame = CreateFrame +local floor = math.floor +local fmod = math.fmod +local format = string.format + +ReAction:UpdateRevision("$Revision$") + +local Bar = { } +local proto = { __index = Bar } +local weak = { __mode = "k" } + +ReAction.Bar = Bar -- export to ReAction + +function Bar:New( name, config ) + if type(config) ~= "table" then + error("ReAction.Bar: config table required") + end + + -- create new self + self = setmetatable( + { + config = config, + name = name, + buttons = setmetatable( { }, weak ), + width = config.width or 480, + height = config.height or 40 + }, + proto ) + + -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is + -- not mouse-clickable by the user. + local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent + local f = CreateFrame("Button", name and format("ReAction-%s",name), parent, + "SecureHandlerStateTemplate, SecureHandlerClickTemplate") + f:SetFrameStrata("MEDIUM") + f:SetWidth(self.width) + f:SetWidth(self.height) + f:SetAlpha(config.alpha or 1.0) + f:Show() + f:EnableMouse(false) + f:SetClampedToScreen(true) + + f:SetAttribute("_onstate-showgrid", + -- function(self,stateid,newstate) + [[ + control:ChildUpdate(stateid,newstate) + control:CallMethod("UpdateShowGrid") + ]]) + f.UpdateShowGrid = function(frame) + for button in self:IterateButtons() do + button:UpdateShowGrid() + end + end + ReAction.gridProxy:AddFrame(f) + + -- Override the default frame accessor to provide strict read-only access + function self:GetFrame() + return f + end + + self:ApplyAnchor() + ReAction.RegisterCallback(self, "OnConfigModeChanged") + + return self +end + +function Bar:Destroy() + local f = self:GetFrame() + f:UnregisterAllEvents() + ReAction.UnregisterAllCallbacks(self) + ReAction.gridProxy:RemoveFrame(f) + f:Hide() + f:SetParent(UIParent) + f:ClearAllPoints() +end + +function Bar:OnConfigModeChanged(event, mode) + self:ShowControls(mode) -- Bar:ShowControls() defined in Overlay.lua +end + +function Bar:ApplyAnchor() + local f = self:GetFrame() + local c = self.config + local p = c.point + + f:SetWidth(c.width) + f:SetHeight(c.height) + f:ClearAllPoints() + + if p then + local a = f:GetParent() + if c.anchor then + local bar = ReAction:GetBar(c.anchor) + if bar then + a = bar:GetFrame() + else + a = _G[c.anchor] + end + end + local fr = a or f:GetParent() + f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0) + else + f:SetPoint("CENTER") + end +end + +function Bar:SetAnchor(point, frame, relativePoint, x, y) + local c = self.config + c.point = point or c.point + c.anchor = frame or c.anchor + c.relpoint = relativePoint or c.relpoint + c.x = x or c.x + c.y = y or c.y + self:ApplyAnchor() + ReAction:RefreshBar(self) +end + +function Bar:GetAnchor() + local c = self.config + return (c.point or "CENTER"), + (c.anchor or self:GetFrame():GetParent():GetName()), + (c.relpoint or c.point or "CENTER"), + (c.x or 0), + (c.y or 0) +end + +function Bar:GetSize() + local f = self:GetFrame() + return f:GetWidth(), f:GetHeight() +end + +function Bar:SetSize(w,h) + local f = self:GetFrame() + self.config.width = w + self.config.height = h + f:SetWidth(w) + f:SetHeight(h) +end + +function Bar:GetButtonSize() + local w = self.config.btnWidth or 32 + local h = self.config.btnHeight or 32 + -- TODO: get from modules? + return w,h +end + +function Bar:SetButtonSize(w,h) + if w > 0 and h > 0 then + self.config.btnWidth = w + self.config.btnHeight = h + end + ReAction:RefreshBar(self) +end + +function Bar:GetButtonGrid() + local cfg = self.config + local r = cfg.btnRows or 1 + local c = cfg.btnColumns or 1 + local s = cfg.spacing or 4 + return r,c,s +end + +function Bar:GetNumButtons() + local r,c = self:GetButtonGrid() + return r*c +end + +function Bar:SetButtonGrid(r,c,s) + if r > 0 and c > 0 and s > 0 then + local cfg = self.config + cfg.btnRows = r + cfg.btnColumns = c + cfg.spacing = s + end + ReAction:RefreshBar(self) +end + +function Bar:ClipNButtons( n ) + local cfg = self.config + local r = cfg.btnRows or 1 + local c = cfg.btnColumns or 1 + + cfg.btnRows = ceil(n/c) + cfg.btnColumns = min(n,c) +end + +function Bar:GetName() + return self.name +end + +function Bar:GetFrame() + -- this method is included for documentation purposes. It is overridden + -- for each object in the :New() method. + error("Invalid Bar object: used without initialization") +end + +-- only ReAction:RenameBar() should call this function. Calling from any other +-- context will desync the bar list in the ReAction class. +function Bar:SetName(name) + self.name = name + self:SetLabel(self.name) -- Bar:SetLabel() defined in Overlay.lua +end + +function Bar:GetAlpha() + return self.config.alpha or 1.0 +end + +function Bar:SetAlpha(value) + self.config.alpha = value + self:GetFrame():SetAlpha(value or 1.0) + ReAction:RefreshBar(self) +end + +function Bar:AddButton(idx, button) + local f = self:GetFrame() + + -- store in a weak reverse-index array + self.buttons[button] = idx + + -- Store a properly wrapped reference to the child frame as an attribute + -- (accessible via "frameref-btn#") + f:SetFrameRef(format("btn%d",idx), button:GetFrame()) +end + +function Bar:RemoveButton(button) + local idx = self.buttons[button] + if idx then + self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil) + self.buttons[button] = nil + end +end + +-- iterator returns button, idx and does NOT iterate in index order +function Bar:IterateButtons() + return pairs(self.buttons) +end + +function Bar:PlaceButton(button, baseW, baseH) + local idx = self.buttons[button] + if idx then + local r, c, s = self:GetButtonGrid() + local bh, bw = self:GetButtonSize() + local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based + local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s) + local scale = bw/baseW + local b = button:GetFrame() + + b:ClearAllPoints() + b:SetPoint("TOPLEFT",x/scale,y/scale) + b:SetScale(scale) + end +end + +function Bar:SkinButton() + -- does nothing by default +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/Button.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,277 @@ +--[[ + ReAction Button base class +--]] + +-- local imports +local ReAction = ReAction +local L = ReAction.L +local _G = _G +local CreateFrame = CreateFrame +local GetBindingKey = GetBindingKey +local format = string.format + +ReAction:UpdateRevision("$Revision: 154 $") + +-- libraries +local KB = LibStub("LibKeyBound-1.0") +local LBF = LibStub("LibButtonFacade",true) -- optional + +-- private +local trash = CreateFrame("Frame") +local frameList = { } +local idPools = { } + +local function kb_onEnter( frame ) + KB:Set(frame) +end + +-- Button class +local Button = { } + +ReAction.Button = Button -- export to ReAction + +function Button:New( name, config, bar, idx, inherits, buttonType ) + buttonType = buttonType or "CheckButton" + + -- create new self + self = setmetatable( + { + bar = bar, + idx = idx, + config = config, + name = name, + }, + { __index = self } ) + + -- have to recycle frames with the same name: CreateFrame() doesn't overwrite + -- existing globals. Can't set to nil in the global because it's then tainted. + -- Caller is responsible for ensuring global uniqueness of names. + local f = name and frameList[name] + if f then + f:SetParent(bar:GetFrame()) + else + f = CreateFrame(buttonType, name, bar:GetFrame(), inherits) + if name then + frameList[name] = f + end + end + + self.frame = f + + if config then + config.name = name + end + + -- install LibKeyBound handlers onto frame + function f:GetActionName() + return format("%s:%s", bar:GetName(), idx) + end + + local clickBinding = format("CLICK %s:LeftButton", name) + function f:GetHotkey() + return KB:ToShortKey(GetBindingKey(clickBinding)) + end + + return self +end + +function Button:Destroy() + local f = self.frame + gridProxy:RemoveGridFrame(f) + f:Hide() + f:SetParent(trash) + f:ClearAllPoints() +end + +function Button:GetFrame() + return self.frame +end + +function Button:GetName() + return self.name +end + +function Button:GetConfig() + return self.config +end + +function Button:GetActionID() + -- derived classes should override this + return nil +end + +function Button:SetActionIDPool( poolID, maxID ) + self.actionPoolID = poolID + self.actionMaxID = maxID +end + +function Button:AcquireActionID( id, hint, unique ) + local poolID = self.actionPoolID + local maxID = self.actionMaxID + if not poolID or not maxID then + error("AcquireActionID: must setup pool first with SetActionIDPool") + end + local pool = pools[poolID] + if not pool then + pool = { nWraps = 0, useCount = { } } + for i = 1, maxID do + pool.useCount[i] = 0 + end + pools[poolID] = pool + end + local useCount = pool.useCount + if id == nil then + repeat + local nWraps = pool.nWraps + if useCount[hint] == nil or useCount[hint] == nWraps then + id = hint + else + local start = hint or 1 + for i = start, maxID do + if useCount[i] == nil or useCount[i] == nWraps then + id = i + break + end + end + if not id then + for i = 1, start do + if useCount[i] == nil or useCount[i] == nWraps then + id = i + break + end + end + end + end + if id == nil then + if unique then + return nil + end + pool.nWraps = nWraps + 1 + end + until id + end + useCount[id] = (useCount[id] or 0) + 1 + return id +end + +function Button:ReleaseActionID( id ) + local poolID = self.actionPoolID + if not poolID then + error("ReleaseActionID: must setup pool first with SetActionIDPool") + end + local pool = pools[poolID] + if pool and id and pool.useCount[id] then + pool.useCount[id] = pool.useCount[id] - 1 + pool.nWraps = min(pool.useCount[id], pool.nWraps) + end +end + +function Button:Refresh() + self.bar:PlaceButton( self, self.frame:GetWidth(), self.frame:GetHeight() ) +end + +function Button:SetKeybindMode( mode ) + local f = self.frame + if mode then + self.oldOnEnter = f:GetScript("OnEnter") + f:SetScript("OnEnter", kb_onEnter) + else + f:SetScript("OnEnter", self.oldOnEnter) + self.oldOnEnter = nil + end + self:UpdateKeybindModeDisplay( mode ) +end + +function Button:UpdateKeybindModeDisplay( mode ) + self.border = self.border or _G[format("%sBorder",tostring(self:GetName()))] + if self.border then + if mode then + self.border:SetVertexColor(KB:GetColorKeyBoundMode()) + self.border:Show() + else + self.border:Hide() + end + end +end + +function Button:UpdateHotkey( hotkey ) + hotkey = hotkey or self.hotkey + if not hotkey then + hotkey = _G[format("%sHotKey", tostring(self:GetName()))] + self.hotkey = hotkey + end + if hotkey then + local txt = self.frame:GetHotkey() + hotkey:SetText( txt ) + if txt == nil or txt == "" then + hotkey:Hide() + else + hotkey:Show() + end + end +end + +function Button:GetActionIDLabel( create ) + local f = self.frame + if not f.actionIDLabel and create then + local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") + label:SetAllPoints() + label:SetJustifyH("CENTER") + label:SetShadowColor(0,0,0,1) + label:SetShadowOffset(2,-2) + f.actionIDLabel = label -- store the label with the frame for recycling + end + return f.actionIDLabel +end + +function Button:UpdateActionIDLabel( show ) + local label = self:GetActionIDLabel( show ) + if label then + if show then + local id = self:GetActionID() + if id then + label:SetText(tostring(id)) + label:Show() + return + end + end + label:Hide() + end +end + +function Button:SetNormalVertexColor( r, g, b, a ) + if LBF then + LBF:SetNormalVertexColor(self.frame, r, g, b, a) + else + self.frame:GetNormalTexture():SetVertexColor(r,g,b,a) + end +end + +function Button:GetNormalVertexColor() + if LBF then + return LBF:GetNormalVertexColor(self.frame) + else + return self.frame:GetNormalTexture():GetVertexColor() + end +end + +function Button:ShowGrid( show ) + if not InCombatLockdown() then + local f = self.frame + local count = f:GetAttribute("showgrid") + if show then + count = count + 1 + else + count = count - 1 + end + if count < 0 then + count = 0 + end + f:SetAttribute("showgrid",count) + self:UpdateShowGrid() + end +end + +function Button:UpdateShowGrid() + -- does nothing by default +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/GridProxy.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,65 @@ +-- +-- A hack for a ShowGrid secure handler, using a bastardized Blizzard ActionBarButton. +-- +local gridProxy = { } +ReAction.gridProxy = gridProxy + +local f = CreateFrame("CheckButton",nil,UIParent,"ActionBarButtonTemplate, SecureHandlerAttributeTemplate") + -- SecureHandlerAttributeTemplate overwrites the onAttributeChanged handler, as it's last in the list +f:UnregisterAllEvents() +f:SetScript("OnEnter",nil) +f:SetScript("OnLeave",nil) +f:SetScript("PostClick",nil) +f:SetScript("OnDragStart",nil) +f:SetScript("OnReceiveDrag",nil) +f:SetScript("OnUpdate",nil) +f:EnableMouse(false) +for _, child in ipairs({f:GetChildren()}) do + child:Hide() +end +for _, region in ipairs({f:GetRegions()}) do + region:Hide() +end +f:SetPoint("TOPLEFT") +f:Hide() + +-- The existing onEvent handler will set the 'showgrid' attribute +-- on this frame. Re-register for those events, but don't touch the +-- onEvent handler, to keep it secure. +f:RegisterEvent("ACTIONBAR_SHOWGRID"); +f:RegisterEvent("ACTIONBAR_HIDEGRID"); + +f:Execute( + [[ + frames = newtable() + ]]) + +-- shuttle 'showgrid' to the registered frames via state-showgrid attribute +f:SetAttribute("_onattributechanged", + -- function _onattributechanged(self,name,value) + [[ + if name == "showgrid" then + for _, f in pairs(frames) do + f:SetAttribute("state-showgrid",value) + end + end + ]]) + +function gridProxy:AddFrame(frame) + f:SetFrameRef("add",frame) + f:SetAttribute("frame-add-id",frame:GetName()) + f:Execute( + [[ + frames[self:GetAttribute("frame-add-id")] = self:GetFrameRef("add") + ]]) +end + +function gridProxy:RemoveFrame(frame) + f:SetAttribute("frame-remove-id",frame:GetName()) + f:Execute( + [[ + frames[self:GetAttribute("frame-remove-id")] = nil + ]]) +end + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/Overlay.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,769 @@ +local ReAction = ReAction +local L = ReAction.L +local CreateFrame = CreateFrame +local InCombatLockdown = InCombatLockdown +local floor = math.floor +local min = math.min +local format = string.format +local GameTooltip = GameTooltip +local Bar = ReAction.Bar +local GetSize = Bar.GetSize +local SetSize = Bar.SetSize +local GetButtonSize = Bar.GetButtonSize +local GetButtonGrid = Bar.GetButtonGrid +local SetButtonSize = Bar.SetButtonSize +local SetButtonGrid = Bar.SetButtonGrid +local ApplyAnchor = Bar.ApplyAnchor +local GameTooltipTextRight1 = GameTooltipTextRight1 +local GameTooltipTextRight2 = GameTooltipTextRight2 +local GameTooltipTextRight3 = GameTooltipTextRight3 + +local KB = LibStub("LibKeyBound-1.0") + +ReAction:UpdateRevision("$Revision$") + + +-- +-- Wrap some of the bar manipulators to make them state-aware +-- +local function SetAnchor( bar, point, frame, relPoint, x, y ) + local state = bar:GetState() + if state then + local anchorstate = bar:GetStateProperty(state, "anchorEnable") + if anchorstate then + bar:SetStateProperty(state, "anchorFrame", frame) + bar:SetStateProperty(state, "anchorPoint", point) + bar:SetStateProperty(state, "anchorRelPoint", relPoint) + bar:SetStateProperty(state, "anchorX", x or 0) + bar:SetStateProperty(state, "anchorY", y or 0) + bar:SetAnchor(bar:GetAnchor()) + return + end + end + bar:SetAnchor(point, frame, relPoint, x, y) +end + +local function GetStateScale( bar ) + local state = bar:GetState() + if state and bar:GetStateProperty(state, "enableScale") then + return bar:GetStateProperty(state, "scale") + end +end + +local function SetStateScale( bar, scale ) + local state = bar:GetState() + if state and bar:GetStateProperty(state, "enableScale") then + bar:SetStateProperty(state, "scale", scale) + end +end + + +-- +-- Bar config overlay +-- + +local function GetNormalTextColor() + return 1.0, 1.0, 1.0, 1.0 +end + +local function GetAnchoredTextColor() + return 1.0, 1.0, 1.0, 1.0 +end + +local function GetNormalBgColor() + return 0.7, 0.7, 1.0, 0.3 +end + +local function GetAnchoredBgColor() + return 0.9, 0.2, 0.7, 0.3 +end + +local function StoreSize(bar) + local f = bar:GetFrame() + SetSize( bar, f:GetWidth(), f:GetHeight() ) +end + +local function StoreExtents(bar) + local f = bar:GetFrame() + local p, fr, rp, x, y = f:GetPoint(1) + fr = fr and fr:GetName() or "UIParent" + SetAnchor( bar, p, fr, rp, x, y ) + SetSize( bar, f:GetWidth(), f:GetHeight() ) +end + +local function RecomputeButtonSize(bar) + local w, h = GetSize(bar) + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + + local scaleW = (floor(w/c) - s) / bw + local scaleH = (floor(h/r) - s) / bh + local scale = min(scaleW, scaleH) + + SetButtonSize(bar, scale * bw, scale * bh, s) +end + +local function ComputeBarScale(bar) + local w, h = bar.controlFrame:GetWidth() - 8, bar.controlFrame:GetHeight() - 8 + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + + local scaleW = w / (c*(bw+s)) + local scaleH = h / (r*(bh+s)) + local scale = min(scaleW, scaleH) + + if scale > 2.5 then + scale = 2.5 + elseif scale < 0.25 then + scale = 0.25 + end + + return scale +end + +local function RecomputeButtonSpacing(bar) + local w, h = GetSize(bar) + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + + SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh)) +end + +local function RecomputeGrid(bar) + local w, h = GetSize(bar) + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + + SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s) +end + +local function ClampToButtons(bar) + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + SetSize(bar, (bw+s)*c + 1, (bh+s)*r + 1) +end + +local function HideGameTooltip() + GameTooltip:Hide() +end + +local anchorInside = { inside = true } +local anchorOutside = { outside = true } +local edges = { "BOTTOM", "TOP", "LEFT", "RIGHT" } +local oppositeEdges = { + TOP = "BOTTOM", + BOTTOM = "TOP", + LEFT = "RIGHT", + RIGHT = "LEFT" +} +local pointsOnEdge = { + BOTTOM = { "BOTTOM", "BOTTOMLEFT", "BOTTOMRIGHT", }, + TOP = { "TOP", "TOPLEFT", "TOPRIGHT", }, + RIGHT = { "RIGHT", "BOTTOMRIGHT", "TOPRIGHT", }, + LEFT = { "LEFT", "BOTTOMLEFT", "TOPLEFT", }, +} +local edgeSelector = { + BOTTOM = 1, -- select x of x,y + TOP = 1, -- select x of x,y + LEFT = 2, -- select y of x,y + RIGHT = 2, -- select y of x,y +} +local snapPoints = { + [anchorOutside] = { + BOTTOMLEFT = {"BOTTOMRIGHT","TOPLEFT","TOPRIGHT"}, + BOTTOM = {"TOP"}, + BOTTOMRIGHT = {"BOTTOMLEFT","TOPRIGHT","TOPLEFT"}, + RIGHT = {"LEFT"}, + TOPRIGHT = {"TOPLEFT","BOTTOMRIGHT","BOTTOMLEFT"}, + TOP = {"BOTTOM"}, + TOPLEFT = {"TOPRIGHT","BOTTOMLEFT","BOTTOMRIGHT"}, + LEFT = {"RIGHT"}, + CENTER = {"CENTER"} + }, + [anchorInside] = { + BOTTOMLEFT = {"BOTTOMLEFT"}, + BOTTOM = {"BOTTOM"}, + BOTTOMRIGHT = {"BOTTOMRIGHT"}, + RIGHT = {"RIGHT"}, + TOPRIGHT = {"TOPRIGHT"}, + TOP = {"TOP"}, + TOPLEFT = {"TOPLEFT"}, + LEFT = {"LEFT"}, + CENTER = {"CENTER"} + } +} +local insidePointOffsetFuncs = { + BOTTOMLEFT = function(x, y) return x, y end, + BOTTOM = function(x, y) return 0, y end, + BOTTOMRIGHT = function(x, y) return -x, y end, + RIGHT = function(x, y) return -x, 0 end, + TOPRIGHT = function(x, y) return -x, -y end, + TOP = function(x, y) return 0, -y end, + TOPLEFT = function(x, y) return x, -y end, + LEFT = function(x, y) return x, 0 end, + CENTER = function(x, y) return x, y end, +} +local pointCoordFuncs = { + BOTTOMLEFT = function(f) return f:GetLeft(), f:GetBottom() end, + BOTTOM = function(f) return nil, f:GetBottom() end, + BOTTOMRIGHT = function(f) return f:GetRight(), f:GetBottom() end, + RIGHT = function(f) return f:GetRight(), nil end, + TOPRIGHT = function(f) return f:GetRight(), f:GetTop() end, + TOP = function(f) return nil, f:GetTop() end, + TOPLEFT = function(f) return f:GetLeft(), f:GetTop() end, + LEFT = function(f) return f:GetLeft(), nil end, + CENTER = function(f) return f:GetCenter() end, +} +local edgeBoundsFuncs = { + BOTTOM = function(f) return f:GetLeft(), f:GetRight() end, + LEFT = function(f) return f:GetBottom(), f:GetTop() end +} +edgeBoundsFuncs.TOP = edgeBoundsFuncs.BOTTOM +edgeBoundsFuncs.RIGHT = edgeBoundsFuncs.LEFT +local cornerTexCoords = { + -- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy + TOPLEFT = { 1, 1, 1, 0, 0, 1, 0, 0 }, + TOPRIGHT = { 1, 0, 0, 0, 1, 1, 0, 1 }, + BOTTOMLEFT = { 0, 1, 1, 1, 0, 0, 1, 0 }, + BOTTOMRIGHT = { 0, 0, 0, 1, 1, 0, 1, 1 }, +} + +-- Returns absolute coordinates x,y of the named point 'p' of frame 'f' +local function GetPointCoords( f, p ) + local x, y = pointCoordFuncs[p](f) + if not(x and y) then + local cx, cy = f:GetCenter() + x = x or cx + y = y or cy + end + return x, y +end + + +-- Returns true if frame 'f1' can be anchored to frame 'f2' +local function CheckAnchorable( f1, f2 ) + -- can't anchor a frame to itself or to nil + if f1 == f2 or f2 == nil then + return false + end + + -- can always anchor to UIParent + if f2 == UIParent then + return true + end + + -- also can't do circular anchoring of frames + -- walk the anchor chain, which generally shouldn't be that expensive + -- (who nests draggables that deep anyway?) + for i = 1, f2:GetNumPoints() do + local _, f = f2:GetPoint(i) + if not f then f = f2:GetParent() end + return CheckAnchorable(f1,f) + end + + return true +end + +-- Returns true if frames f1 and f2 specified edges overlap +local function CheckEdgeOverlap( f1, f2, e ) + local l1, u1 = edgeBoundsFuncs[e](f1) + local l2, u2 = edgeBoundsFuncs[e](f2) + return l1 <= l2 and l2 <= u1 or l2 <= l1 and l1 <= u2 +end + +-- Returns true if point p1 on frame f1 overlaps edge e2 on frame f2 +local function CheckPointEdgeOverlap( f1, p1, f2, e2 ) + local l, u = edgeBoundsFuncs[e2](f2) + local x, y = GetPointCoords(f1,p1) + x = select(edgeSelector[e2], x, y) + return l <= x and x <= u +end + +-- Returns the distance between corresponding edges. It is +-- assumed that the passed in edges e1 and e2 are the same or opposites +local function GetEdgeDistance( f1, f2, e1, e2 ) + local x1, y1 = pointCoordFuncs[e1](f1) + local x2, y2 = pointCoordFuncs[e2](f2) + return math.abs((x1 or y1) - (x2 or y2)) +end + +local globalSnapTargets = { [UIParent] = anchorInside } + +local function GetClosestFrameEdge(f1,f2,a) + local dist, edge, opp + if f2:IsVisible() and CheckAnchorable(f1,f2) then + for _, e in pairs(edges) do + local o = a.inside and e or oppositeEdges[e] + if CheckEdgeOverlap(f1,f2,e) then + local d = GetEdgeDistance(f1, f2, e, o) + if not dist or (d < dist) then + dist, edge, opp = d, e, o + end + end + end + end + return dist, edge, opp +end + +local function GetClosestVisibleEdge( f ) + local r, o, e1, e2 + local a = anchorOutside + for _, b in ReAction:IterateBars() do + local d, e, opp = GetClosestFrameEdge(f,b:GetFrame(),a) + if d and (not r or d < r) then + r, o, e1, e2 = d, b:GetFrame(), e, opp + end + end + for f2, a2 in pairs(globalSnapTargets) do + local d, e, opp = GetClosestFrameEdge(f,f2,a2) + if d and (not r or d < r) then + r, o, e1, e2, a = d, f2, e, opp, a2 + end + end + return o, e1, e2, a +end + +local function GetClosestVisiblePoint(f1) + local f2, e1, e2, a = GetClosestVisibleEdge(f1) + if f2 then + local rsq, p, rp, x, y + -- iterate pointsOnEdge in order and use < to prefer edge centers to corners + for _, p1 in ipairs(pointsOnEdge[e1]) do + if CheckPointEdgeOverlap(f1,p1,f2,e2) then + for _, p2 in pairs(snapPoints[a][p1]) do + local x1, y1 = GetPointCoords(f1,p1) + local x2, y2 = GetPointCoords(f2,p2) + local dx = x1 - x2 + local dy = y1 - y2 + local rsq2 = dx*dx + dy*dy + if not rsq or rsq2 < rsq then + rsq, p, rp, x, y = rsq2, p1, p2, dx, dy + end + end + end + end + return f2, p, rp, x, y + end +end + +local function GetClosestPointSnapped(f1, rx, ry, xOff, yOff) + local o, p, rp, x, y = GetClosestVisiblePoint(f1) + local s = false + + local insideOffsetFunc = p and insidePointOffsetFuncs[p] + local coordFunc = p and pointCoordFuncs[p] + if not insideOffsetFunc or not coordFunc then + return + end + + local sx, sy = insideOffsetFunc(xOff or 0, yOff or 0) + local xx, yy = coordFunc(f1) + if xx and yy then + if math.abs(x) <= rx then + if math.abs(y) <= ry then + x = sx + y = sy + s = true + elseif CheckEdgeOverlap(f1,o,"LEFT") then + x = sx + s = true + end + elseif math.abs(y) <= ry and CheckEdgeOverlap(f1,o,"TOP") then + y = sy + s = true + end + elseif xx then + if math.abs(x) <= rx then + x = sx + s = true + if math.abs(y) <= ry then + y = sy + end + end + elseif yy then + if math.abs(y) <= ry then + y = sy + s = true + if math.abs(x) <= rx then + x = sx + end + end + end + + -- correct for some Lua oddities with doubles + if x == -0 then x = 0 end + if y == -0 then y = 0 end + + if s then + return o, p, rp, math.floor(x), math.floor(y) + end +end + +local function CreateSnapIndicator() + local si = CreateFrame("Frame",nil,UIParent) + si:SetFrameStrata("HIGH") + si:SetHeight(16) + si:SetWidth(16) + local tex = si:CreateTexture() + tex:SetAllPoints() + tex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock") + tex:SetBlendMode("ADD") + tex:SetDrawLayer("OVERLAY") + return si +end + +local si1 = CreateSnapIndicator() +local si2 = CreateSnapIndicator() + +local function DisplaySnapIndicator( f, rx, ry, xOff, yOff ) + local o, p, rp, x, y, snap = GetClosestPointSnapped(f, rx, ry, xOff, yOff) + if o then + si1:ClearAllPoints() + si2:ClearAllPoints() + si1:SetPoint("CENTER", f, p, 0, 0) + local xx, yy = pointCoordFuncs[rp](o) + x = math.abs(x) <=rx and xx and 0 or x + y = math.abs(y) <=ry and yy and 0 or y + si2:SetPoint("CENTER", o, rp, x, y) + si1:Show() + si2:Show() + else + if si1:IsVisible() then + si1:Hide() + si2:Hide() + end + end + return o, p +end + +local function HideSnapIndicator() + if si1:IsVisible() then + si1:Hide() + si2:Hide() + end +end + +local function UpdateLabelString(bar) + local label = bar.controlLabelString + if label then + local name = bar.labelName + if name and bar.labelSubtext then + name = format("%s (%s)", name, bar.labelSubtext) + end + label:SetText(name or "") + end +end + +local function CreateControls(bar) + local f = bar:GetFrame() + + f:SetMovable(true) + f:SetResizable(true) + + -- child of UIParent so that alpha and scale doesn't propagate to it + local overlay = CreateFrame("Button", nil, UIParent) + overlay:EnableMouse(true) + overlay:SetFrameLevel(3) -- set it above the buttons + overlay:SetPoint("TOPLEFT", f, "TOPLEFT", -4, 4) + overlay:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 4, -4) + overlay:SetBackdrop({ + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, + tileSize = 16, + edgeSize = 16, + insets = { left = 0, right = 0, top = 0, bottom = 0 }, + }) + + -- textures + local bgTex = overlay:CreateTexture(nil,"BACKGROUND") + bgTex:SetTexture(0.7,0.7,1.0,0.2) + bgTex:SetPoint("TOPLEFT",4,-4) + bgTex:SetPoint("BOTTOMRIGHT",-4,4) + local hTex = overlay:CreateTexture(nil,"HIGHLIGHT") + hTex:SetTexture(0.7,0.7,1.0,0.2) + hTex:SetPoint("TOPLEFT",4,-4) + hTex:SetPoint("BOTTOMRIGHT",-4,4) + hTex:SetBlendMode("ADD") + local aTex = overlay:CreateTexture(nil,"ARTWORK") + aTex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock") + aTex:SetWidth(16) + aTex:SetHeight(16) + aTex:Hide() + + -- label + local label = overlay:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") + label:SetAllPoints() + label:SetJustifyH("CENTER") + label:SetShadowColor(0,0,0,1) + label:SetShadowOffset(3,-3) + label:SetTextColor(GetNormalTextColor()) + label:SetText(bar:GetName()) + label:Show() + bar.controlLabelString = label -- so that bar:SetLabel() can update it + + local function UpdateAnchorDecoration() + local point, anchor, relPoint, x, y = f:GetPoint(1) + if point then + local ofsx, ofsy = insidePointOffsetFuncs[point](x,y) + if (anchor and anchor ~= UIParent) or (ofsx == 0 and ofsy == 0) then + bgTex:SetTexture( GetAnchoredBgColor() ) + hTex:SetTexture( GetAnchoredBgColor() ) + label:SetTextColor( GetAnchoredTextColor() ) + aTex:ClearAllPoints() + aTex:SetPoint(point) + aTex:Show() + return + end + end + bgTex:SetTexture( GetNormalBgColor() ) + hTex:SetTexture( GetNormalBgColor() ) + label:SetTextColor( GetNormalTextColor() ) + aTex:Hide() + end + + local function StopResize() + f:StopMovingOrSizing() + f.isMoving = false + f:SetScript("OnUpdate",nil) + StoreSize(bar) + ClampToButtons(bar) + ReAction:RefreshOptions() + end + + local function CornerUpdate() + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + local ss = GetStateScale(bar) + if IsShiftKeyDown() then + if ss then + f:SetMinResize( ((s+bw)*c*0.25)/ss, ((s+bh)*r*0.25)/ss ) + f:SetMaxResize( ((s+bw)*c*2.5 + 1)/ss, ((s+bh)*r*2.5 + 1)/ss ) + scale = ComputeBarScale(bar) + else + f:SetMinResize( (s+12)*c+1, (s+12)*r+1 ) + f:SetMaxResize( (s+128)*c+1, (s+128)*r+1 ) + RecomputeButtonSize(bar) + end + elseif not ss and IsAltKeyDown() then + f:SetMinResize( bw*c, bh*r ) + f:SetMaxResize( 2*bw*c, 2*bh*r ) + RecomputeButtonSpacing(bar) + else + f:SetMinResize( bw+s+1, bh+s+1 ) + f:SetMaxResize( 50*(bw+s)+1, 50*(bh+s)+1 ) + RecomputeGrid(bar) + end + GameTooltipTextRight2:SetText(format("%d x %d",r,c)) + + local ss = GetStateScale(bar) + local state = bar:GetState() + if ss then + GameTooltipTextRight4:SetText(format("%d%%", scale*100)) + else + local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh) + GameTooltipTextRight3:SetText(size) + GameTooltipTextRight4:SetText(tostring(s)) + end + end + + -- corner drag handles + for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do + local corner = CreateFrame("Frame",nil,overlay) + corner:EnableMouse(true) + corner:SetWidth(16) + corner:SetHeight(16) + corner:SetPoint(point) + + local tex = corner:CreateTexture(nil,"HIGHLIGHT") + tex:SetTexture("Interface\\AddOns\\ReAction\\img\\corner") + tex:SetTexCoord(unpack(cornerTexCoords[point])) + tex:SetBlendMode("ADD") + tex:SetAlpha(0.6) + tex:SetAllPoints() + + corner:SetScript("OnMouseDown", + function(_,btn) + f:SetScript("OnUpdate", CornerUpdate) + f:StartSizing(point) + end + ) + corner:SetScript("OnMouseUp", + function() + local ss = GetStateScale(bar) + if ss then + local state = bar:GetState() + SetStateScale(bar, ComputeBarScale(bar)) + end + StopResize() + end) + corner:SetScript("OnEnter", + function() + local bw, bh = GetButtonSize(bar) + local r, c, s = bar:GetButtonGrid() + local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh) + local ss = GetStateScale(bar) + local state = bar:GetState() + GameTooltip:SetOwner(f, "ANCHOR_"..point) + if ss then + GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state)) + else + GameTooltip:AddLine(bar:GetName()) + end + GameTooltip:AddDoubleLine(format("|cffcccccc%s|r %s",L["Drag"],L["to add/remove buttons:"]), format("%d x %d",r,c)) + if ss then + GameTooltip:AddLine(L["State Scale Override"]) + GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to change scale:"]), format("%d%%", bar:GetStateProperty(state,"scale")*100)) + else + GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to resize buttons:"]), tostring(floor(size))) + GameTooltip:AddDoubleLine(format("|cff0033cc%s|r %s",L["Hold Alt"], L["to change spacing:"]), tostring(floor(s))) + end + GameTooltip:Show() + end + ) + corner:SetScript("OnLeave", + function() + GameTooltip:Hide() + f:SetScript("OnUpdate",nil) + end + ) + end + + overlay:RegisterForDrag("LeftButton") + overlay:RegisterForClicks("RightButtonUp") + + overlay:SetScript("OnDragStart", + function() + f:StartMoving() + f.isMoving = true + local w,h = bar:GetButtonSize() + f:ClearAllPoints() + UpdateAnchorDecoration() + f:SetScript("OnUpdate", function() + if IsShiftKeyDown() then + local f, p = DisplaySnapIndicator(f,w,h) + else + HideSnapIndicator() + end + end) + end + ) + + local function UpdateDragTooltip() + GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT") + local ss = GetStateScale(bar) + local state = bar:GetState() + if ss then + GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state)) + else + GameTooltip:AddLine(bar:GetName()) + end + GameTooltip:AddLine(format("|cffcccccc%s|r %s",L["Drag"],L["to move"])) + GameTooltip:AddLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to anchor to nearby frames"])) + GameTooltip:AddLine(format("|cff00cccc%s|r %s",L["Right-click"],L["for options..."])) + local point, frame, relpoint, x, y = bar:GetFrame():GetPoint(1) + if point then + local ofsx, ofsy = insidePointOffsetFuncs[point](x,y) + if (frame and frame ~= UIParent) or (ofsx == 0 and ofsy == 0) then + frame = frame or UIParent + GameTooltip:AddLine(format("%s <%s>",L["Currently anchored to"],frame:GetName())) + end + end + GameTooltip:Show() + end + + overlay:SetScript("OnDragStop", + function() + f:StopMovingOrSizing() + f.isMoving = false + f:SetScript("OnUpdate",nil) + + if IsShiftKeyDown() then + local w, h = bar:GetButtonSize() + local a, p, rp, x, y = GetClosestPointSnapped(f,w,h) + if a then + f:ClearAllPoints() + f:SetPoint(p,a,rp,x,y) + end + HideSnapIndicator() + end + + StoreExtents(bar) + ReAction:RefreshOptions() + UpdateDragTooltip() + UpdateAnchorDecoration() + end + ) + + overlay:SetScript("OnEnter", + function() + UpdateDragTooltip() + end + ) + + overlay:SetScript("OnLeave", HideGameTooltip) + + overlay:SetScript("OnClick", + function() + ReAction:ShowEditor(bar) + end + ) + + function overlay:LIBKEYBOUND_ENABLED(evt) + self:SetFrameLevel(1) + end + + function overlay:LIBKEYBOUND_DISABLED(evt) + self:SetFrameLevel(3) + end + + function overlay:RefreshControls() + UpdateAnchorDecoration() + end + + overlay:SetScript("OnShow", overlay.RefreshControls) + + KB.RegisterCallback(overlay,"LIBKEYBOUND_ENABLED") + KB.RegisterCallback(overlay,"LIBKEYBOUND_DISABLED") + + if ReAction:GetKeybindMode() then + overlay:SetFrameLevel(1) + end + + bar:SetLabel(bar:GetName()) + UpdateLabelString(bar) + UpdateAnchorDecoration() + + return overlay +end + + +-- export methods to the Bar prototype + +function Bar:ShowControls(show) + local f = self.controlFrame + if show then + if not f then + f = CreateControls(self) + self.controlFrame = f + end + f:Show() + elseif f then + f:Hide() + end +end + +function Bar:RefreshControls() + if self.controlFrame and self.controlFrame:IsShown() then + self.controlFrame:RefreshControls() + end +end + +function Bar:SetLabel(name) + self.labelName = name + UpdateLabelString(self) +end + +function Bar:SetLabelSubtext(text) + self.labelSubtext = text + UpdateLabelString(self) +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/classes.xml Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,10 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd"> + +<Script file="GridProxy.lua"/> +<Script file="Bar.lua"/> +<Script file="Overlay.lua"/> +<Script file="Button.lua"/> + +</Ui> \ No newline at end of file
--- a/modules/Bar.lua Mon Feb 09 19:02:58 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -local ReAction = ReAction -local L = ReAction.L -local _G = _G -local CreateFrame = CreateFrame -local floor = math.floor -local fmod = math.fmod -local format = string.format - -ReAction:UpdateRevision("$Revision$") - -local Bar = { } -local proto = { __index = Bar } -local weak = { __mode = "k" } - -ReAction.Bar = Bar -- export to ReAction - -function Bar:New( name, config ) - if type(config) ~= "table" then - error("ReAction.Bar: config table required") - end - - -- create new self - self = setmetatable( - { - config = config, - name = name, - buttons = setmetatable( { }, weak ), - width = config.width or 480, - height = config.height or 40 - }, - proto ) - - -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is - -- not mouse-clickable by the user. - local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent - local f = CreateFrame("Button", name and format("ReAction-%s",name), parent, - "SecureHandlerStateTemplate, SecureHandlerClickTemplate") - f:SetFrameStrata("MEDIUM") - f:SetWidth(self.width) - f:SetWidth(self.height) - f:SetAlpha(config.alpha or 1.0) - f:Show() - f:EnableMouse(false) - f:SetClampedToScreen(true) - - -- Override the default frame accessor to provide strict read-only access - function self:GetFrame() - return f - end - - self:ApplyAnchor() - ReAction.RegisterCallback(self, "OnConfigModeChanged") - - return self -end - -function Bar:Destroy() - local f = self:GetFrame() - f:UnregisterAllEvents() - ReAction.UnregisterAllCallbacks(self) - f:Hide() - f:SetParent(UIParent) - f:ClearAllPoints() -end - -function Bar:OnConfigModeChanged(event, mode) - self:ShowControls(mode) -- Bar:ShowControls() defined in Overlay.lua -end - -function Bar:ApplyAnchor() - local f = self:GetFrame() - local c = self.config - local p = c.point - - f:SetWidth(c.width) - f:SetHeight(c.height) - f:ClearAllPoints() - - if p then - local a = f:GetParent() - if c.anchor then - local bar = ReAction:GetBar(c.anchor) - if bar then - a = bar:GetFrame() - else - a = _G[c.anchor] - end - end - local fr = a or f:GetParent() - f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0) - else - f:SetPoint("CENTER") - end -end - -function Bar:SetAnchor(point, frame, relativePoint, x, y) - local c = self.config - c.point = point or c.point - c.anchor = frame or c.anchor - c.relpoint = relativePoint or c.relpoint - c.x = x or c.x - c.y = y or c.y - self:ApplyAnchor() - ReAction:RefreshBar(self) -end - -function Bar:GetAnchor() - local c = self.config - return (c.point or "CENTER"), - (c.anchor or self:GetFrame():GetParent():GetName()), - (c.relpoint or c.point or "CENTER"), - (c.x or 0), - (c.y or 0) -end - -function Bar:GetSize() - local f = self:GetFrame() - return f:GetWidth(), f:GetHeight() -end - -function Bar:SetSize(w,h) - local f = self:GetFrame() - self.config.width = w - self.config.height = h - f:SetWidth(w) - f:SetHeight(h) -end - -function Bar:GetButtonSize() - local w = self.config.btnWidth or 32 - local h = self.config.btnHeight or 32 - -- TODO: get from modules? - return w,h -end - -function Bar:SetButtonSize(w,h) - if w > 0 and h > 0 then - self.config.btnWidth = w - self.config.btnHeight = h - end - ReAction:RefreshBar(self) -end - -function Bar:GetButtonGrid() - local cfg = self.config - local r = cfg.btnRows or 1 - local c = cfg.btnColumns or 1 - local s = cfg.spacing or 4 - return r,c,s -end - -function Bar:GetNumButtons() - local r,c = self:GetButtonGrid() - return r*c -end - -function Bar:SetButtonGrid(r,c,s) - if r > 0 and c > 0 and s > 0 then - local cfg = self.config - cfg.btnRows = r - cfg.btnColumns = c - cfg.spacing = s - end - ReAction:RefreshBar(self) -end - -function Bar:ClipNButtons( n ) - local cfg = self.config - local r = cfg.btnRows or 1 - local c = cfg.btnColumns or 1 - - cfg.btnRows = ceil(n/c) - cfg.btnColumns = min(n,c) -end - -function Bar:GetName() - return self.name -end - -function Bar:GetFrame() - -- this method is included for documentation purposes. It is overridden - -- for each object in the :New() method. - error("Invalid Bar object: used without initialization") -end - --- only ReAction:RenameBar() should call this function. Calling from any other --- context will desync the bar list in the ReAction class. -function Bar:SetName(name) - self.name = name - self:SetLabel(self.name) -- Bar:SetLabel() defined in Overlay.lua -end - -function Bar:GetAlpha() - return self.config.alpha or 1.0 -end - -function Bar:SetAlpha(value) - self.config.alpha = value - self:GetFrame():SetAlpha(value or 1.0) - ReAction:RefreshBar(self) -end - -function Bar:AddButton(idx, button) - local f = self:GetFrame() - - -- store in a weak reverse-index array - self.buttons[button] = idx - - -- Store a properly wrapped reference to the child frame as an attribute - -- (accessible via "frameref-btn#") - f:SetFrameRef(format("btn%d",idx), button:GetFrame()) -end - -function Bar:RemoveButton(button) - local idx = self.buttons[button] - if idx then - self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil) - self.buttons[button] = nil - end -end - --- iterator returns button, idx and does NOT iterate in index order -function Bar:IterateButtons() - return pairs(self.buttons) -end - -function Bar:PlaceButton(button, baseW, baseH) - local idx = self.buttons[button] - if idx then - local r, c, s = self:GetButtonGrid() - local bh, bw = self:GetButtonSize() - local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based - local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s) - local scale = bw/baseW - local b = button:GetFrame() - - b:ClearAllPoints() - b:SetPoint("TOPLEFT",x/scale,y/scale) - b:SetScale(scale) - end -end - -function Bar:SkinButton() - -- does nothing by default -end \ No newline at end of file
--- a/modules/Bindings.lua Mon Feb 09 19:02:58 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -local L = ReAction.L -local _G = _G - -_G["BINDING_HEADER_REACTION"] = L["ReAction"] - -_G["BINDING_NAME_REACTION_TOGGLELOCK"] = L["Toggle ReAction Bar Lock"] -_G["BINDING_NAME_REACTION_TOGGLEKEYBIND"] = L["ReAction Keybinding Mode"]
--- a/modules/LDB.lua Mon Feb 09 19:02:58 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -local ReAction = ReAction -local L = ReAction.L -local format = string.format - --- Export ReAction launcher to LibDataBroker-aware displays -LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject( "ReAction", - { - type = "launcher", - icon = "Interface\\Icons\\INV_Qiraj_JewelEncased", - - OnClick = function( frame, button ) - if not InCombatLockdown() then - if IsAltKeyDown() then - ReAction:SetKeybindMode( not ReAction:GetKeybindMode() ) - elseif IsShiftKeyDown() then - ReAction:SetConfigMode( not ReAction:GetConfigMode() ) - elseif button == "RightButton" then - ReAction:ShowEditor() - else - ReAction:ShowConfig() - end - else - ReAction:UserError(L["ReAction: can't configure in combat"]) - end - end, - - -- this isn't included in the 'launcher' type LDB spec but it seems all launcher displays use it - OnTooltipShow = function( tooltip ) - tooltip:AddLine(format("|cffffffff%s|r %s",L["Click"],L["for global configuration"])) - tooltip:AddLine(format("|cffffd200%s|r %s",L["Right-click"],L["for bar editor dialog"])) - tooltip:AddLine(format("|cff00ff00%s|r %s",L["Shift-click"],L["to unlock bars"])) - tooltip:AddLine(format("|cff00cccc%s|r %s",L["Alt-click"],L["for keybind mode"])) - end, - - } -)
--- a/modules/Overlay.lua Mon Feb 09 19:02:58 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,769 +0,0 @@ -local ReAction = ReAction -local L = ReAction.L -local CreateFrame = CreateFrame -local InCombatLockdown = InCombatLockdown -local floor = math.floor -local min = math.min -local format = string.format -local GameTooltip = GameTooltip -local Bar = ReAction.Bar -local GetSize = Bar.GetSize -local SetSize = Bar.SetSize -local GetButtonSize = Bar.GetButtonSize -local GetButtonGrid = Bar.GetButtonGrid -local SetButtonSize = Bar.SetButtonSize -local SetButtonGrid = Bar.SetButtonGrid -local ApplyAnchor = Bar.ApplyAnchor -local GameTooltipTextRight1 = GameTooltipTextRight1 -local GameTooltipTextRight2 = GameTooltipTextRight2 -local GameTooltipTextRight3 = GameTooltipTextRight3 - -local KB = LibStub("LibKeyBound-1.0") - -ReAction:UpdateRevision("$Revision$") - - --- --- Wrap some of the bar manipulators to make them state-aware --- -local function SetAnchor( bar, point, frame, relPoint, x, y ) - local state = bar:GetState() - if state then - local anchorstate = bar:GetStateProperty(state, "anchorEnable") - if anchorstate then - bar:SetStateProperty(state, "anchorFrame", frame) - bar:SetStateProperty(state, "anchorPoint", point) - bar:SetStateProperty(state, "anchorRelPoint", relPoint) - bar:SetStateProperty(state, "anchorX", x or 0) - bar:SetStateProperty(state, "anchorY", y or 0) - bar:SetAnchor(bar:GetAnchor()) - return - end - end - bar:SetAnchor(point, frame, relPoint, x, y) -end - -local function GetStateScale( bar ) - local state = bar:GetState() - if state and bar:GetStateProperty(state, "enableScale") then - return bar:GetStateProperty(state, "scale") - end -end - -local function SetStateScale( bar, scale ) - local state = bar:GetState() - if state and bar:GetStateProperty(state, "enableScale") then - bar:SetStateProperty(state, "scale", scale) - end -end - - --- --- Bar config overlay --- - -local function GetNormalTextColor() - return 1.0, 1.0, 1.0, 1.0 -end - -local function GetAnchoredTextColor() - return 1.0, 1.0, 1.0, 1.0 -end - -local function GetNormalBgColor() - return 0.7, 0.7, 1.0, 0.3 -end - -local function GetAnchoredBgColor() - return 0.9, 0.2, 0.7, 0.3 -end - -local function StoreSize(bar) - local f = bar:GetFrame() - SetSize( bar, f:GetWidth(), f:GetHeight() ) -end - -local function StoreExtents(bar) - local f = bar:GetFrame() - local p, fr, rp, x, y = f:GetPoint(1) - fr = fr and fr:GetName() or "UIParent" - SetAnchor( bar, p, fr, rp, x, y ) - SetSize( bar, f:GetWidth(), f:GetHeight() ) -end - -local function RecomputeButtonSize(bar) - local w, h = GetSize(bar) - local bw, bh = GetButtonSize(bar) - local r, c, s = GetButtonGrid(bar) - - local scaleW = (floor(w/c) - s) / bw - local scaleH = (floor(h/r) - s) / bh - local scale = min(scaleW, scaleH) - - SetButtonSize(bar, scale * bw, scale * bh, s) -end - -local function ComputeBarScale(bar) - local w, h = bar.controlFrame:GetWidth() - 8, bar.controlFrame:GetHeight() - 8 - local bw, bh = GetButtonSize(bar) - local r, c, s = GetButtonGrid(bar) - - local scaleW = w / (c*(bw+s)) - local scaleH = h / (r*(bh+s)) - local scale = min(scaleW, scaleH) - - if scale > 2.5 then - scale = 2.5 - elseif scale < 0.25 then - scale = 0.25 - end - - return scale -end - -local function RecomputeButtonSpacing(bar) - local w, h = GetSize(bar) - local bw, bh = GetButtonSize(bar) - local r, c, s = GetButtonGrid(bar) - - SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh)) -end - -local function RecomputeGrid(bar) - local w, h = GetSize(bar) - local bw, bh = GetButtonSize(bar) - local r, c, s = GetButtonGrid(bar) - - SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s) -end - -local function ClampToButtons(bar) - local bw, bh = GetButtonSize(bar) - local r, c, s = GetButtonGrid(bar) - SetSize(bar, (bw+s)*c + 1, (bh+s)*r + 1) -end - -local function HideGameTooltip() - GameTooltip:Hide() -end - -local anchorInside = { inside = true } -local anchorOutside = { outside = true } -local edges = { "BOTTOM", "TOP", "LEFT", "RIGHT" } -local oppositeEdges = { - TOP = "BOTTOM", - BOTTOM = "TOP", - LEFT = "RIGHT", - RIGHT = "LEFT" -} -local pointsOnEdge = { - BOTTOM = { "BOTTOM", "BOTTOMLEFT", "BOTTOMRIGHT", }, - TOP = { "TOP", "TOPLEFT", "TOPRIGHT", }, - RIGHT = { "RIGHT", "BOTTOMRIGHT", "TOPRIGHT", }, - LEFT = { "LEFT", "BOTTOMLEFT", "TOPLEFT", }, -} -local edgeSelector = { - BOTTOM = 1, -- select x of x,y - TOP = 1, -- select x of x,y - LEFT = 2, -- select y of x,y - RIGHT = 2, -- select y of x,y -} -local snapPoints = { - [anchorOutside] = { - BOTTOMLEFT = {"BOTTOMRIGHT","TOPLEFT","TOPRIGHT"}, - BOTTOM = {"TOP"}, - BOTTOMRIGHT = {"BOTTOMLEFT","TOPRIGHT","TOPLEFT"}, - RIGHT = {"LEFT"}, - TOPRIGHT = {"TOPLEFT","BOTTOMRIGHT","BOTTOMLEFT"}, - TOP = {"BOTTOM"}, - TOPLEFT = {"TOPRIGHT","BOTTOMLEFT","BOTTOMRIGHT"}, - LEFT = {"RIGHT"}, - CENTER = {"CENTER"} - }, - [anchorInside] = { - BOTTOMLEFT = {"BOTTOMLEFT"}, - BOTTOM = {"BOTTOM"}, - BOTTOMRIGHT = {"BOTTOMRIGHT"}, - RIGHT = {"RIGHT"}, - TOPRIGHT = {"TOPRIGHT"}, - TOP = {"TOP"}, - TOPLEFT = {"TOPLEFT"}, - LEFT = {"LEFT"}, - CENTER = {"CENTER"} - } -} -local insidePointOffsetFuncs = { - BOTTOMLEFT = function(x, y) return x, y end, - BOTTOM = function(x, y) return 0, y end, - BOTTOMRIGHT = function(x, y) return -x, y end, - RIGHT = function(x, y) return -x, 0 end, - TOPRIGHT = function(x, y) return -x, -y end, - TOP = function(x, y) return 0, -y end, - TOPLEFT = function(x, y) return x, -y end, - LEFT = function(x, y) return x, 0 end, - CENTER = function(x, y) return x, y end, -} -local pointCoordFuncs = { - BOTTOMLEFT = function(f) return f:GetLeft(), f:GetBottom() end, - BOTTOM = function(f) return nil, f:GetBottom() end, - BOTTOMRIGHT = function(f) return f:GetRight(), f:GetBottom() end, - RIGHT = function(f) return f:GetRight(), nil end, - TOPRIGHT = function(f) return f:GetRight(), f:GetTop() end, - TOP = function(f) return nil, f:GetTop() end, - TOPLEFT = function(f) return f:GetLeft(), f:GetTop() end, - LEFT = function(f) return f:GetLeft(), nil end, - CENTER = function(f) return f:GetCenter() end, -} -local edgeBoundsFuncs = { - BOTTOM = function(f) return f:GetLeft(), f:GetRight() end, - LEFT = function(f) return f:GetBottom(), f:GetTop() end -} -edgeBoundsFuncs.TOP = edgeBoundsFuncs.BOTTOM -edgeBoundsFuncs.RIGHT = edgeBoundsFuncs.LEFT -local cornerTexCoords = { - -- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy - TOPLEFT = { 1, 1, 1, 0, 0, 1, 0, 0 }, - TOPRIGHT = { 1, 0, 0, 0, 1, 1, 0, 1 }, - BOTTOMLEFT = { 0, 1, 1, 1, 0, 0, 1, 0 }, - BOTTOMRIGHT = { 0, 0, 0, 1, 1, 0, 1, 1 }, -} - --- Returns absolute coordinates x,y of the named point 'p' of frame 'f' -local function GetPointCoords( f, p ) - local x, y = pointCoordFuncs[p](f) - if not(x and y) then - local cx, cy = f:GetCenter() - x = x or cx - y = y or cy - end - return x, y -end - - --- Returns true if frame 'f1' can be anchored to frame 'f2' -local function CheckAnchorable( f1, f2 ) - -- can't anchor a frame to itself or to nil - if f1 == f2 or f2 == nil then - return false - end - - -- can always anchor to UIParent - if f2 == UIParent then - return true - end - - -- also can't do circular anchoring of frames - -- walk the anchor chain, which generally shouldn't be that expensive - -- (who nests draggables that deep anyway?) - for i = 1, f2:GetNumPoints() do - local _, f = f2:GetPoint(i) - if not f then f = f2:GetParent() end - return CheckAnchorable(f1,f) - end - - return true -end - --- Returns true if frames f1 and f2 specified edges overlap -local function CheckEdgeOverlap( f1, f2, e ) - local l1, u1 = edgeBoundsFuncs[e](f1) - local l2, u2 = edgeBoundsFuncs[e](f2) - return l1 <= l2 and l2 <= u1 or l2 <= l1 and l1 <= u2 -end - --- Returns true if point p1 on frame f1 overlaps edge e2 on frame f2 -local function CheckPointEdgeOverlap( f1, p1, f2, e2 ) - local l, u = edgeBoundsFuncs[e2](f2) - local x, y = GetPointCoords(f1,p1) - x = select(edgeSelector[e2], x, y) - return l <= x and x <= u -end - --- Returns the distance between corresponding edges. It is --- assumed that the passed in edges e1 and e2 are the same or opposites -local function GetEdgeDistance( f1, f2, e1, e2 ) - local x1, y1 = pointCoordFuncs[e1](f1) - local x2, y2 = pointCoordFuncs[e2](f2) - return math.abs((x1 or y1) - (x2 or y2)) -end - -local globalSnapTargets = { [UIParent] = anchorInside } - -local function GetClosestFrameEdge(f1,f2,a) - local dist, edge, opp - if f2:IsVisible() and CheckAnchorable(f1,f2) then - for _, e in pairs(edges) do - local o = a.inside and e or oppositeEdges[e] - if CheckEdgeOverlap(f1,f2,e) then - local d = GetEdgeDistance(f1, f2, e, o) - if not dist or (d < dist) then - dist, edge, opp = d, e, o - end - end - end - end - return dist, edge, opp -end - -local function GetClosestVisibleEdge( f ) - local r, o, e1, e2 - local a = anchorOutside - for _, b in ReAction:IterateBars() do - local d, e, opp = GetClosestFrameEdge(f,b:GetFrame(),a) - if d and (not r or d < r) then - r, o, e1, e2 = d, b:GetFrame(), e, opp - end - end - for f2, a2 in pairs(globalSnapTargets) do - local d, e, opp = GetClosestFrameEdge(f,f2,a2) - if d and (not r or d < r) then - r, o, e1, e2, a = d, f2, e, opp, a2 - end - end - return o, e1, e2, a -end - -local function GetClosestVisiblePoint(f1) - local f2, e1, e2, a = GetClosestVisibleEdge(f1) - if f2 then - local rsq, p, rp, x, y - -- iterate pointsOnEdge in order and use < to prefer edge centers to corners - for _, p1 in ipairs(pointsOnEdge[e1]) do - if CheckPointEdgeOverlap(f1,p1,f2,e2) then - for _, p2 in pairs(snapPoints[a][p1]) do - local x1, y1 = GetPointCoords(f1,p1) - local x2, y2 = GetPointCoords(f2,p2) - local dx = x1 - x2 - local dy = y1 - y2 - local rsq2 = dx*dx + dy*dy - if not rsq or rsq2 < rsq then - rsq, p, rp, x, y = rsq2, p1, p2, dx, dy - end - end - end - end - return f2, p, rp, x, y - end -end - -local function GetClosestPointSnapped(f1, rx, ry, xOff, yOff) - local o, p, rp, x, y = GetClosestVisiblePoint(f1) - local s = false - - local insideOffsetFunc = p and insidePointOffsetFuncs[p] - local coordFunc = p and pointCoordFuncs[p] - if not insideOffsetFunc or not coordFunc then - return - end - - local sx, sy = insideOffsetFunc(xOff or 0, yOff or 0) - local xx, yy = coordFunc(f1) - if xx and yy then - if math.abs(x) <= rx then - if math.abs(y) <= ry then - x = sx - y = sy - s = true - elseif CheckEdgeOverlap(f1,o,"LEFT") then - x = sx - s = true - end - elseif math.abs(y) <= ry and CheckEdgeOverlap(f1,o,"TOP") then - y = sy - s = true - end - elseif xx then - if math.abs(x) <= rx then - x = sx - s = true - if math.abs(y) <= ry then - y = sy - end - end - elseif yy then - if math.abs(y) <= ry then - y = sy - s = true - if math.abs(x) <= rx then - x = sx - end - end - end - - -- correct for some Lua oddities with doubles - if x == -0 then x = 0 end - if y == -0 then y = 0 end - - if s then - return o, p, rp, math.floor(x), math.floor(y) - end -end - -local function CreateSnapIndicator() - local si = CreateFrame("Frame",nil,UIParent) - si:SetFrameStrata("HIGH") - si:SetHeight(16) - si:SetWidth(16) - local tex = si:CreateTexture() - tex:SetAllPoints() - tex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock") - tex:SetBlendMode("ADD") - tex:SetDrawLayer("OVERLAY") - return si -end - -local si1 = CreateSnapIndicator() -local si2 = CreateSnapIndicator() - -local function DisplaySnapIndicator( f, rx, ry, xOff, yOff ) - local o, p, rp, x, y, snap = GetClosestPointSnapped(f, rx, ry, xOff, yOff) - if o then - si1:ClearAllPoints() - si2:ClearAllPoints() - si1:SetPoint("CENTER", f, p, 0, 0) - local xx, yy = pointCoordFuncs[rp](o) - x = math.abs(x) <=rx and xx and 0 or x - y = math.abs(y) <=ry and yy and 0 or y - si2:SetPoint("CENTER", o, rp, x, y) - si1:Show() - si2:Show() - else - if si1:IsVisible() then - si1:Hide() - si2:Hide() - end - end - return o, p -end - -local function HideSnapIndicator() - if si1:IsVisible() then - si1:Hide() - si2:Hide() - end -end - -local function UpdateLabelString(bar) - local label = bar.controlLabelString - if label then - local name = bar.labelName - if name and bar.labelSubtext then - name = format("%s (%s)", name, bar.labelSubtext) - end - label:SetText(name or "") - end -end - -local function CreateControls(bar) - local f = bar:GetFrame() - - f:SetMovable(true) - f:SetResizable(true) - - -- child of UIParent so that alpha and scale doesn't propagate to it - local overlay = CreateFrame("Button", nil, UIParent) - overlay:EnableMouse(true) - overlay:SetFrameLevel(3) -- set it above the buttons - overlay:SetPoint("TOPLEFT", f, "TOPLEFT", -4, 4) - overlay:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 4, -4) - overlay:SetBackdrop({ - edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = true, - tileSize = 16, - edgeSize = 16, - insets = { left = 0, right = 0, top = 0, bottom = 0 }, - }) - - -- textures - local bgTex = overlay:CreateTexture(nil,"BACKGROUND") - bgTex:SetTexture(0.7,0.7,1.0,0.2) - bgTex:SetPoint("TOPLEFT",4,-4) - bgTex:SetPoint("BOTTOMRIGHT",-4,4) - local hTex = overlay:CreateTexture(nil,"HIGHLIGHT") - hTex:SetTexture(0.7,0.7,1.0,0.2) - hTex:SetPoint("TOPLEFT",4,-4) - hTex:SetPoint("BOTTOMRIGHT",-4,4) - hTex:SetBlendMode("ADD") - local aTex = overlay:CreateTexture(nil,"ARTWORK") - aTex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock") - aTex:SetWidth(16) - aTex:SetHeight(16) - aTex:Hide() - - -- label - local label = overlay:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") - label:SetAllPoints() - label:SetJustifyH("CENTER") - label:SetShadowColor(0,0,0,1) - label:SetShadowOffset(3,-3) - label:SetTextColor(GetNormalTextColor()) - label:SetText(bar:GetName()) - label:Show() - bar.controlLabelString = label -- so that bar:SetLabel() can update it - - local function UpdateAnchorDecoration() - local point, anchor, relPoint, x, y = f:GetPoint(1) - if point then - local ofsx, ofsy = insidePointOffsetFuncs[point](x,y) - if (anchor and anchor ~= UIParent) or (ofsx == 0 and ofsy == 0) then - bgTex:SetTexture( GetAnchoredBgColor() ) - hTex:SetTexture( GetAnchoredBgColor() ) - label:SetTextColor( GetAnchoredTextColor() ) - aTex:ClearAllPoints() - aTex:SetPoint(point) - aTex:Show() - return - end - end - bgTex:SetTexture( GetNormalBgColor() ) - hTex:SetTexture( GetNormalBgColor() ) - label:SetTextColor( GetNormalTextColor() ) - aTex:Hide() - end - - local function StopResize() - f:StopMovingOrSizing() - f.isMoving = false - f:SetScript("OnUpdate",nil) - StoreSize(bar) - ClampToButtons(bar) - ReAction:RefreshOptions() - end - - local function CornerUpdate() - local bw, bh = GetButtonSize(bar) - local r, c, s = GetButtonGrid(bar) - local ss = GetStateScale(bar) - if IsShiftKeyDown() then - if ss then - f:SetMinResize( ((s+bw)*c*0.25)/ss, ((s+bh)*r*0.25)/ss ) - f:SetMaxResize( ((s+bw)*c*2.5 + 1)/ss, ((s+bh)*r*2.5 + 1)/ss ) - scale = ComputeBarScale(bar) - else - f:SetMinResize( (s+12)*c+1, (s+12)*r+1 ) - f:SetMaxResize( (s+128)*c+1, (s+128)*r+1 ) - RecomputeButtonSize(bar) - end - elseif not ss and IsAltKeyDown() then - f:SetMinResize( bw*c, bh*r ) - f:SetMaxResize( 2*bw*c, 2*bh*r ) - RecomputeButtonSpacing(bar) - else - f:SetMinResize( bw+s+1, bh+s+1 ) - f:SetMaxResize( 50*(bw+s)+1, 50*(bh+s)+1 ) - RecomputeGrid(bar) - end - GameTooltipTextRight2:SetText(format("%d x %d",r,c)) - - local ss = GetStateScale(bar) - local state = bar:GetState() - if ss then - GameTooltipTextRight4:SetText(format("%d%%", scale*100)) - else - local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh) - GameTooltipTextRight3:SetText(size) - GameTooltipTextRight4:SetText(tostring(s)) - end - end - - -- corner drag handles - for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do - local corner = CreateFrame("Frame",nil,overlay) - corner:EnableMouse(true) - corner:SetWidth(16) - corner:SetHeight(16) - corner:SetPoint(point) - - local tex = corner:CreateTexture(nil,"HIGHLIGHT") - tex:SetTexture("Interface\\AddOns\\ReAction\\img\\corner") - tex:SetTexCoord(unpack(cornerTexCoords[point])) - tex:SetBlendMode("ADD") - tex:SetAlpha(0.6) - tex:SetAllPoints() - - corner:SetScript("OnMouseDown", - function(_,btn) - f:SetScript("OnUpdate", CornerUpdate) - f:StartSizing(point) - end - ) - corner:SetScript("OnMouseUp", - function() - local ss = GetStateScale(bar) - if ss then - local state = bar:GetState() - SetStateScale(bar, ComputeBarScale(bar)) - end - StopResize() - end) - corner:SetScript("OnEnter", - function() - local bw, bh = GetButtonSize(bar) - local r, c, s = bar:GetButtonGrid() - local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh) - local ss = GetStateScale(bar) - local state = bar:GetState() - GameTooltip:SetOwner(f, "ANCHOR_"..point) - if ss then - GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state)) - else - GameTooltip:AddLine(bar:GetName()) - end - GameTooltip:AddDoubleLine(format("|cffcccccc%s|r %s",L["Drag"],L["to add/remove buttons:"]), format("%d x %d",r,c)) - if ss then - GameTooltip:AddLine(L["State Scale Override"]) - GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to change scale:"]), format("%d%%", bar:GetStateProperty(state,"scale")*100)) - else - GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to resize buttons:"]), tostring(floor(size))) - GameTooltip:AddDoubleLine(format("|cff0033cc%s|r %s",L["Hold Alt"], L["to change spacing:"]), tostring(floor(s))) - end - GameTooltip:Show() - end - ) - corner:SetScript("OnLeave", - function() - GameTooltip:Hide() - f:SetScript("OnUpdate",nil) - end - ) - end - - overlay:RegisterForDrag("LeftButton") - overlay:RegisterForClicks("RightButtonUp") - - overlay:SetScript("OnDragStart", - function() - f:StartMoving() - f.isMoving = true - local w,h = bar:GetButtonSize() - f:ClearAllPoints() - UpdateAnchorDecoration() - f:SetScript("OnUpdate", function() - if IsShiftKeyDown() then - local f, p = DisplaySnapIndicator(f,w,h) - else - HideSnapIndicator() - end - end) - end - ) - - local function UpdateDragTooltip() - GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT") - local ss = GetStateScale(bar) - local state = bar:GetState() - if ss then - GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state)) - else - GameTooltip:AddLine(bar:GetName()) - end - GameTooltip:AddLine(format("|cffcccccc%s|r %s",L["Drag"],L["to move"])) - GameTooltip:AddLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to anchor to nearby frames"])) - GameTooltip:AddLine(format("|cff00cccc%s|r %s",L["Right-click"],L["for options..."])) - local point, frame, relpoint, x, y = bar:GetFrame():GetPoint(1) - if point then - local ofsx, ofsy = insidePointOffsetFuncs[point](x,y) - if (frame and frame ~= UIParent) or (ofsx == 0 and ofsy == 0) then - frame = frame or UIParent - GameTooltip:AddLine(format("%s <%s>",L["Currently anchored to"],frame:GetName())) - end - end - GameTooltip:Show() - end - - overlay:SetScript("OnDragStop", - function() - f:StopMovingOrSizing() - f.isMoving = false - f:SetScript("OnUpdate",nil) - - if IsShiftKeyDown() then - local w, h = bar:GetButtonSize() - local a, p, rp, x, y = GetClosestPointSnapped(f,w,h) - if a then - f:ClearAllPoints() - f:SetPoint(p,a,rp,x,y) - end - HideSnapIndicator() - end - - StoreExtents(bar) - ReAction:RefreshOptions() - UpdateDragTooltip() - UpdateAnchorDecoration() - end - ) - - overlay:SetScript("OnEnter", - function() - UpdateDragTooltip() - end - ) - - overlay:SetScript("OnLeave", HideGameTooltip) - - overlay:SetScript("OnClick", - function() - ReAction:ShowEditor(bar) - end - ) - - function overlay:LIBKEYBOUND_ENABLED(evt) - self:SetFrameLevel(1) - end - - function overlay:LIBKEYBOUND_DISABLED(evt) - self:SetFrameLevel(3) - end - - function overlay:RefreshControls() - UpdateAnchorDecoration() - end - - overlay:SetScript("OnShow", overlay.RefreshControls) - - KB.RegisterCallback(overlay,"LIBKEYBOUND_ENABLED") - KB.RegisterCallback(overlay,"LIBKEYBOUND_DISABLED") - - if ReAction:GetKeybindMode() then - overlay:SetFrameLevel(1) - end - - bar:SetLabel(bar:GetName()) - UpdateLabelString(bar) - UpdateAnchorDecoration() - - return overlay -end - - --- export methods to the Bar prototype - -function Bar:ShowControls(show) - local f = self.controlFrame - if show then - if not f then - f = CreateControls(self) - self.controlFrame = f - end - f:Show() - elseif f then - f:Hide() - end -end - -function Bar:RefreshControls() - if self.controlFrame and self.controlFrame:IsShown() then - self.controlFrame:RefreshControls() - end -end - -function Bar:SetLabel(name) - self.labelName = name - UpdateLabelString(self) -end - -function Bar:SetLabelSubtext(text) - self.labelSubtext = text - UpdateLabelString(self) -end
--- a/modules/modules.xml Mon Feb 09 19:02:58 2009 +0000 +++ b/modules/modules.xml Mon Feb 23 18:56:57 2009 +0000 @@ -2,12 +2,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd"> -<Script file="bindings.lua"/> -<Script file="Bar.lua"/> -<Script file="Overlay.lua"/> <Script file="ConfigUI.lua"/> <Script file="State.lua"/> -<Script file="LDB.lua"/> <Script file="LBF.lua"/> <Script file="HideBlizzard.lua"/> <Script file="Action.lua"/>