| 
Nenue@6
 | 
     1 --- Dialog Generator
 | 
| 
Nenue@6
 | 
     2 -- @file-author@
 | 
| 
Nenue@6
 | 
     3 -- @project-revision@ @project-hash@
 | 
| 
Nenue@6
 | 
     4 -- @file-revision@ @file-hash@
 | 
| 
Nenue@6
 | 
     5 -- Created: 1/1/2016 3:37 PM
 | 
| 
Nenue@6
 | 
     6 --- Framescript template for generating intelligible dialog panels
 | 
| 
Nenue@6
 | 
     7 --[[
 | 
| 
Nenue@6
 | 
     8 -- Frame << TkListFrame
 | 
| 
Nenue@6
 | 
     9 -- {
 | 
| 
Nenue@6
 | 
    10 --    Frame <rows> << TkListItem                <--  Any number of list item frames with parentArray="rows"
 | 
| 
Nenue@6
 | 
    11 --    {
 | 
| 
Nenue@6
 | 
    12           :GetRow(row, values, id, offset)      <--  Populates the uiobjects that make up the given row, with data from values[id], on display row offset
 | 
| 
Nenue@6
 | 
    13           <opts>                                <--  Any layered region of child frame with parentArray=opts"
 | 
| 
Nenue@6
 | 
    14       }
 | 
| 
Nenue@6
 | 
    15       Button <buttons>                      <--  Any frame with parentArray="buttons"
 | 
| 
Nenue@6
 | 
    16 
 | 
| 
Nenue@6
 | 
    17       .Click (button, list)                 <--  Defines results of using a control button
 | 
| 
Nenue@6
 | 
    18       .Check (button, row, list)            <--  Defines results of operating a row widget
 | 
| 
Nenue@6
 | 
    19       .Wheel (list, delta)                  <--  Defines response to mousewheel action over the list panel
 | 
| 
Nenue@6
 | 
    20    }
 | 
| 
Nenue@6
 | 
    21 
 | 
| 
Nenue@6
 | 
    22    Globals:
 | 
| 
Nenue@6
 | 
    23    TkList_Init ( object, values, offset, numRows )
 | 
| 
Nenue@6
 | 
    24     Takes the return from CreateFrame and a table of values and establishes a scrollable list interface.
 | 
| 
Nenue@6
 | 
    25 
 | 
| 
Nenue@6
 | 
    26    TkPanel_Init ( object )
 | 
| 
Nenue@6
 | 
    27     TkList_Init without the scrollable list operations. Lines up control buttons and nothing else.
 | 
| 
Nenue@6
 | 
    28 --]]
 | 
| 
Nenue@6
 | 
    29 local TK_LIST_SPACING = 1
 | 
| 
Nenue@6
 | 
    30 local TK_LIST_PADDING = 3
 | 
| 
Nenue@6
 | 
    31 local TK_LIST_HEADING_SIZE = 26
 | 
| 
Nenue@6
 | 
    32 local TK_LIST_ITEM_HEIGHT = 24
 | 
| 
Nenue@6
 | 
    33 local TK_LIST_DISPLAY_ITEMS = 10
 | 
| 
Nenue@6
 | 
    34 
 | 
| 
Nenue@6
 | 
    35 local print = function(...)
 | 
| 
Nenue@6
 | 
    36   if _G.Devian and _G.DevianDB.workspace ~= 1 then
 | 
| 
Nenue@6
 | 
    37     _G.print('Xui', ...)
 | 
| 
Nenue@6
 | 
    38   end
 | 
| 
Nenue@6
 | 
    39 end
 | 
| 
Nenue@6
 | 
    40 -- GLOBALS: TkList_SetView, TkList_Init, Turok
 | 
| 
Nenue@6
 | 
    41 local type, error, pairs, ipairs, tonumber, max, CreateFrame = type, error, pairs, ipairs, tonumber, math.max, CreateFrame
 | 
| 
Nenue@6
 | 
    42 local checkval = function(valtype, t, fallback)
 | 
| 
Nenue@6
 | 
    43   return (type(t) == valtype) and t or (fallback or error('Expected table reference, got '..type(t)))
 | 
| 
Nenue@6
 | 
    44 end
 | 
| 
Nenue@6
 | 
    45 local tableval = function(t, fallback)
 | 
