view UI.lua @ 35:3304455a3f45

code organizing; UI stuff is in the UI script, Devian prime just deals with config and print corner menu elements placed and hooked, still needs follow-up code
author Nenue
date Sun, 27 Dec 2015 03:51:17 -0500
parents
children bec37163b7fe
line wrap: on
line source
--- ${PACKAGE_NAME}
-- @file-author@
-- @project-revision@ @project-hash@
-- @file-revision@ @file-hash@
-- Created: 12/27/2015 3:01 AM


if not LibStub then
  print('Something has happened...')
end
local D = LibStub("AceAddon-3.0"):GetAddon("Devian")



local DEVIAN_FRAME = 'DevianConsole'
local DEVIAN_DOCK_FRAME = 'DevianDockFrame'
local MSG_NEED_DEV_MODE = 'Must be in development mode to use this function.'


local function Console_MinMax(self)
  if self.minimized then
    self:Maximize()
  else
    self:Minimize()
  end
end

local function Console_Minimize(self)
  self:SetHeight(20)
  self:SetMaxResize(GetScreenWidth(),20)
  self.minimized = true
  self.out:Hide()
  self:Save()
end

local function Console_Maximize(self)
  local db = D.channels[self.index]
  self:SetHeight(db.height)
  self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
  self.minimized = nil
  self.out:Show()
  self:Save()
end


local function Console_Save(self)
  local db = D.channels[self.index]
  if self.x then
    db.x = self.x
  else
    db.x = self:GetLeft()
  end

  if self.y then
    db.y = self.y
  else
    db.y = (self:GetTop() - GetScreenHeight())
  end

  if self.width then
    db.width = self.width
  else
    db.width = self:GetWidth()
  end

  if not self.minimized then
    if self.height then
      db.height = self.height
    else
      db.height = self:GetHeight()
    end
    self:SetHeight(db.height)
  end

  db.dockedTo = self.dockedTo
  db.docked = self.docked

  db.minimized = self.minimized and true or nil
  db.enabled = self:IsVisible() and true or nil
  db.active = self.active and true or nil
  --print('save:', db.signature, 'min=', db.minimized, ' enabled=', db.enabled, ' active = ', db.active, 'x=', db.x, 'y=', db.y, 'h=', db.height, 'w=', db.width)
  self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
  self:SetWidth(db.width)
end

-- Console frame toggler
-- @paramsig [...]
-- @param ... one or more space-seperated channel keys
local function Console_Toggle(input)
  local db = D.db
  if db.workspace == 1 then
    return D:Print(MSG_NEED_DEV_MODE)
  end
  local search = {}
  local n = 0
  if D:GetArgs(input,1) then
    repeat
      key, n = D:GetArgs(input,1,n)
      if D.sig[key] then
        table.insert(search, D.sig[key])
      elseif D.console[key] then
        table.insert(search, D.console[key])
      end
    until n == 1e9
  else
    search = D.console
  end

  db.enabled = (not db.enabled) and true or nil
  for i, c in ipairs(search) do
    --print(i,c.index)
    if db.enabled then
      c.enabled = true
      c:Show()
      if db.current_channel == c.index then
        c:ToFront()
      end
      c:Save()
    else
      c:Hide()
    end
  end

  if db.enabled then
    D:Print('toggled on?')
  else
    D:Print('toggled off?')
  end
end

--- Brings the console to the front.
-- Frame method used to bring a console frame to the front of the display stack.
local function Console_ToFront(c)
  local db = D.db
  --print(D.raise_ct, 'Raising', c.signature)
  --print(unpack(db.frontdrop))
  --print(unpack(db.frontgrad))
  --print(db.frontblend)
  -- D.raise_ct = D.raise_ct + 1
  c:Raise()
  c:SetAlpha(db.frontalpha)
  c.out.backdrop:SetTexture(unpack(db.frontdrop))
  c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad))
  c.out.backdrop:SetBlendMode(db.frontblend)
  db.current_channel = c.index

  for _, part in pairs(c.border) do
    part:SetTexture(unpack(db.frontborder))
  end

  for id, bc in pairs(D.console) do
    if id ~= c.index then
      --print(D.raise_ct, 'Lowering', bc.signature)
      --print(unpack(db.backdrop))
      --print(unpack(db.backgrad))
      --print(db.backblend)
      bc:SetAlpha(db.backalpha)
      bc.out.backdrop:SetTexture(unpack(db.backdrop))
      bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad))
      bc.out.backdrop:SetBlendMode(db.backblend)

      for _, part in pairs(bc.border) do
        part:SetTexture(unpack(db.backborder))
      end
    end
  end
end

local function Console_MouseDown(self, button, up)
  if button == 'LeftButton' then
    if up then
      self:StopMovingOrSizing()
      self:ToFront()
      self.x = nil
      self.y = nil
      self.width = nil
      self.height = nil
      self:Save()
    elseif self.out.grip:IsMouseOver() then
      self:StartSizing()
    else
      self:StartMoving()
    end
  else
    if up then
      self:MinMax()
    end
  end
end
local function Console_MouseUp(self, button)
  return Console_MouseDown(self, button, true)
end
print('load check')


