Nenue@6: --- Dialog Generator Nenue@6: -- @file-author@ Nenue@6: -- @project-revision@ @project-hash@ Nenue@6: -- @file-revision@ @file-hash@ Nenue@6: -- Created: 1/1/2016 3:37 PM Nenue@6: --- Framescript template for generating intelligible dialog panels Nenue@6: --[[ Nenue@6: -- Frame << TkListFrame Nenue@6: -- { Nenue@6: -- Frame << TkListItem <-- Any number of list item frames with parentArray="rows" Nenue@6: -- { Nenue@6: :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: <-- Any layered region of child frame with parentArray=opts" Nenue@6: } Nenue@6: Button <-- Any frame with parentArray="buttons" Nenue@6: Nenue@6: .Click (button, list) <-- Defines results of using a control button Nenue@6: .Check (button, row, list) <-- Defines results of operating a row widget Nenue@6: .Wheel (list, delta) <-- Defines response to mousewheel action over the list panel Nenue@6: } Nenue@6: Nenue@6: Globals: Nenue@6: TkList_Init ( object, values, offset, numRows ) Nenue@6: Takes the return from CreateFrame and a table of values and establishes a scrollable list interface. Nenue@6: Nenue@6: TkPanel_Init ( object ) Nenue@6: TkList_Init without the scrollable list operations. Lines up control buttons and nothing else. Nenue@6: --]] Nenue@6: local TK_LIST_SPACING = 1 Nenue@6: local TK_LIST_PADDING = 3 Nenue@6: local TK_LIST_HEADING_SIZE = 26 Nenue@6: local TK_LIST_ITEM_HEIGHT = 24 Nenue@6: local TK_LIST_DISPLAY_ITEMS = 10 Nenue@6: Nenue@6: local print = function(...) Nenue@6: if _G.Devian and _G.DevianDB.workspace ~= 1 then Nenue@6: _G.print('Xui', ...) Nenue@6: end Nenue@6: end Nenue@6: -- GLOBALS: TkList_SetView, TkList_Init, Turok Nenue@6: local type, error, pairs, ipairs, tonumber, max, CreateFrame = type, error, pairs, ipairs, tonumber, math.max, CreateFrame Nenue@6: local checkval = function(valtype, t, fallback) Nenue@6: return (type(t) == valtype) and t or (fallback or error('Expected table reference, got '..type(t))) Nenue@6: end Nenue@6: local tableval = function(t, fallback) Nenue@6: return checkval('table', t, fallback or {}) Nenue@6: end Nenue@6: local funcval = function(f, fallback) Nenue@6: return checkval('function', f, fallback or function() end) Nenue@6: end Nenue@6: Nenue@6: --- Orders list row Nenue@6: -- Does an ipairs iteration over self.opts and distributes the referenced objects along the horizontal axis of 'self' Nenue@6: -- Note that members are only aligned horizontally; no column alignment is done. Widths can be set by datafunc to accomplish that. Nenue@6: local function TkListItem_Init (listrow) Nenue@6: if not listrow.opts then Nenue@6: print('no options to enumerate') Nenue@6: return Nenue@6: end Nenue@6: local rwidth = TK_LIST_PADDING*2 Nenue@6: for i, z in pairs(listrow.opts) do Nenue@6: if i > 1 then Nenue@6: z:SetPoint('LEFT', listrow.opts[i-1], 'RIGHT', TK_LIST_SPACING, 0) Nenue@6: else Nenue@6: z:SetPoint('LEFT', listrow, 'LEFT', TK_LIST_PADDING, 0) Nenue@6: end Nenue@6: rwidth = rwidth + z:GetWidth()+TK_LIST_SPACING Nenue@6: z:Show() Nenue@6: end Nenue@6: listrow:SetSize(rwidth-TK_LIST_PADDING*2,TK_LIST_ITEM_HEIGHT) Nenue@6: listrow:Show() Nenue@6: print(rwidth) Nenue@6: return rwidth Nenue@6: end Nenue@6: Nenue@6: Nenue@6: --- Nenue@6: local function TkControls_Init(self) Nenue@6: local buttonsize = (self._dwidth - (#self.buttons -1) * TK_LIST_SPACING - TK_LIST_PADDING*2) / #self.buttons Nenue@6: for n, b in ipairs(self.buttons) do Nenue@6: --print('Spirit', buttonsize) Nenue@6: b:SetWidth(buttonsize) Nenue@6: b:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', buttonsize* (n-1) + TK_LIST_SPACING * (n-1) + TK_LIST_PADDING, -TK_LIST_PADDING) Nenue@6: end Nenue@6: self.controls:SetHeight(self.buttons[1]:GetHeight()+ TK_LIST_PADDING*2) Nenue@6: end Nenue@6: Nenue@6: --- Populates the list frame with items Nenue@6: function TkList_SetView(self, start_num, num_rows) Nenue@6: print(self, start_num, num_rows) Nenue@6: if not start_num then Nenue@6: start_num = self.offset Nenue@6: end Nenue@6: Nenue@6: if not num_rows then Nenue@6: num_rows = self.num_rows Nenue@6: end Nenue@6: Nenue@6: if start_num > #self.info then Nenue@6: start_num = #self.info - #self.info % num_rows Nenue@6: elseif start_num < 1 then Nenue@6: start_num = 1 Nenue@6: end Nenue@6: Nenue@6: print(' ', self:GetName(), start_num, num_rows, #self.info) Nenue@6: self.offset = start_num Nenue@6: Nenue@6: for draw_num = 1, num_rows do Nenue@6: local actual_row = draw_num + start_num - 1 Nenue@6: if not self.rows[draw_num] then Nenue@6: self.rows[draw_num] = CreateFrame('Frame', self:GetName()..'_Option_'..draw_num, self, 'TurokListItem') Nenue@6: self.rows[draw_num]:SetHeight(TK_LIST_ITEM_HEIGHT) Nenue@6: self.rows[draw_num].row_num = draw_num Nenue@6: end Nenue@6: self.rows[draw_num].actual_row = actual_row Nenue@6: local row = self.rows[draw_num] Nenue@6: if self.info[actual_row] then Nenue@6: print( actual_row, draw_num) Nenue@6: self.GetRow(row, self.info, actual_row, draw_num) Nenue@6: row:Show() Nenue@6: else Nenue@6: print('|cFF888888'..actual_row, draw_num) Nenue@6: row:Hide() Nenue@6: end Nenue@6: row:SetParent(self) Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: --- Prime TkListFrame template-spawn for use Nenue@6: -- @param self frame object to list-ify Nenue@6: -- @param info array of list item values Nenue@6: -- @param datafunc function that takes 1) frame object 2) info table 3) index number 4) row number Nenue@6: -- @param offset starting offset for initial view Nenue@6: function TkList_Init (self, info, offset, num_rows) Nenue@6: -- error checking Nenue@6: --[[if type(info) ~= 'table' then Nenue@6: error('arg #2 info must be an associative array') Nenue@6: end Nenue@6: if type(datafunc) ~= 'function' then Nenue@6: error('arg #3 needs a funcref or method name from the frame object') Nenue@6: end Nenue@6: --]] Nenue@6: self.GetRow = funcval(self.GetRow, function() end) Nenue@6: self.info = tableval(info, {}) Nenue@6: for i, v in ipairs(info) do Nenue@6: print('Main', i, '=', v.spellName, v.spellTab) Nenue@6: self.max_row = i Nenue@6: end Nenue@6: print('Main', 'last row #', self.max_row) Nenue@6: Nenue@6: Nenue@6: -- obtain data contents Nenue@6: self._dwidth = 0 Nenue@6: self.rows = {} Nenue@6: self.offset = offset and offset or 1 Nenue@6: self.num_rows = (tonumber(num_rows) ~= nil) and num_rows or TK_LIST_DISPLAY_ITEMS Nenue@6: self.name:SetHeight(TK_LIST_HEADING_SIZE) Nenue@6: TkList_SetView(self, offset) Nenue@6: Nenue@6: -- sort out the proper width Nenue@6: local rwidth = 1 Nenue@6: local k = 0 Nenue@6: for n, item in ipairs(self.rows) do Nenue@6: print(item:GetName()) Nenue@6: if item:IsShown() then Nenue@6: if n > 1 then Nenue@6: item:SetPoint('TOPLEFT', self.rows[n-1], 'BOTTOMLEFT', 0, - TK_LIST_SPACING) Nenue@6: else Nenue@6: item:SetPoint('TOPLEFT', self, 'TOPLEFT', TK_LIST_PADDING, -(TK_LIST_PADDING+TK_LIST_HEADING_SIZE+TK_LIST_SPACING)) Nenue@6: end Nenue@6: k = k+1 Nenue@6: self._dwidth = max(self._dwidth, TkListItem_Init(item)) Nenue@6: end Nenue@6: end Nenue@6: Nenue@6: TkControls_Init(self) Nenue@6: Nenue@6: self:SetSize(self._dwidth , (k*TK_LIST_ITEM_HEIGHT)+(TK_LIST_PADDING*2)+(k*TK_LIST_SPACING)+TK_LIST_HEADING_SIZE) Nenue@6: end Nenue@6: Nenue@6: --- Set up for a non-list-style panel, no iterative controls Nenue@6: function TkPanel_Init(self) Nenue@6: self._dwidth = self:GetWidth() Nenue@6: TkControls_Init(self) Nenue@6: --self:SetSize(self._dwidth , (k*TK_LIST_ITEM_HEIGHT)+(TK_LIST_PADDING*2)+(k*TK_LIST_SPACING)+TK_LIST_HEADING_SIZE) Nenue@6: end