| 
Nenue@6
 | 
    46   return checkval('table', t, fallback or {})
 | 
| 
Nenue@6
 | 
    47 end
 | 
| 
Nenue@6
 | 
    48 local funcval = function(f, fallback)
 | 
| 
Nenue@6
 | 
    49   return checkval('function', f, fallback or function() end)
 | 
| 
Nenue@6
 | 
    50 end
 | 
| 
Nenue@6
 | 
    51 
 | 
| 
Nenue@6
 | 
    52 --- Orders list row
 | 
| 
Nenue@6
 | 
    53 -- Does an ipairs iteration over self.opts and distributes the referenced objects along the horizontal axis of 'self'
 | 
| 
Nenue@6
 | 
    54 -- Note that members are only aligned horizontally; no column alignment is done. Widths can be set by datafunc to accomplish that.
 | 
| 
Nenue@6
 | 
    55 local function TkListItem_Init (listrow)
 | 
| 
Nenue@6
 | 
    56   if not listrow.opts then
 | 
| 
Nenue@6
 | 
    57     print('no options to enumerate')
 | 
| 
Nenue@6
 | 
    58     return
 | 
| 
Nenue@6
 | 
    59   end
 | 
| 
Nenue@6
 | 
    60   local rwidth = TK_LIST_PADDING*2
 | 
| 
Nenue@6
 | 
    61   for i, z in pairs(listrow.opts) do
 | 
| 
Nenue@6
 | 
    62     if i > 1 then
 | 
| 
Nenue@6
 | 
    63       z:SetPoint('LEFT', listrow.opts[i-1], 'RIGHT', TK_LIST_SPACING, 0)
 | 
| 
Nenue@6
 | 
    64     else
 | 
| 
Nenue@6
 | 
    65       z:SetPoint('LEFT', listrow, 'LEFT', TK_LIST_PADDING, 0)
 | 
| 
Nenue@6
 | 
    66     end
 | 
| 
Nenue@6
 | 
    67     rwidth = rwidth + z:GetWidth()+TK_LIST_SPACING
 | 
| 
Nenue@6
 | 
    68     z:Show()
 | 
| 
Nenue@6
 | 
    69   end
 | 
| 
Nenue@6
 | 
    70   listrow:SetSize(rwidth-TK_LIST_PADDING*2,TK_LIST_ITEM_HEIGHT)
 | 
| 
Nenue@6
 | 
    71   listrow:Show()
 | 
| 
Nenue@6
 | 
    72   print(rwidth)
 | 
| 
Nenue@6
 | 
    73   return rwidth
 | 
| 
Nenue@6
 | 
    74 end
 | 
| 
Nenue@6
 | 
    75 
 | 
| 
Nenue@6
 | 
    76 
 | 
| 
Nenue@6
 | 
    77 ---
 | 
| 
Nenue@6
 | 
    78 local function TkControls_Init(self)
 | 
