view Turok/Layout/Dialog.lua @ 11:0b1a2f3dbfc4 tip

aura duration override triggering activation twice when aura data still exists briefly after duration end
author Nenue
date Mon, 22 Feb 2016 03:11:54 -0500
parents a9b8b0866ece
children
line wrap: on
line source
--- Dialog Generator
-- @file-author@
-- @project-revision@ @project-hash@
-- @file-revision@ @file-hash@
-- Created: 1/1/2016 3:37 PM
--- Framescript template for generating intelligible dialog panels
--[[
-- Frame << TkListFrame
-- {
--    Frame <rows> << TkListItem                <--  Any number of list item frames with parentArray="rows"
--    {
          :GetRow(row, values, id, offset)      <--  Populates the uiobjects that make up the given row, with data from values[id], on display row offset
          <opts>                                <--  Any layered region of child frame with parentArray=opts"
      }
      Button <buttons>                      <--  Any frame with parentArray="buttons"

      .Click (button, list)                 <--  Defines results of using a control button
      .Check (button, row, list)            <--  Defines results of operating a row widget
      .Wheel (list, delta)                  <--  Defines response to mousewheel action over the list panel
   }

   Globals:
   TkList_Init ( object, values, offset, numRows )
    Takes the return from CreateFrame and a table of values and establishes a scrollable list interface.

   TkPanel_Init ( object )
    TkList_Init without the scrollable list operations. Lines up control buttons and nothing else.
--]]
local TK_LIST_SPACING = 1
local TK_LIST_PADDING = 3
local TK_LIST_HEADING_SIZE = 26
local TK_LIST_ITEM_HEIGHT = 24
local TK_LIST_DISPLAY_ITEMS = 10

local print = function(...)
  if _G.Devian and _G.DevianDB.workspace ~= 1 then
    _G.print('Xui', ...)
  end
end
-- GLOBALS: TkList_SetView, TkList_Init, Turok
local type, error, pairs, ipairs, tonumber, max, CreateFrame = type, error, pairs, ipairs, tonumber, math.max, CreateFrame
local checkval = function(valtype, t, fallback)
  return (type(t) == valtype) and t or (fallback or error('Expected table reference, got '..type(t)))
end
local tableval = function(t, fallback)
  return checkval('table', t, fallback or {})
end
local funcval = function(f, fallback)
  return checkval('function', f, fallback or function() end)
end

--- Orders list row
-- Does an ipairs iteration over self.opts and distributes the referenced objects along the horizontal axis of 'self'
-- Note that members are only aligned horizontally; no column alignment is done. Widths can be set by datafunc to accomplish that.
local function TkListItem_Init (listrow)
  if not listrow.opts then
    print('no options to enumerate')
    return
  end
  local rwidth = TK_LIST_PADDING*2
  for i, z in pairs(listrow.opts) do
    if i > 1 then
      z:SetPoint('LEFT', listrow.opts[i-1], 'RIGHT', TK_LIST_SPACING, 0)
    else
      z:SetPoint('LEFT', listrow, 'LEFT', TK_LIST_PADDING, 0)
    end
    rwidth = rwidth + z:GetWidth()+TK_LIST_SPACING
    z:Show()
  end
  listrow:SetSize(rwidth-TK_LIST_PADDING*2,TK_LIST_ITEM_HEIGHT)
  listrow:Show()
  print(rwidth)
  return rwidth
end


---
local function TkControls_Init(self)
  local buttonsize = (self._dwidth - (#self.buttons -1) * TK_LIST_SPACING - TK_LIST_PADDING*2) / #self.buttons
  for n, b in ipairs(self.buttons) do
    --print('Spirit', buttonsize)
    b:SetWidth(buttonsize)
    b:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', buttonsize* (n-1) + TK_LIST_SPACING * (n-1) + TK_LIST_PADDING, -TK_LIST_PADDING)
  end
  self.controls:SetHeight(self.buttons[1]:GetHeight()+ TK_LIST_PADDING*2)
end

--- Populates the list frame with items
function TkList_SetView(self, start_num, num_rows)
  print(self, start_num, num_rows)
  if not start_num then
    start_num = self.offset
  end

  if not num_rows then
    num_rows = self.num_rows
  end

  if start_num > #self.info then
    start_num = #self.info - #self.info % num_rows
  elseif start_num < 1 then
    start_num = 1
  end

  print('  ', self:GetName(), start_num, num_rows, #self.info)
  self.offset = start_num

  for draw_num = 1, num_rows do
    local actual_row = draw_num + start_num - 1
    if not self.rows[draw_num] then
      self.rows[draw_num] = CreateFrame('Frame', self:GetName()..'_Option_'..draw_num, self, 'TurokListItem')
      self.rows[draw_num]:SetHeight(TK_LIST_ITEM_HEIGHT)
      self.rows[draw_num].row_num = draw_num
    end
    self.rows[draw_num].actual_row = actual_row
    local row = self.rows[draw_num]
    if self.info[actual_row] then
      print( actual_row, draw_num)
      self.GetRow(row, self.info, actual_row, draw_num)
      row:Show()
    else
      print('|cFF888888'..actual_row, draw_num)
      row:Hide()
    end
    row:SetParent(self)
  end
end

--- Prime TkListFrame template-spawn for use
-- @param self frame object to list-ify
-- @param info array of list item values
-- @param datafunc function that takes 1) frame object 2) info table 3) index number 4) row number
-- @param offset starting offset for initial view
function TkList_Init (self, info, offset, num_rows)
  -- error checking
  --[[if type(info) ~= 'table' then
    error('arg #2 info must be an associative array')
  end
  if type(datafunc) ~= 'function' then
    error('arg #3 needs a funcref or method name from the frame object')
  end
  --]]
  self.GetRow = funcval(self.GetRow, function() end)
  self.info = tableval(info, {})
  for i, v in ipairs(info) do
    print('Main', i, '=', v.spellName, v.spellTab)
    self.max_row = i
  end
  print('Main', 'last row #', self.max_row)


  -- obtain data contents
  self._dwidth = 0
  self.rows = {}
  self.offset = offset and offset or 1
  self.num_rows = (tonumber(num_rows) ~= nil) and num_rows or TK_LIST_DISPLAY_ITEMS
  self.name:SetHeight(TK_LIST_HEADING_SIZE)
  TkList_SetView(self, offset)

  -- sort out the proper width
  local rwidth = 1
  local  k = 0
  for n, item in ipairs(self.rows) do
    print(item:GetName())
    if item:IsShown() then
      if n > 1 then
        item:SetPoint('TOPLEFT', self.rows[n-1], 'BOTTOMLEFT', 0, - TK_LIST_SPACING)
      else
        item:SetPoint('TOPLEFT', self, 'TOPLEFT', TK_LIST_PADDING, -(TK_LIST_PADDING+TK_LIST_HEADING_SIZE+TK_LIST_SPACING))
      end
      k = k+1
      self._dwidth = max(self._dwidth, TkListItem_Init(item))
    end
  end

  TkControls_Init(self)

  self:SetSize(self._dwidth , (k*TK_LIST_ITEM_HEIGHT)+(TK_LIST_PADDING*2)+(k*TK_LIST_SPACING)+TK_LIST_HEADING_SIZE)
end

--- Set up for a non-list-style panel, no iterative controls
function TkPanel_Init(self)
  self._dwidth = self:GetWidth()
  TkControls_Init(self)
  --self:SetSize(self._dwidth , (k*TK_LIST_ITEM_HEIGHT)+(TK_LIST_PADDING*2)+(k*TK_LIST_SPACING)+TK_LIST_HEADING_SIZE)
end