annotate UI.lua @ 72:da5ff1fc9fb6

- Fixed an issue with creating more than one output channel per UI session. - Cleanup of globals for slightly better performance when printing to a lot of channels at once
author Nenue
date Sat, 09 Apr 2016 05:51:19 -0400
parents d73b883b415b
children 80ad43c94033
rev   line source
Nenue@50 1 --- Devian - UI.lua
Nenue@35 2 -- @file-author@
Nenue@35 3 -- @project-revision@ @project-hash@
Nenue@35 4 -- @file-revision@ @file-hash@
Nenue@35 5 -- Created: 12/27/2015 3:01 AM
Nenue@35 6 if not LibStub then
Nenue@35 7 print('Something has happened...')
Nenue@35 8 end
Nenue@66 9 local _, D = ...
Nenue@35 10 local DEVIAN_FRAME = 'DevianConsole'
Nenue@66 11 local insert, tonumber, pairs, concat = tinsert, tonumber, pairs, table.concat
Nenue@66 12 local L = D.L
Nenue@66 13 local print = D.print
Nenue@66 14
Nenue@66 15
Nenue@66 16
Nenue@66 17
Nenue@66 18 local Console_OnMovementChanged = function(self, event)
Nenue@66 19 local db = D.db
Nenue@66 20 if self.enabled then
Nenue@66 21 if event == 'PLAYER_STARTED_MOVING' then
Nenue@66 22 self.moveFade:Stop()
Nenue@66 23 local F1 = self.moveFade.alphaOut
Nenue@66 24 F1:SetFromAlpha(db.movement_fade_from)
Nenue@66 25 F1:SetToAlpha(db.movement_fade_to)
Nenue@66 26 F1:SetDuration(db.movement_fade_time)
Nenue@66 27 self.moveFade:Play()
Nenue@66 28 self:EnableMouse(false)
Nenue@66 29 else
Nenue@66 30 self.moveFade:Stop()
Nenue@66 31 local F1 = self.moveFade.alphaOut
Nenue@66 32 F1:SetToAlpha(db.movement_fade_from)
Nenue@66 33 F1:SetFromAlpha(db.movement_fade_to)
Nenue@66 34 F1:SetDuration(db.movement_fade_time)
Nenue@66 35 self.moveFade:Play()
Nenue@66 36 self:EnableMouse(true)
Nenue@66 37 end
Nenue@66 38 end
Nenue@66 39 end
Nenue@66 40
Nenue@35 41
Nenue@35 42
Nenue@35 43 local function Console_MinMax(self)
Nenue@35 44 if self.minimized then
Nenue@35 45 self:Maximize()
Nenue@35 46 else
Nenue@35 47 self:Minimize()
Nenue@35 48 end
Nenue@35 49 end
Nenue@35 50
Nenue@35 51 local function Console_Minimize(self)
Nenue@35 52 self:SetHeight(20)
Nenue@35 53 self:SetMaxResize(GetScreenWidth(),20)
Nenue@35 54 self.minimized = true
Nenue@35 55 self.out:Hide()
Nenue@35 56 self:Save()
Nenue@35 57 end
Nenue@35 58
Nenue@35 59 local function Console_Maximize(self)
Nenue@35 60 local db = D.channels[self.index]
Nenue@35 61 self:SetHeight(db.height)
Nenue@35 62 self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
Nenue@35 63 self.minimized = nil
Nenue@35 64 self.out:Show()
Nenue@35 65 self:Save()
Nenue@35 66 end
Nenue@35 67
Nenue@35 68
Nenue@35 69 local function Console_Save(self)
Nenue@70 70 local db = D.currentProfile.channels[self.index]
Nenue@35 71 db.x = self:GetLeft()
Nenue@35 72 db.y = (self:GetTop() - GetScreenHeight())
Nenue@35 73 db.width = self:GetWidth()
Nenue@35 74
Nenue@35 75 if not self.minimized then
Nenue@55 76 db.height = self:GetHeight()
Nenue@35 77 self:SetHeight(db.height)
Nenue@35 78 end
Nenue@35 79
Nenue@35 80 db.dockedTo = self.dockedTo
Nenue@35 81 db.docked = self.docked
Nenue@35 82
Nenue@70 83 db.minimized = self.minimized
Nenue@70 84 db.enabled = self.enabled
Nenue@70 85 db.active = self.active
Nenue@35 86 self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
Nenue@35 87 self:SetWidth(db.width)
Nenue@35 88 end
Nenue@35 89
Nenue@35 90 --- Brings the console to the front.
Nenue@35 91 -- Frame method used to bring a console frame to the front of the display stack.
Nenue@35 92 local function Console_ToFront(c)
Nenue@35 93 local db = D.db
Nenue@68 94 local profile = D.currentProfile
Nenue@35 95 c:Raise()
Nenue@35 96 c:SetAlpha(db.frontalpha)
Nenue@35 97 c.out.backdrop:SetTexture(unpack(db.frontdrop))
Nenue@35 98 c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad))
Nenue@35 99 c.out.backdrop:SetBlendMode(db.frontblend)
Nenue@45 100 c.dropmenu.icon:SetVertexColor(unpack(db.frontheader))
Nenue@45 101 c.title:SetTextColor(unpack(db.frontborder))
Nenue@60 102
Nenue@62 103 --oldprint('changing current toplevel from', db.current_channel, 'to', c.index)
Nenue@68 104 profile.current_channel = c.index
Nenue@35 105
Nenue@62 106 --oldprint('toplevel is now', db.current_channel)
Nenue@60 107 c:Save()
Nenue@60 108
Nenue@60 109
Nenue@50 110 -- update dock buttons
Nenue@50 111 local beacon = D.dock.buttons[c.index]
Nenue@50 112 beacon.selected = true
Nenue@58 113 beacon.newMessage = nil
Nenue@50 114 D.UpdateBeacon(beacon)
Nenue@50 115
Nenue@35 116 for _, part in pairs(c.border) do
Nenue@35 117 part:SetTexture(unpack(db.frontborder))
Nenue@35 118 end
Nenue@35 119
Nenue@35 120 for id, bc in pairs(D.console) do
Nenue@35 121 if id ~= c.index then
Nenue@35 122 bc:SetAlpha(db.backalpha)
Nenue@35 123 bc.out.backdrop:SetTexture(unpack(db.backdrop))
Nenue@35 124 bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad))
Nenue@35 125 bc.out.backdrop:SetBlendMode(db.backblend)
Nenue@45 126 bc.dropmenu.icon:SetVertexColor(unpack(db.backheader))
Nenue@36 127 bc.title:SetTextColor(unpack(db.backborder))
Nenue@35 128
Nenue@50 129 local beacon = D.dock.buttons[bc.index]
Nenue@58 130 beacon.raised = nil
Nenue@58 131 beacon.showName = nil
Nenue@50 132 beacon.selected = nil
Nenue@50 133 D.UpdateBeacon(beacon)
Nenue@50 134
Nenue@35 135 for _, part in pairs(bc.border) do
Nenue@35 136 part:SetTexture(unpack(db.backborder))
Nenue@35 137 end
Nenue@35 138 end
Nenue@35 139 end
Nenue@35 140 end
Nenue@35 141
Nenue@35 142 local function Console_MouseDown(self, button, up)
Nenue@35 143 if button == 'LeftButton' then
Nenue@35 144 if up then
Nenue@35 145 self:StopMovingOrSizing()
Nenue@35 146 self:ToFront()
Nenue@35 147 self:Save()
Nenue@35 148 elseif self.out.grip:IsMouseOver() then
Nenue@35 149 self:StartSizing()
Nenue@35 150 else
Nenue@35 151 self:StartMoving()
Nenue@35 152 end
Nenue@35 153 else
Nenue@35 154 if up then
Nenue@35 155 self:MinMax()
Nenue@35 156 end
Nenue@35 157 end
Nenue@35 158 end
Nenue@35 159 local function Console_MouseUp(self, button)
Nenue@35 160 return Console_MouseDown(self, button, true)
Nenue@35 161 end
Nenue@35 162
Nenue@35 163
Nenue@35 164 --- Constructs the frame object for a console channel
Nenue@35 165 -- Initializes the console channel at a specified index.
Nenue@35 166 -- Configuration data can be overridden by passing a desired settings table.
Nenue@35 167 -- @param i Numeric index of the channel as it manifests in db.channels
Nenue@35 168 -- @param vars Optional settings table to be used.
Nenue@35 169 local function CreateConsole(i, vars)
Nenue@35 170 local db = D.db
Nenue@35 171 if tonumber(i) == nil or math.floor(i) ~= i then
Nenue@35 172 error('Non-integer index value.')
Nenue@35 173 end
Nenue@35 174 if not vars then
Nenue@35 175 vars = D.channels[i] and D.channels[i] or D.channels[db.primary_channel]
Nenue@35 176 end
Nenue@35 177 local f
Nenue@70 178 f = CreateFrame('Frame', 'DevianChannelFrame' .. i, UIParent, DEVIAN_FRAME)
Nenue@47 179
Nenue@35 180 --@debug@
Nenue@35 181 --print(f:GetName())
Nenue@35 182
Nenue@35 183 --print('create(2)')
Nenue@35 184 for k,v in pairs(vars) do
Nenue@35 185 f[k] = v
Nenue@35 186 --@debug@
Nenue@36 187 --print(' f['..type(k)..' '..tostring(k)..'] = '..type(v)..' '..tostring(v))
Nenue@35 188 end
Nenue@35 189
Nenue@35 190 f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y)
Nenue@35 191 f:SetSize(vars.width, vars.height)
Nenue@35 192 f:Lower()
Nenue@35 193 f.out:SetFont(db.font, db.fontsize, db.fontoutline)
Nenue@35 194 if (db.current_channel == i) then
Nenue@35 195 f.out.backdrop:SetTexture(unpack(db.frontdrop))
Nenue@36 196 f.dropmenu.icon:SetVertexColor(unpack(db.headerfontcolor))
Nenue@36 197 f.title:SetTextColor(unpack(db.headerfontcolor))
Nenue@45 198 f.header:SetAlpha(db.headeralpha)
Nenue@35 199 else
Nenue@35 200 f.out.backdrop:SetTexture(unpack(db.backdrop))
Nenue@35 201 end
Nenue@35 202
Nenue@35 203 f.Save = Console_Save
Nenue@35 204 f.Minimize = Console_Minimize
Nenue@35 205 f.Maximize = Console_Maximize
Nenue@35 206 f.MinMax = Console_MinMax
Nenue@35 207 f.ToFront = Console_ToFront
Nenue@35 208 f.Toggle = D.Console_Toggle
Nenue@35 209 f:SetScript('OnMouseDown', Console_MouseDown)
Nenue@35 210 f:SetScript('OnMouseUp', Console_MouseUp)
Nenue@66 211 f.profileID = db.current_profile
Nenue@35 212
Nenue@36 213
Nenue@36 214 UIDropDownMenu_Initialize(f.menuFrame, function()
Nenue@36 215 local info = { {
Nenue@36 216 text= "Close",
Nenue@36 217 value = "OptClose",
Nenue@36 218 func = function ()
Nenue@36 219 f.enabled = nil
Nenue@36 220 f:Hide()
Nenue@36 221 f:Save()
Nenue@38 222 end },--[[
Nenue@36 223 {
Nenue@36 224 text = "Dock",
Nenue@36 225 value = "OptDock",
Nenue@38 226 func = function() print('Dvn', 'docking shenanary') end }]]
Nenue@36 227 }
Nenue@36 228 for _, v in ipairs(info) do
Nenue@36 229 UIDropDownMenu_AddButton(v)
Nenue@36 230 end
Nenue@36 231 end, 'MENU')
Nenue@36 232
Nenue@66 233 if db.movement_fade then
Nenue@66 234 f:RegisterEvent('PLAYER_STARTED_MOVING')
Nenue@66 235 f:RegisterEvent('PLAYER_STOPPED_MOVING')
Nenue@66 236 f:SetScript('OnEvent', Console_OnMovementChanged)
Nenue@66 237 end
Nenue@66 238
Nenue@47 239 D.dock.buttons[i] = CreateFrame('Button', 'Channel'..i..'Beacon', UIParent, 'DevianBeacon')
Nenue@47 240 D.dock.buttons[i].icon:SetVertexColor(math.random(),math.random(),math.random())
Nenue@47 241 D.dock.buttons[i].console = f
Nenue@47 242 D.dock.buttons[i].index = i
Nenue@47 243 D.dock.buttons[i].caption.name:SetText(vars.signature)
Nenue@47 244 D.dock.buttons[i]:Show()
Nenue@47 245
Nenue@35 246 if vars.minimized then
Nenue@35 247 f:Minimize()
Nenue@35 248 else
Nenue@35 249 f:Maximize()
Nenue@35 250 end
Nenue@68 251 if db.enabled then
Nenue@68 252 f.enabled = true
Nenue@35 253 f:Show()
Nenue@35 254 end
Nenue@35 255
Nenue@35 256 return f
Nenue@35 257 end
Nenue@35 258
Nenue@35 259
Nenue@35 260 --- Updates console information and returns the handle of the channel object that was worked on.
Nenue@35 261 -- When key is nil or not a valid handle, a new channel is created using whatever signature can be found in cinfo.
Nenue@35 262 -- The signature can be passed as a string, or as a table entry under the key 'signature'
Nenue@35 263 -- If the signature of a new channel is also a tag, the channel will be added to that tag
Nenue@35 264 -- @param cinfo string signature of a new channel, or a table of config variables to be imposed on the channel
Nenue@35 265 -- @param key string signature or index number of channel to operate on
Nenue@35 266 -- @usage channel = D:SetChannel('new', nil) -- creates a new channel
Nenue@35 267 -- @usage channel = D:SetChannel({x = 200, y = 100}, 4) -- updates channel #4
Nenue@35 268 function D:SetChannel(cinfo, key)
Nenue@66 269 local profile = D.currentProfile
Nenue@35 270 local t_info = {}
Nenue@35 271 local channel, isNew, id, sig, t_id
Nenue@36 272 --@debug@
Nenue@68 273 --print('setchan(0) cinfo, key', cinfo, key)--@end-debug@
Nenue@35 274 -- obtain source data
Nenue@66 275 if tonumber(key) ~= nil and D.channels[key] then
Nenue@35 276 id = tonumber(key)
Nenue@35 277 elseif D.sigID[tostring(key)] then
Nenue@35 278 id = D.sigID[tostring(key)]
Nenue@35 279 else
Nenue@66 280 id = profile.default_channel
Nenue@35 281 isNew = true
Nenue@35 282 end
Nenue@66 283 local dbvars = D.channels[id]
Nenue@35 284 t_id = id -- overridden later if new
Nenue@35 285 t_info.index = t_id --
Nenue@35 286 --@debug@
Nenue@68 287 --print('setchan(1) cinfo, key, id=', cinfo, key, id)--@end-debug@
Nenue@35 288
Nenue@35 289
Nenue@35 290 -- obtain config info
Nenue@35 291 if type(cinfo) == 'string' then
Nenue@35 292 sig = cinfo
Nenue@35 293 cinfo = {signature = sig}
Nenue@35 294 elseif type(cinfo) ~= 'table' then -- stop here if a table wans't passed
Nenue@66 295 error('Expecting table of string as arg1')
Nenue@35 296 elseif cinfo.signature then -- new sig
Nenue@66 297 sig = cinfo.signature
Nenue@35 298 elseif isNew then -- new channel sig
Nenue@66 299 sig = 'Ch'
Nenue@35 300 else -- old sig
Nenue@66 301 sig = D.channels[id].signature
Nenue@35 302 end
Nenue@35 303 t_info.signature = sig
Nenue@35 304 --@debug@
Nenue@68 305 --print('setchan(2) sig,id,isNew=', sig, id, isNew)--@end-debug@
Nenue@35 306
Nenue@35 307 for k,v in pairs(cinfo) do -- allow all cinfo to pass
Nenue@35 308 t_info[k] = v
Nenue@35 309 end
Nenue@35 310
Nenue@35 311 local blocked = { -- ignore these vars:
Nenue@35 312 ['docked'] = true, -- table
Nenue@35 313 ['dockedTo'] = true, -- table-related
Nenue@35 314 ['signature'] = true} -- already determined
Nenue@35 315 for k,v in pairs(dbvars) do
Nenue@35 316 if not t_info[k] and not blocked[k] then -- already set or blocked?
Nenue@70 317 --print('assign', k, '=', v)
Nenue@35 318 t_info[k] = v
Nenue@35 319 end
Nenue@35 320 end
Nenue@35 321 -- new channel overrides
Nenue@35 322 if isNew then
Nenue@72 323 if D.sigID[sig] then -- find a non-clashing signature
Nenue@35 324 local result, i = sig, 1
Nenue@35 325 while D.sigID[result] do
Nenue@35 326 result = sig .. i
Nenue@35 327 i = i + 1
Nenue@35 328 end
Nenue@35 329 t_info.signature = result
Nenue@35 330 end
Nenue@36 331 t_id = self.max_channel + 1
Nenue@35 332 t_info.index = t_id
Nenue@72 333
Nenue@72 334 self.max_channel = t_id
Nenue@35 335 --@debug@
Nenue@68 336 --print('setchan(3a) t_id, isNew, sig, t_info.signature=', t_id, isNew, sig, t_info.signature)--@end-debug@
Nenue@35 337 else
Nenue@35 338 --@debug@
Nenue@68 339 --print('setchan(3b) t_id, isNew, sig, t_info.signature=', t_id, isNew, sig, t_info.signature)--@end-debug@
Nenue@35 340 end
Nenue@35 341
Nenue@35 342 local channel
Nenue@35 343 if not self.console[t_id] then -- create a frame
Nenue@66 344 if isNew then -- position the channel frame
Nenue@66 345 profile.max_channel = t_id
Nenue@66 346 t_info.x = t_info.x + 20
Nenue@66 347 t_info.y = t_info.y - 20
Nenue@66 348 profile.channels[t_id] = t_info
Nenue@66 349 --@debug@
Nenue@68 350 --print('setchan(4a)', 't_id, x, y=', t_id, t_info.x, t_info.y)--@end-debug@
Nenue@66 351 end
Nenue@66 352 channel = CreateConsole(t_id, t_info)
Nenue@66 353 self.console[t_id] = channel
Nenue@66 354 self.sig[t_info.signature] = channel
Nenue@66 355 self.sigID[t_info.signature] = t_id
Nenue@66 356 self.IDsig[t_id] = t_info.signature
Nenue@35 357 end
Nenue@35 358 channel = self.console[t_id]
Nenue@35 359 if channel.minimized then
Nenue@35 360 channel:Minimize()
Nenue@35 361 else
Nenue@35 362 channel:Maximize()
Nenue@35 363 end
Nenue@35 364
Nenue@55 365 if channel.enabled then -- hide or show last since Min/Max mess with visibility
Nenue@70 366 --print('setchan(5a) enable')
Nenue@55 367 channel:Show()
Nenue@60 368 --channel:ToFront()
Nenue@35 369 else
Nenue@68 370 --print('setchan(5a) disable')
Nenue@35 371 channel:Hide()
Nenue@35 372 end
Nenue@35 373 --@debug@
Nenue@68 374 --print('setchan(end); c:IsVisible(), c.enabled, db.enabled=', channel:IsVisible(), channel.enabled, profile.enabled)--@end-debug@
Nenue@35 375 return channel
Nenue@66 376 end
Nenue@66 377
Nenue@66 378 --- Console frame toggler
Nenue@66 379 -- @paramsig [...]
Nenue@66 380 -- @param ... one or more space-seperated channel keys
Nenue@66 381 function D:Console_Toggle(input, force)
Nenue@66 382 local profile = D.currentProfile
Nenue@66 383 local setAll
Nenue@66 384 local search = {}
Nenue@66 385 local key
Nenue@66 386 local n = 0
Nenue@66 387
Nenue@70 388 -- resolve key/sig values from args
Nenue@70 389 while self:GetArgs(input,1,n) and n < 255 do
Nenue@70 390 key, n = self:GetArgs(input,1,n)
Nenue@70 391
Nenue@70 392 if self.sig[key] then
Nenue@70 393 --print(key, self.sigID[key])
Nenue@70 394 insert(search, self.sigID[key])
Nenue@70 395 elseif self.console[tonumber(key)] then
Nenue@70 396 --print(key, tonumber(key))
Nenue@70 397 insert(search, tonumber(key))
Nenue@70 398 end
Nenue@66 399
Nenue@66 400 --oldprint(#search, key, n)
Nenue@66 401 end
Nenue@70 402
Nenue@70 403 -- if nothing was found, then do an all toggle
Nenue@66 404 if #search < 1 then
Nenue@70 405 search = self.sigID -- using this since it lists frame ID's
Nenue@66 406 setAll = true
Nenue@66 407 end
Nenue@70 408
Nenue@70 409 -- sort global enable state
Nenue@66 410 if setAll then
Nenue@66 411 --oldprint('setall', setAll)
Nenue@66 412 profile.enabled = (not profile.enabled) and true or nil
Nenue@66 413 if force == 0 then
Nenue@66 414 profile.enabled = nil
Nenue@66 415 end
Nenue@66 416 end
Nenue@66 417
Nenue@70 418 -- sort local enable states: if global enable, apply that change to channel
Nenue@70 419 -- else, channel enable takes precedence
Nenue@66 420 for i, id in pairs(search) do
Nenue@66 421 local c = self.console[id]
Nenue@66 422 if setAll then
Nenue@70 423 c.enabled = profile.enabled
Nenue@66 424 else
Nenue@66 425 c.enabled = (not c.enabled) and true or nil
Nenue@66 426 if force == 0 then
Nenue@66 427 c.enabled = nil
Nenue@66 428 end
Nenue@66 429 end
Nenue@66 430
Nenue@70 431 if c.enabled then
Nenue@70 432 profile.enabled = true
Nenue@66 433 c:Show()
Nenue@70 434 else
Nenue@66 435 c:Hide()
Nenue@66 436 end
Nenue@66 437 c:Save()
Nenue@66 438 end
Nenue@66 439
Nenue@66 440 if setAll then
Nenue@66 441 if profile.enabled then
Nenue@66 442 self:Print('toggled all consoles ON')
Nenue@66 443 if D.console[profile.current_channel] then
Nenue@66 444 D.console[profile.current_channel]:ToFront()
Nenue@66 445 end
Nenue@66 446 else
Nenue@66 447 self:Print('toggled all consoles OFF')
Nenue@66 448 end
Nenue@66 449 else
Nenue@66 450 local result = {}
Nenue@66 451 for i, id in pairs(search) do
Nenue@66 452 result[i] = tostring(id) .. ' = ' .. (self.console[id].enabled and 'ON' or 'OFF')
Nenue@66 453 end
Nenue@66 454 self:Print('toggled: '..concat(result, ', '))
Nenue@66 455 end
Nenue@66 456 end
Nenue@72 457
Nenue@72 458 local frame_helper = CreateFrame('Frame', 'DevianFrameHelper', UIParent)
Nenue@72 459 frame_helper.fill = frame_helper:CreateTexture(nil, 'BACKGROUND')
Nenue@72 460 frame_helper.fill:SetTexture(1,0,0,1)
Nenue@72 461 frame_helper.fill:SetAllPoints(frame_helper)
Nenue@72 462 D.FrameHelper_Update = function(input, editbox)
Nenue@72 463 local frame, func = D:GetArgs(input,2)
Nenue@72 464
Nenue@72 465 if type(frame) == 'string' then
Nenue@72 466 if not _G[frame] then
Nenue@72 467 return
Nenue@72 468 end
Nenue@72 469 frame = _G[frame]
Nenue@72 470 elseif type(frame) == 'table' and frame.IsVisible then
Nenue@72 471 local x, y = frame:GetCenter()
Nenue@72 472 if not (x or y) then
Nenue@72 473 frame_helper:ClearAllPoints()
Nenue@72 474 frame_helper:SetPoint('CENTER')
Nenue@72 475 end
Nenue@72 476 else
Nenue@72 477 local frame = EnumerateFrames(); -- Get the first frame
Nenue@72 478 while frame do
Nenue@72 479 if ( frame:IsVisible() and MouseIsOver(frame) ) then
Nenue@72 480 print(frame:GetName() or string.format("[Unnamed Frame: %s]", tostring(frame)));
Nenue@72 481 end
Nenue@72 482 frame = EnumerateFrames(frame); -- Get the next frame
Nenue@72 483 end
Nenue@72 484 end
Nenue@72 485
Nenue@72 486 frame_helper:SetPoint('TOPLEFT', UIParent, 'BOTTOMLEFT', frameHandle:GetLeft(), frameHandle:GetTop())
Nenue@72 487 frame_helper:SetPoint('BOTTOMRIGHT', UIParent, 'BOTTOMLEFT', frameHandle:GetRight(), frameHandle:GetBottom())
Nenue@72 488
Nenue@72 489 end
Nenue@72 490
Nenue@72 491
Nenue@72 492 local frame_guide_init = function(self)
Nenue@72 493 self.testU = self.testU or self:CreateTexture('TestU', 'OVERLAY', 'VnTestLine')
Nenue@72 494 self.testB = self.testB or self:CreateTexture('TestB', 'OVERLAY', 'VnTestLine')
Nenue@72 495 self.testL = self.testL or self:CreateTexture('TestL', 'OVERLAY', 'VnTestLine')
Nenue@72 496 self.testR = self.testR or self:CreateTexture('TestR', 'OVERLAY', 'VnTestLine')
Nenue@72 497 end
Nenue@72 498 local frame_guide = function(self, target)
Nenue@72 499 if not target then return end
Nenue@72 500 if target:IsDragging() then return end
Nenue@72 501 local thickness = 1
Nenue@72 502 local midX, midY = target:GetCenter()
Nenue@72 503 local width, height = target:GetWidth() * 1.5, target:GetHeight() * 1.5
Nenue@72 504 --print('frame', target:GetLeft(), target:GetTop(), target:GetRight(), target:GetBottom())
Nenue@72 505 self.testB:ClearAllPoints()
Nenue@72 506 self.testB:SetPoint('TOP', UIParent, 'BOTTOMLEFT', midX, target:GetBottom())
Nenue@72 507 self.testB:SetSize(width,thickness)
Nenue@72 508
Nenue@72 509 self.testU:ClearAllPoints()
Nenue@72 510 self.testU:SetPoint('BOTTOM', UIParent, 'BOTTOMLEFT', midX, target:GetTop())
Nenue@72 511 self.testU:SetSize(width,thickness)
Nenue@72 512
Nenue@72 513 self.testL:ClearAllPoints()
Nenue@72 514 self.testL:SetPoint('RIGHT', UIParent, 'BOTTOMLEFT', target:GetLeft(), midY)
Nenue@72 515 self.testL:SetSize(thickness,height)
Nenue@72 516
Nenue@72 517 self.testR:ClearAllPoints()
Nenue@72 518 self.testR:SetPoint('LEFT', UIParent, 'BOTTOMLEFT', target:GetRight(), midY)
Nenue@72 519 self.testR:SetSize(thickness,height)
Nenue@72 520 end