| 
Nenue@6
 | 
    79   local buttonsize = (self._dwidth - (#self.buttons -1) * TK_LIST_SPACING - TK_LIST_PADDING*2) / #self.buttons
 | 
| 
Nenue@6
 | 
    80   for n, b in ipairs(self.buttons) do
 | 
| 
Nenue@6
 | 
    81     --print('Spirit', buttonsize)
 | 
| 
Nenue@6
 | 
    82     b:SetWidth(buttonsize)
 | 
| 
Nenue@6
 | 
    83     b:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', buttonsize* (n-1) + TK_LIST_SPACING * (n-1) + TK_LIST_PADDING, -TK_LIST_PADDING)
 | 
| 
Nenue@6
 | 
    84   end
 | 
| 
Nenue@6
 | 
    85   self.controls:SetHeight(self.buttons[1]:GetHeight()+ TK_LIST_PADDING*2)
 | 
| 
Nenue@6
 | 
    86 end
 | 
| 
Nenue@6
 | 
    87 
 | 
| 
Nenue@6
 | 
    88 --- Populates the list frame with items
 | 
| 
Nenue@6
 | 
    89 function TkList_SetView(self, start_num, num_rows)
 | 
| 
Nenue@6
 | 
    90   print(self, start_num, num_rows)
 | 
| 
Nenue@6
 | 
    91   if not start_num then
 | 
| 
Nenue@6
 | 
    92     start_num = self.offset
 | 
| 
Nenue@6
 | 
    93   end
 | 
| 
Nenue@6
 | 
    94 
 | 
| 
Nenue@6
 | 
    95   if not num_rows then
 | 
| 
Nenue@6
 | 
    96     num_rows = self.num_rows
 | 
| 
Nenue@6
 | 
    97   end
 | 
| 
Nenue@6
 | 
    98 
 | 
| 
Nenue@6
 | 
    99   if start_num > #self.info then
 | 
| 
Nenue@6
 | 
   100     start_num = #self.info - #self.info % num_rows
 | 
| 
Nenue@6
 | 
   101   elseif start_num < 1 then
 | 
| 
Nenue@6
 | 
   102     start_num = 1
 | 
| 
Nenue@6
 | 
   103   end
 | 
| 
Nenue@6
 | 
   104 
 | 
| 
Nenue@6
 | 
   105   print('  ', self:GetName(), start_num, num_rows, #self.info)
 | 
| 
Nenue@6
 | 
   106   self.offset = start_num
 | 
| 
Nenue@6
 | 
   107 
 | 
| 
Nenue@6
 | 
   108   for draw_num = 1, num_rows do
 | 
| 
Nenue@6
 | 
   109     local actual_row = draw_num + start_num - 1
 | 
| 
Nenue@6
 | 
   110     if not self.rows[draw_num] then
 | 
| 
Nenue@6
 | 
   111       self.rows[draw_num] = CreateFrame('Frame', self:GetName()..'_Option_'..draw_num, self, 'TurokListItem')
 | 
| 
Nenue@6
 | 
   112       self.rows[draw_num]:SetHeight(TK_LIST_ITEM_HEIGHT)
 | 
| 
Nenue@6
 | 
   113       self.rows[draw_num].row_num = draw_num
 | 
| 
Nenue@6
 | 
   114     end
 | 
| 
Nenue@6
 | 
   115     self.rows[draw_num].actual_row = actual_row
 | 
| 
Nenue@6
 | 
   116     local row = self.rows[draw_num]
 | 
| 
Nenue@6
 | 
   117     if self.info[actual_row] then
 | 
| 
Nenue@6
 | 
   118       print( actual_row, draw_num)
 | 
| 
Nenue@6
 | 
   119       self.GetRow(row, self.info, actual_row, draw_num)
 | 
| 
Nenue@6
 | 
   120       row:Show()
 | 
| 
Nenue@6
 | 
   121     else
 | 
| 
Nenue@6
 | 
   122       print('|cFF888888'..actual_row, draw_num)
 | 
| 
Nenue@6
 | 
   123       row:Hide()
 | 
| 
Nenue@6
 | 
   124     end
 | 
| 
Nenue@6
 | 
   125     row:SetParent(self)
 | 
| 
Nenue@6
 | 
   126   end
 | 
| 
Nenue@6
 | 
   127 end
 | 
| 
Nenue@6
 | 
   128 
 | 
| 
Nenue@6
 | 
   129 --- Prime TkListFrame template-spawn for use
 | 
| 
Nenue@6
 | 
   130 -- @param self frame object to list-ify
 | 
| 
Nenue@6
 | 
   131 -- @param info array of list item values
 | 
| 
Nenue@6
 | 
   132 -- @param datafunc function that takes 1) frame object 2) info table 3) index number 4) row number
 | 
| 
Nenue@6
 | 
   133 -- @param offset starting offset for initial view
 | 
| 
Nenue@6
 | 
   134 function TkList_Init (self, info, offset, num_rows)
 | 
| 
Nenue@6
 | 
   135   -- error checking
 | 
| 
Nenue@6
 | 
   136   --[[if type(info) ~= 'table' then
 | 
| 
Nenue@6
 | 
   137     error('arg #2 info must be an associative array')
 | 
| 
Nenue@6
 | 
   138   end
 | 
| 
Nenue@6
 | 
   139   if type(datafunc) ~= 'function' then
 | 
| 
Nenue@6
 | 
   140     error('arg #3 needs a funcref or method name from the frame object')
 | 
| 
Nenue@6
 | 
   141   end
 | 
| 
Nenue@6
 | 
   142   --]]
 | 
