Nenue@54
|
1 -- Veneer
|
Nenue@71
|
2 -- Base framework for making things draggable.
|
Nenue@0
|
3
|
Nenue@84
|
4
|
Nenue@84
|
5
|
Nenue@84
|
6
|
Nenue@84
|
7 SLASH_VENEER1 = "/veneer"
|
Nenue@84
|
8 SLASH_VENEER2 = "/vn"
|
Nenue@84
|
9
|
Nenue@84
|
10 SlashCmdList.VENEER = function(cmd)
|
Nenue@84
|
11 end
|
Nenue@84
|
12 VeneerCore = {
|
Nenue@84
|
13 Frames = {},
|
Nenue@84
|
14 ConfigLayers = {},
|
Nenue@84
|
15 FrameClusters = {},
|
Nenue@84
|
16 parserDepth = 0,
|
Nenue@84
|
17 pendingCalls = {},
|
Nenue@84
|
18 }
|
Nenue@84
|
19 VeneerHandlerMixin = {
|
Nenue@84
|
20 Reanchor = nop
|
Nenue@84
|
21 }
|
Nenue@84
|
22 local print = DEVIAN_WORKSPACE and function(...) print('Veneer', ...) end or nop
|
Nenue@80
|
23 local wipe = table.wipe
|
Nenue@0
|
24
|
Nenue@59
|
25 local defaults = {
|
Nenue@59
|
26 enableAll = true,
|
Nenue@59
|
27 enableModule = {
|
Nenue@59
|
28 BuffFrame = true,
|
Nenue@59
|
29 },
|
Nenue@59
|
30 BuffFrame = {
|
Nenue@59
|
31 width = 48,
|
Nenue@59
|
32 height = 48,
|
Nenue@59
|
33 }
|
Nenue@59
|
34 }
|
Nenue@84
|
35
|
Nenue@71
|
36 local configMode
|
Nenue@79
|
37 local anonID = 0
|
Nenue@79
|
38 local tostring = tostring
|
Nenue@79
|
39 local IsFrameHandle = IsFrameHandle
|
Nenue@79
|
40 local GetAnonymousName = function(key)
|
Nenue@79
|
41 if not key then
|
Nenue@71
|
42 anonID = anonID + 1
|
Nenue@79
|
43 key = anonID
|
Nenue@71
|
44 end
|
Nenue@79
|
45 return 'VN' .. key
|
Nenue@71
|
46 end
|
Nenue@79
|
47 local GetTableName = function(table)
|
Nenue@79
|
48 return (IsFrameHandle(table) and table:GetName()) or tostring(table)
|
Nenue@79
|
49 end
|
Nenue@79
|
50
|
Nenue@72
|
51 local anchor_coefficients = {
|
Nenue@72
|
52 ['TOP'] = function(x, y) return x, y end,
|
Nenue@72
|
53 ['BOTTOM'] = function(x, y) return x,y end,
|
Nenue@72
|
54 ['LEFT'] = function(x, y) return x,y end,
|
Nenue@72
|
55 ['RIGHT'] = function(x,y) return x,y end,
|
Nenue@72
|
56 }
|
Nenue@72
|
57
|
Nenue@84
|
58 function VeneerCore:print(...)
|
Nenue@84
|
59 local txt = '|cFFFFFF00Veneer|r:'
|
Nenue@84
|
60 for i = 1, select('#', ...) do
|
Nenue@84
|
61 txt = txt .. ' '.. tostring(select(i, ...))
|
Nenue@84
|
62 end
|
Nenue@84
|
63
|
Nenue@84
|
64 DEFAULT_CHAT_FRAME:AddMessage(txt)
|
Nenue@84
|
65 end
|
Nenue@84
|
66
|
Nenue@84
|
67 function VeneerCore:OnLoad()
|
Nenue@84
|
68 print('|cFFFFFF00Veneer!|r')
|
Nenue@84
|
69 self:RegisterEvent('ADDON_LOADED')
|
Nenue@84
|
70 self:RegisterEvent('PLAYER_LOGIN')
|
Nenue@84
|
71
|
Nenue@84
|
72 self.DEVIAN_PNAME = 'Veneer'
|
Nenue@84
|
73 self:RegisterForDrag('LeftButton')
|
Nenue@84
|
74 end
|
Nenue@84
|
75
|
Nenue@84
|
76 function VeneerCore:OnEvent(event, ...)
|
Nenue@84
|
77 if event == 'ADDON_LOADED' or event == 'PLAYER_LOGIN' then
|
Nenue@84
|
78 if IsLoggedIn() and not self.intialized then
|
Nenue@84
|
79 self.intialized = true
|
Nenue@84
|
80 self:Setup()
|
Nenue@84
|
81 end
|
Nenue@84
|
82 end
|
Nenue@84
|
83 end
|
Nenue@84
|
84
|
Nenue@84
|
85 function VeneerCore:OnDragStart()
|
Nenue@84
|
86 self:StartMoving()
|
Nenue@84
|
87 end
|
Nenue@84
|
88
|
Nenue@84
|
89
|
Nenue@84
|
90 function VeneerCore:OnDragStop()
|
Nenue@84
|
91 self:StopMovingOrSizing()
|
Nenue@84
|
92 end
|
Nenue@84
|
93
|
Nenue@84
|
94 function VeneerCore:Setup ()
|
Nenue@84
|
95 if (not VeneerData) or (not VeneerData.version) then
|
Nenue@84
|
96 VeneerData = defaults
|
Nenue@84
|
97 end
|
Nenue@84
|
98 self.data = VeneerData
|
Nenue@84
|
99
|
Nenue@84
|
100
|
Nenue@84
|
101 self:ExecuteOnClusters(nil, 'Setup')
|
Nenue@84
|
102 end
|
Nenue@84
|
103
|
Nenue@84
|
104 function VeneerCore:AddHandler(handler, ...)
|
Nenue@84
|
105 print('*** Adding handler:', handler.moduleName or handler:GetName())
|
Nenue@84
|
106 local clusterTable = self.FrameClusters
|
Nenue@84
|
107 for i = 1, select('#', ...) do
|
Nenue@84
|
108 local anchor = select(i, ...)
|
Nenue@84
|
109 clusterTable[anchor] = clusterTable[anchor] or {}
|
Nenue@84
|
110 clusterTable = clusterTable[anchor]
|
Nenue@84
|
111 print(' cluster layer', i, anchor)
|
Nenue@84
|
112 end
|
Nenue@84
|
113 for k,v in pairs(VeneerHandlerMixin) do
|
Nenue@84
|
114 if not handler[k] then
|
Nenue@84
|
115 handler[k] = v
|
Nenue@84
|
116 end
|
Nenue@84
|
117 end
|
Nenue@84
|
118 tinsert(clusterTable, handler)
|
Nenue@84
|
119 handler:Reanchor()
|
Nenue@84
|
120 end
|
Nenue@84
|
121
|
Nenue@84
|
122 function VeneerCore:ExecuteOnClusters(layer, method)
|
Nenue@84
|
123 self.parserDepth = self.parserDepth + 1
|
Nenue@84
|
124 layer = layer or self.FrameClusters
|
Nenue@84
|
125 if not layer then
|
Nenue@84
|
126 if self.parserDepth >= 1 then
|
Nenue@84
|
127 tinsert(self.pendingCalls, method)
|
Nenue@84
|
128 print('delaying walk for', method)
|
Nenue@84
|
129 return
|
Nenue@84
|
130 end
|
Nenue@84
|
131 print('|cFF00FFFFVeneer|r:'..method..'('..tostring(layer)..')')
|
Nenue@84
|
132 else
|
Nenue@84
|
133 print(' L'..self.parserDepth)
|
Nenue@84
|
134 end
|
Nenue@84
|
135 for anchor, cluster in pairs(layer) do
|
Nenue@84
|
136 for index, frame in ipairs(cluster) do
|
Nenue@84
|
137 print(' '..anchor..'.'..index..' = '..frame:GetName())
|
Nenue@84
|
138 if frame[method] then
|
Nenue@84
|
139 print(' '..frame:GetName()..':'..method..'(...)')
|
Nenue@84
|
140 frame[method](frame)
|
Nenue@84
|
141 end
|
Nenue@84
|
142 end
|
Nenue@84
|
143 if cluster.FrameClusters then
|
Nenue@84
|
144 self:ExecuteOnClusters(cluster.FrameClusters, method)
|
Nenue@84
|
145 end
|
Nenue@84
|
146 end
|
Nenue@84
|
147 self.parserDepth = self.parserDepth - 1
|
Nenue@84
|
148
|
Nenue@84
|
149 if (self.parserDepth == 0) and (#self.pendingCalls >= 1) then
|
Nenue@84
|
150 local delayedMethod = tremove(self.pendingCalls, 1)
|
Nenue@84
|
151 print('starting delayed walk for', delayedMethod)
|
Nenue@84
|
152 self:ExecuteOnClusters(nil, delayedMethod)
|
Nenue@84
|
153 end
|
Nenue@84
|
154 end
|
Nenue@84
|
155
|
Nenue@84
|
156 function VeneerCore:Update()
|
Nenue@84
|
157 self:ExecuteOnClusters(nil, 'Update')
|
Nenue@84
|
158 end
|
Nenue@84
|
159
|
Nenue@72
|
160 local VeneerButton_OnDragStart = function(self)
|
Nenue@72
|
161 self.startingLeft = self:GetLeft()
|
Nenue@72
|
162 self.startingBottom = self:GetBottom()
|
Nenue@72
|
163 self.anchors = self.anchors or {}
|
Nenue@72
|
164 table.wipe(self.anchors)
|
Nenue@72
|
165
|
Nenue@72
|
166 local frame = self:GetParent()
|
Nenue@72
|
167 local n = frame:GetNumPoints()
|
Nenue@72
|
168 for i = 1, n do
|
Nenue@72
|
169 local anchor, parent, relative, x, y = frame:GetPoint(i)
|
Nenue@72
|
170 self.anchors[i] = {
|
Nenue@72
|
171 anchor = anchor,
|
Nenue@72
|
172 parent = parent,
|
Nenue@72
|
173 relative = relative,
|
Nenue@72
|
174 x = x,
|
Nenue@72
|
175 y = y
|
Nenue@72
|
176 }
|
Nenue@72
|
177 end
|
Nenue@72
|
178
|
Nenue@72
|
179 print(self:GetName(), 'start moving', self.startingLeft, self.startingBottom)
|
Nenue@72
|
180 self:StartMoving()
|
Nenue@72
|
181 end
|
Nenue@72
|
182
|
Nenue@72
|
183 local VeneerButton_OnDragStop = function(self)
|
Nenue@72
|
184 self:StopMovingOrSizing()
|
Nenue@72
|
185 if self.OnDragStop then
|
Nenue@72
|
186 self.OnDragStop(self)
|
Nenue@72
|
187 else
|
Nenue@72
|
188 local frame = self:GetParent()
|
Nenue@72
|
189 local dx = self:GetLeft() - self.startingLeft
|
Nenue@72
|
190 local dy = self:GetBottom() - self.startingBottom
|
Nenue@72
|
191
|
Nenue@72
|
192 frame:ClearAllPoints()
|
Nenue@72
|
193 for i, point in ipairs(self.anchors) do
|
Nenue@72
|
194 frame:SetPoint(point.anchor, point.parent, point.relative, point.x + dx, point.y + dy)
|
Nenue@72
|
195 print('adjusting anchor', point.anchor, point.parent, point.relative, point.x + dx, point.y + dy)
|
Nenue@72
|
196 end
|
Nenue@72
|
197 end
|
Nenue@72
|
198 end
|
Nenue@72
|
199
|
Nenue@72
|
200 local Veneer_FixMovers = function()
|
Nenue@72
|
201 for frame, veneer in pairs(veneers) do
|
Nenue@72
|
202 if veneer:IsMoving() then
|
Nenue@72
|
203 VeneerButton_OnDragStop(veneer)
|
Nenue@72
|
204 end
|
Nenue@72
|
205 end
|
Nenue@72
|
206 end
|
Nenue@71
|
207
|
Nenue@71
|
208 local VeneerButton_Update = function(self)
|
Nenue@71
|
209 if configMode then
|
Nenue@72
|
210 self:SetScript('OnDragStart', VeneerButton_OnDragStart)
|
Nenue@72
|
211 self:SetScript('OnDragStop', VeneerButton_OnDragStop)
|
Nenue@72
|
212 self:SetMovable(true)
|
Nenue@72
|
213 self:EnableMouse(true)
|
Nenue@71
|
214 self:RegisterForDrag('LeftButton')
|
Nenue@71
|
215
|
Nenue@71
|
216 self.bg:SetColorTexture(0,1,0,0.5)
|
Nenue@72
|
217 for i, region in ipairs(self.configLayers) do
|
Nenue@72
|
218 region:Show()
|
Nenue@72
|
219 end
|
Nenue@72
|
220 self:Show()
|
Nenue@71
|
221 else
|
Nenue@71
|
222
|
Nenue@71
|
223 self:SetScript('OnDragStart', self.StartMoving)
|
Nenue@71
|
224 self:SetScript('OnDragStop', self.StopMovingOrSizing)
|
Nenue@71
|
225 self:SetMovable(false)
|
Nenue@71
|
226 self:EnableMouse(false)
|
Nenue@71
|
227
|
Nenue@71
|
228 self.bg:SetColorTexture(0,1,0,0)
|
Nenue@72
|
229 for i, region in ipairs(self.configLayers) do
|
Nenue@72
|
230 region:Hide()
|
Nenue@72
|
231 end
|
Nenue@72
|
232 if self.isHidden then
|
Nenue@72
|
233 self:Hide()
|
Nenue@72
|
234 end
|
Nenue@72
|
235
|
Nenue@71
|
236 end
|
Nenue@71
|
237 end
|
Nenue@71
|
238
|
Nenue@71
|
239 local ToggleVeneerConfig = function()
|
Nenue@71
|
240 if configMode then
|
Nenue@71
|
241 configMode = false
|
Nenue@84
|
242 Veneer:print('Config mode off.')
|
Nenue@71
|
243 else
|
Nenue@71
|
244 configMode = true
|
Nenue@84
|
245 Veneer:print('Config mode on.')
|
Nenue@71
|
246 end
|
Nenue@71
|
247
|
Nenue@71
|
248 for frame, veneer in pairs(veneers) do
|
Nenue@71
|
249 VeneerButton_Update(veneer)
|
Nenue@71
|
250 end
|
Nenue@71
|
251 end
|
Nenue@71
|
252
|
Nenue@71
|
253 local VeneerButton_OnShow = function(self)
|
Nenue@71
|
254 VeneerButton_Update(self)
|
Nenue@71
|
255 end
|
Nenue@71
|
256
|
Nenue@84
|
257 function VeneerCore:Acquire (frame, template)
|
Nenue@71
|
258 if not frame then
|
Nenue@71
|
259 print('|cFFFF4400Unable to acquire frame...|r')
|
Nenue@71
|
260 return
|
Nenue@71
|
261 end
|
Nenue@84
|
262 local veneer = self.Frames[frame]
|
Nenue@84
|
263 if not veneer then
|
Nenue@84
|
264 local name = type(frame) == 'table' and GetTableName(frame) or GetAnonymousName()
|
Nenue@84
|
265 veneer = CreateFrame('Frame', name, frame, template or 'VeneerTemplate')
|
Nenue@84
|
266 print('+veneer', name)
|
Nenue@71
|
267
|
Nenue@84
|
268 veneer:SetAllPoints(frame)
|
Nenue@84
|
269 veneer:SetParent(frame)
|
Nenue@84
|
270 veneer.label:SetText(name)
|
Nenue@84
|
271 veneer.bg:SetColorTexture(0,0,0,0)
|
Nenue@84
|
272 veneer:Hide()
|
Nenue@84
|
273 veneer:EnableMouse(false)
|
Nenue@84
|
274
|
Nenue@84
|
275 veneer:SetScript('OnShow', VeneerButton_OnShow)
|
Nenue@84
|
276
|
Nenue@84
|
277 -- find current X/Y
|
Nenue@84
|
278 veneer.currentLeft = frame:GetLeft()
|
Nenue@84
|
279 veneer.currentTop = frame:GetTop()
|
Nenue@84
|
280 self.Frames[frame] = veneer
|
Nenue@71
|
281 end
|
Nenue@71
|
282
|
Nenue@84
|
283 return veneer
|
Nenue@71
|
284 end
|
Nenue@0
|
285
|
Nenue@80
|
286 local mixin_probe = {
|
Nenue@80
|
287 'ArtifactFrame',
|
Nenue@80
|
288 'ArtifactFrameUnderlay',
|
Nenue@80
|
289 }
|
Nenue@80
|
290
|
Nenue@80
|
291
|