--- Constructs the frame object for a console channel
-- Initializes the console channel at a specified index.
-- Configuration data can be overridden by passing a desired settings table.
-- @param i Numeric index of the channel as it manifests in db.channels
-- @param vars Optional settings table to be used.
local function CreateConsole(i, vars)
  local db = D.db
  if tonumber(i) == nil or math.floor(i) ~= i then
    error('Non-integer index value.')
  end
  if not vars then
    vars = D.channels[i] and D.channels[i] or D.channels[db.primary_channel]
  end
  local f
  if vars.docked then
    f = CreateFrame('Frame','DevianDockFrame' .. i, DEVIAN_DOCK_FRAME)
  else
    f= CreateFrame('Frame', 'DevianChannelFrame' .. i, UIParent, DEVIAN_FRAME)
  end
  --@debug@
  --print(f:GetName())

  --print('create(2)')
  for k,v in pairs(vars) do
    f[k] = v
    --@debug@
    print(' f['..type(k)..' '..tostring(k)..'] = '..type(v)..' '..tostring(v))
  end

  f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y)
  f:SetSize(vars.width, vars.height)
  f:Lower()
  f.out:SetFont(db.font, db.fontsize, db.fontoutline)
  if (db.current_channel == i) then
    f.out.backdrop:SetTexture(unpack(db.frontdrop))
  else
    f.out.backdrop:SetTexture(unpack(db.backdrop))
  end



  f.Save = Console_Save
  f.Minimize = Console_Minimize
  f.Maximize = Console_Maximize
  f.MinMax = Console_MinMax
  f.ToFront = Console_ToFront
  f.Toggle = D.Console_Toggle
  f:SetScript('OnMouseDown', Console_MouseDown)
  f:SetScript('OnMouseUp', Console_MouseUp)

  if vars.minimized then
    f:Minimize()
  else
    f:Maximize()
  end
  if db.enabled and f.enabled then
    f:Show()
  end

  return f
end


--- Updates console information and returns the handle of the channel object that was worked on.
-- When key is nil or not a valid handle, a new channel is created using whatever signature can be found in cinfo.
-- The signature can be passed as a string, or as a table entry under the key 'signature'
-- If the signature of a new channel is also a tag, the channel will be added to that tag
-- @param cinfo string signature of a new channel, or a table of config variables to be imposed on the channel
-- @param key string signature or index number of channel to operate on
-- @usage channel = D:SetChannel('new', nil) -- creates a new channel
-- @usage channel = D:SetChannel({x = 200, y = 100}, 4) -- updates channel #4
function D:SetChannel(cinfo, key)
  local db = self.db
  local t_info = {}
  local channel, isNew, id, sig, t_id
  -- obtain source data
  if tonumber(key) ~= nil and  db.channels[key] then
    id = tonumber(key)
  elseif D.sigID[tostring(key)] then
    id = D.sigID[tostring(key)]
  else
    id = db.primary_channel
    isNew = true
  end
  local dbvars = db.channels[id]
  t_id = id           -- overridden later if new
  t_info.index = t_id --
  --@debug@
  --print('setchan(1) cinfo, key, id=', cinfo, key, id)--@end-debug@


  -- obtain config info
  if type(cinfo) == 'string' then
    sig = cinfo
    cinfo = {signature = sig}
  elseif type(cinfo) ~= 'table' then -- stop here if a table wans't passed
  error('Expecting table of string as arg1')
  elseif cinfo.signature then -- new sig
  sig = cinfo.signature
  elseif isNew then -- new channel sig
  sig = 'Ch'
  else -- old sig
  sig = db.channels[id].signature
  end
  t_info.signature = sig
  --@debug@
  --print('setchan(2) sig,id,isNew=', sig, id, isNew)--@end-debug@

  for k,v in pairs(cinfo) do -- allow all cinfo to pass
  t_info[k] = v
  end

  local blocked = {          -- ignore these vars:
    ['docked'] = true,       -- table
    ['dockedTo'] = true,     -- table-related
    ['signature'] = true}    -- already determined
  for k,v in pairs(dbvars) do
    if not t_info[k] and not blocked[k] then -- already set or blocked?
    t_info[k] = v
    end
  end
  -- new channel overrides
  if isNew then
    if D.sigID[sig]then -- find a non-clashing signature
    local result, i = sig, 1
    while D.sigID[result] do
      result = sig .. i
      i = i + 1
    end
    t_info.signature = result
    end
    t_id = db.max_channel + 1
    t_info.index = t_id
    --@debug@
    --print('setchan(3a) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
  else
    --@debug@
    --print('setchan(3b) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
  end

  local channel
  if not self.console[t_id] then -- create a frame
  if isNew then -- position the channel frame
  t_info.x = t_info.x + 20
  t_info.y = t_info.y - 20
  db.channels[t_id] = t_info
  --@debug@
  print('setchan(4a)', 't_id, x, y=', t_id, t_info.x, t_info.y)--@end-debug@
  end
  channel = CreateConsole(t_id, t_info)
  self.console[t_id] = channel
  self.sig[t_info.signature] = channel
  self.sigID[t_info.signature] = t_id
  self.IDsig[t_id] = t_info.signature

  end
  channel = self.console[t_id]
  if channel.minimized then
    channel:Minimize()
  else
    channel:Maximize()
  end

  if channel.enabled and db.enabled then -- hide or show last since Min/Max mess with visibility
  print('setchan(5a) enable')
  channel:Show()
  else
    print('setchan(5a) disable')
    channel:Hide()
  end
  --@debug@
  --print('setchan(end); c:IsVisible(), c.enabled, db.enabled=', channel:IsVisible(), channel.enabled, db.enabled)--@end-debug@
  return channel
end