| 
Nenue@6
 | 
   143   self.GetRow = funcval(self.GetRow, function() end)
 | 
| 
Nenue@6
 | 
   144   self.info = tableval(info, {})
 | 
| 
Nenue@6
 | 
   145   for i, v in ipairs(info) do
 | 
| 
Nenue@6
 | 
   146     print('Main', i, '=', v.spellName, v.spellTab)
 | 
| 
Nenue@6
 | 
   147     self.max_row = i
 | 
| 
Nenue@6
 | 
   148   end
 | 
| 
Nenue@6
 | 
   149   print('Main', 'last row #', self.max_row)
 | 
| 
Nenue@6
 | 
   150 
 | 
| 
Nenue@6
 | 
   151 
 | 
| 
Nenue@6
 | 
   152   -- obtain data contents
 | 
| 
Nenue@6
 | 
   153   self._dwidth = 0
 | 
| 
Nenue@6
 | 
   154   self.rows = {}
 | 
| 
Nenue@6
 | 
   155   self.offset = offset and offset or 1
 | 
| 
Nenue@6
 | 
   156   self.num_rows = (tonumber(num_rows) ~= nil) and num_rows or TK_LIST_DISPLAY_ITEMS
 | 
| 
Nenue@6
 | 
   157   self.name:SetHeight(TK_LIST_HEADING_SIZE)
 | 
| 
Nenue@6
 | 
   158   TkList_SetView(self, offset)
 | 
| 
Nenue@6
 | 
   159 
 | 
| 
Nenue@6
 | 
   160   -- sort out the proper width
 | 
| 
Nenue@6
 | 
   161   local rwidth = 1
 | 
| 
Nenue@6
 | 
   162   local  k = 0
 | 
| 
Nenue@6
 | 
   163   for n, item in ipairs(self.rows) do
 | 
| 
Nenue@6
 | 
   164     print(item:GetName())
 | 
| 
Nenue@6
 | 
   165     if item:IsShown() then
 | 
| 
Nenue@6
 | 
   166       if n > 1 then
 | 
| 
Nenue@6
 | 
   167         item:SetPoint('TOPLEFT', self.rows[n-1], 'BOTTOMLEFT', 0, - TK_LIST_SPACING)
 | 
| 
Nenue@6
 | 
   168       else
 | 
| 
Nenue@6
 | 
   169         item:SetPoint('TOPLEFT', self, 'TOPLEFT', TK_LIST_PADDING, -(TK_LIST_PADDING+TK_LIST_HEADING_SIZE+TK_LIST_SPACING))
 | 
| 
Nenue@6
 | 
   170       end
 | 
| 
Nenue@6
 | 
   171       k = k+1
 | 
| 
Nenue@6
 | 
   172       self._dwidth = max(self._dwidth, TkListItem_Init(item))
 | 
| 
Nenue@6
 | 
   173     end
 | 
| 
Nenue@6
 | 
   174   end
 | 
| 
Nenue@6
 | 
   175 
 | 
| 
Nenue@6
 | 
   176   TkControls_Init(self)
 | 
| 
Nenue@6
 | 
   177 
 | 
| 
Nenue@6
 | 
   178   self:SetSize(self._dwidth , (k*TK_LIST_ITEM_HEIGHT)+(TK_LIST_PADDING*2)+(k*TK_LIST_SPACING)+TK_LIST_HEADING_SIZE)
 | 
| 
Nenue@6
 | 
   179 end
 | 
| 
Nenue@6
 | 
   180 
 | 
| 
Nenue@6
 | 
   181 --- Set up for a non-list-style panel, no iterative controls
 | 
| 
Nenue@6
 | 
   182 function TkPanel_Init(self)
 | 
| 
Nenue@6
 | 
   183   self._dwidth = self:GetWidth()
 | 
| 
Nenue@6
 | 
   184   TkControls_Init(self)
 | 
| 
Nenue@6
 | 
   185   --self:SetSize(self._dwidth , (k*TK_LIST_ITEM_HEIGHT)+(TK_LIST_PADDING*2)+(k*TK_LIST_SPACING)+TK_LIST_HEADING_SIZE)
 | 
| 
Nenue@6
 | 
   186 end
 |