Mercurial > wow > reaction
diff Bar.lua @ 33:c54c481ad0ed
- Moved bar control frame from ConfigUI to Bar
- Added LICENSE.txt
- added profile management options
- other minor cleanup
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Thu, 03 Apr 2008 20:25:40 +0000 |
parents | 0d95ce7a9ec2 |
children | c3c64e2def50 |
line wrap: on
line diff
--- a/Bar.lua Thu Apr 03 16:59:16 2008 +0000 +++ b/Bar.lua Thu Apr 03 20:25:40 2008 +0000 @@ -2,9 +2,16 @@ local L = ReAction.L local _G = _G local CreateFrame = CreateFrame +local InCombatLockdown = InCombatLockdown +local floor = math.floor +local min = math.min +local format = string.format +local GameTooltip = GameTooltip + + -- update ReAction revision if this file is newer -local revision = tonumber(("$Revision: 1 $"):match("%d+")) +local revision = tonumber(("$Revision$"):match("%d+")) if revision > ReAction.revision then Reaction.revision = revision end @@ -112,6 +119,13 @@ return self.name end +function Bar:SetName(name) + self.name = name + if self.controlLabelString then + self.controlLabelString:SetText(self.name) + end +end + function Bar:PlaceButton(f, idx, baseW, baseH) local r, c, s = self:GetButtonGrid() local bh, bw = self:GetButtonSize() @@ -127,6 +141,378 @@ + + + + +-- +-- Bar config overlay +-- +local StoreExtents, RecomputeButtonSize, RecomputeButtonSpacing, RecomputeGrid, ClampToButtons, HideGameTooltip, CreateControls + +do + -- upvalue some of these for small OnUpdate performance boost + local GetSize = Bar.GetSize + local GetButtonSize = Bar.GetButtonSize + local GetButtonGrid = Bar.GetButtonGrid + local SetSize = Bar.SetSize + local SetButtonSize = Bar.SetButtonSize + local SetButtonGrid = Bar.SetButtonGrid + local ApplyAnchor = Bar.ApplyAnchor + + StoreExtents = function(bar) + local f = bar.frame + local point, relativeTo, relativePoint, x, y = f:GetPoint(1) + relativeTo = relativeTo or f:GetParent() + local anchorTo + for name, b in pairs(ReAction.bars) do + if b then + if b:GetFrame() == relativeTo then + anchorTo = name + break + end + end + end + anchorTo = anchorTo or relativeTo:GetName() + local c = bar.config + c.anchor = point + c.anchorTo = anchorTo + c.relativePoint = relativePoint + c.x = x + c.y = y + c.width, c.height = f:GetWidth(), f:GetHeight() + end + + RecomputeButtonSize = function(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 + + RecomputeButtonSpacing = function(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 + + RecomputeGrid = function(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 + + ClampToButtons = function(bar) + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + SetSize(bar, (bw+s)*c, (bh+s)*r ) + end + + HideGameTooltip = function() + GameTooltip:Hide() + end + + CreateControls = function(bar) + local f = bar.frame + + f:SetMovable(true) + f:SetResizable(true) + f:SetClampedToScreen(true) + + -- buttons on the bar should be direct children of the bar frame. + -- The control elements need to float on top of this, which we could + -- do with SetFrameLevel() or Raise(), but it's more reliable to do it + -- via frame nesting, hence good old foo's appearance here. + local foo = CreateFrame("Frame",nil,f) + foo:SetAllPoints() + + local control = CreateFrame("Button", nil, foo) + control:EnableMouse(true) + control:SetToplevel(true) + control:SetPoint("TOPLEFT", -4, 4) + control:SetPoint("BOTTOMRIGHT", 4, -4) + control: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 = control: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 = control: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") + + -- label + local label = control:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") + label:SetAllPoints() + label:SetJustifyH("CENTER") + label:SetShadowColor(0,0,0,1) + label:SetShadowOffset(2,-2) + label:SetTextColor(1,1,1,1) + label:SetText(bar:GetName()) + label:Show() + bar.controlLabelString = label -- so that bar:SetName() can update it + + local StopResize = function() + f:StopMovingOrSizing() + f.isMoving = false + f:SetScript("OnUpdate",nil) + StoreExtents(bar) + ClampToButtons(bar) + ApplyAnchor(bar) + end + + -- edge drag handles + for _, point in pairs({"LEFT","TOP","RIGHT","BOTTOM"}) do + local edge = CreateFrame("Frame",nil,control) + edge:EnableMouse(true) + edge:SetWidth(8) + edge:SetHeight(8) + if point == "TOP" or point == "BOTTOM" then + edge:SetPoint(point.."LEFT") + edge:SetPoint(point.."RIGHT") + else + edge:SetPoint("TOP"..point) + edge:SetPoint("BOTTOM"..point) + end + local tex = edge:CreateTexture(nil,"HIGHLIGHT") + tex:SetTexture(1.0,0.82,0,0.7) + tex:SetBlendMode("ADD") + tex:SetAllPoints() + edge:RegisterForDrag("LeftButton") + edge:SetScript("OnMouseDown", + function() + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + f:SetMinResize( bw+s+1, bh+s+1 ) + f:StartSizing(point) + f:SetScript("OnUpdate", + function() + RecomputeGrid(bar) + bar:RefreshLayout() + end + ) + end + ) + edge:SetScript("OnMouseUp", StopResize) + edge:SetScript("OnEnter", + function() + GameTooltip:SetOwner(f, "ANCHOR_"..point) + GameTooltip:AddLine(L["Drag to add/remove buttons"]) + GameTooltip:Show() + end + ) + edge:SetScript("OnLeave", HideGameTooltip) + edge:Show() + end + + -- corner drag handles, again nested in an anonymous frame so that they are on top + local foo2 = CreateFrame("Frame",nil,control) + foo2:SetAllPoints(true) + for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do + local corner = CreateFrame("Frame",nil,foo2) + corner:EnableMouse(true) + corner:SetWidth(12) + corner:SetHeight(12) + corner:SetPoint(point) + local tex = corner:CreateTexture(nil,"HIGHLIGHT") + tex:SetTexture(1.0,0.82,0,0.7) + tex:SetBlendMode("ADD") + tex:SetAllPoints() + corner:RegisterForDrag("LeftButton","RightButton") + local updateTooltip = function() + local size, size2 = bar:GetButtonSize() + local rows, cols, spacing = bar:GetButtonGrid() + size = (size == size2) and tostring(size) or format("%dx%d",size,size2) + GameTooltipTextRight4:SetText(size) + GameTooltipTextRight5:SetText(tostring(spacing)) + end + corner:SetScript("OnMouseDown", + function(_,btn) + local bw, bh = GetButtonSize(bar) + local r, c, s = GetButtonGrid(bar) + if btn == "LeftButton" then -- button resize + f:SetMinResize( (s+12)*c+1, (s+12)*r+1 ) + f:SetScript("OnUpdate", + function() + RecomputeButtonSize(bar) + bar:RefreshLayout() + updateTooltip() + end + ) + elseif btn == "RightButton" then -- spacing resize + f:SetMinResize( bw*c, bh*r ) + f:SetScript("OnUpdate", + function() + RecomputeButtonSpacing(bar) + bar:RefreshLayout() + updateTooltip() + end + ) + end + f:StartSizing(point) + end + ) + corner:SetScript("OnMouseUp",StopResize) + corner:SetScript("OnEnter", + function() + GameTooltip:SetOwner(f, "ANCHOR_"..point) + GameTooltip:AddLine(L["Drag to resize buttons"]) + GameTooltip:AddLine(L["Right-click-drag"]) + GameTooltip:AddLine(L["to change spacing"]) + local size, size2 = bar:GetButtonSize() + local rows, cols, spacing = bar:GetButtonGrid() + size = (size == size2) and tostring(size) or format("%dx%d",size,size2) + GameTooltip:AddDoubleLine(L["Size:"], size) + GameTooltip:AddDoubleLine(L["Spacing:"], tostring(spacing)) + GameTooltip:Show() + end + ) + corner:SetScript("OnLeave", + function() + GameTooltip:Hide() + f:SetScript("OnUpdate",nil) + end + ) + + end + + control:RegisterForDrag("LeftButton") + control:RegisterForClicks("RightButtonDown") + + control:SetScript("OnDragStart", + function() + f:StartMoving() + f.isMoving = true + -- TODO: snap indicator update install + end + ) + + control:SetScript("OnDragStop", + function() + f:StopMovingOrSizing() + f.isMoving = false + f:SetScript("OnUpdate",nil) + -- TODO: snap frame here + StoreExtents(bar) + end + ) + + control:SetScript("OnEnter", + function() + -- add bar type and status information to name + local name = bar.name + for _, m in ReAction:IterateModules() do + --[[ + local suffix = safecall(m,"GetBarNameModifier",bar) + if suffix then + name = ("%s %s"):format(name,suffix) + end + --]] + end + + GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT") + GameTooltip:AddLine(name) + GameTooltip:AddLine(L["Drag to move"]) + --GameTooltip:AddLine(L["Shift-drag for sticky mode"]) + GameTooltip:AddLine(L["Right-click for options"]) + GameTooltip:Show() + end + ) + + control:SetScript("OnLeave", HideGameTooltip) + + control:SetScript("OnClick", + function() + bar:ShowMenu() + end + ) + + return control + end +end + + +local OpenMenu, CloseMenu +do + -- Looking for a lightweight AceConfig3-struct-compatible + -- replacement for Dewdrop, encapsulate here + -- Considering Blizzard's EasyMenu/UIDropDownMenu, but that's + -- a bit tricky to convert from AceConfig3-struct + local Dewdrop = AceLibrary("Dewdrop-2.0") + OpenMenu = function(frame, opts) + Dewdrop:Open(frame, "children", opts, "cursorX", true, "cursorY", true) + end + CloseMenu = function(frame) + if Dewdrop:GetOpenedParent() == frame then + Dewdrop:Close() + end + end +end + + +function Bar:ShowControls(show) + if show then + if not self.controlFrame then + self.controlFrame = CreateControls(self) + end + self.controlFrame:Show() + elseif self.controlFrame then + CloseMenu(self.controlFrame) + self.controlFrame:Hide() + end +end + +function Bar:ShowMenu() + if not self.menuOpts then + self.menuOpts = { + type = "group", + args = { + --[[ + openConfig = { + type = "execute", + name = L["Configure..."], + desc = L["Open the configuration dialogue for this bar"], + func = function() CloseMenu(self.controlFrame); module:OpenConfig(self) end, + disabled = InCombatLockdown, + order = 1 + }, + --]] + delete = { + type = "execute", + name = L["Delete Bar"], + desc = L["Remove the bar from the current profile"], + func = function() ReAction:EraseBar(self) end, + order = 2 + }, + } + } + end + if self.modMenuOpts == nil then + self.modMenuOpts = { } + end + OpenMenu(self.controlFrame, self.menuOpts) +end + + + ------ Export as a class-factory ------ ReAction.Bar = { prototype = Bar,