Asa@0
|
1 local AceGUI = LibStub("AceGUI-3.0")
|
Asa@0
|
2
|
Asa@0
|
3 -- Lua APIs
|
Asa@0
|
4 local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
Asa@0
|
5 local math_min, math_max, floor = math.min, math.max, floor
|
Asa@0
|
6 local select, tremove, unpack = select, table.remove, unpack
|
Asa@0
|
7
|
Asa@0
|
8 -- WoW APIs
|
Asa@0
|
9 local CreateFrame, UIParent = CreateFrame, UIParent
|
Asa@0
|
10
|
Asa@0
|
11 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
Asa@0
|
12 -- List them here for Mikk's FindGlobals script
|
Asa@0
|
13 -- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
|
Asa@0
|
14
|
Asa@0
|
15 -- Recycling functions
|
Asa@0
|
16 local new, del
|
Asa@0
|
17 do
|
Asa@0
|
18 local pool = setmetatable({},{__mode='k'})
|
Asa@0
|
19 function new()
|
Asa@0
|
20 local t = next(pool)
|
Asa@0
|
21 if t then
|
Asa@0
|
22 pool[t] = nil
|
Asa@0
|
23 return t
|
Asa@0
|
24 else
|
Asa@0
|
25 return {}
|
Asa@0
|
26 end
|
Asa@0
|
27 end
|
Asa@0
|
28 function del(t)
|
Asa@0
|
29 for k in pairs(t) do
|
Asa@0
|
30 t[k] = nil
|
Asa@0
|
31 end
|
Asa@0
|
32 pool[t] = true
|
Asa@0
|
33 end
|
Asa@0
|
34 end
|
Asa@0
|
35
|
Asa@0
|
36 --------------
|
Asa@0
|
37 -- TreeView --
|
Asa@0
|
38 --------------
|
Asa@0
|
39
|
Asa@0
|
40 do
|
Asa@0
|
41 local Type = "TreeGroup"
|
Asa@0
|
42 local Version = 23
|
Asa@0
|
43
|
Asa@0
|
44 local DEFAULT_TREE_WIDTH = 175
|
Asa@0
|
45 local DEFAULT_TREE_SIZABLE = true
|
Asa@0
|
46
|
Asa@0
|
47 local PaneBackdrop = {
|
Asa@0
|
48 bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
Asa@0
|
49 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
Asa@0
|
50 tile = true, tileSize = 16, edgeSize = 16,
|
Asa@0
|
51 insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
Asa@0
|
52 }
|
Asa@0
|
53
|
Asa@0
|
54 local DraggerBackdrop = {
|
Asa@0
|
55 bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
Asa@0
|
56 edgeFile = nil,
|
Asa@0
|
57 tile = true, tileSize = 16, edgeSize = 0,
|
Asa@0
|
58 insets = { left = 3, right = 3, top = 7, bottom = 7 }
|
Asa@0
|
59 }
|
Asa@0
|
60
|
Asa@0
|
61 local function OnAcquire(self)
|
Asa@0
|
62 self:SetTreeWidth(DEFAULT_TREE_WIDTH,DEFAULT_TREE_SIZABLE)
|
Asa@0
|
63 self:EnableButtonTooltips(true)
|
Asa@0
|
64 end
|
Asa@0
|
65
|
Asa@0
|
66 local function OnRelease(self)
|
Asa@0
|
67
|
Asa@0
|
68 self.frame:ClearAllPoints()
|
Asa@0
|
69 self.frame:Hide()
|
Asa@0
|
70 self.status = nil
|
Asa@0
|
71 for k, v in pairs(self.localstatus) do
|
Asa@0
|
72 if k == "groups" then
|
Asa@0
|
73 for k2 in pairs(v) do
|
Asa@0
|
74 v[k2] = nil
|
Asa@0
|
75 end
|
Asa@0
|
76 else
|
Asa@0
|
77 self.localstatus[k] = nil
|
Asa@0
|
78 end
|
Asa@0
|
79 end
|
Asa@0
|
80 self.localstatus.scrollvalue = 0
|
Asa@0
|
81 self.localstatus.treewidth = DEFAULT_TREE_WIDTH
|
Asa@0
|
82 self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
|
Asa@0
|
83 end
|
Asa@0
|
84
|
Asa@0
|
85 local function GetButtonParents(line)
|
Asa@0
|
86 local parent = line.parent
|
Asa@0
|
87 if parent and parent.value then
|
Asa@0
|
88 return parent.value, GetButtonParents(parent)
|
Asa@0
|
89 end
|
Asa@0
|
90 end
|
Asa@0
|
91
|
Asa@0
|
92 local function GetButtonUniqueValue(line)
|
Asa@0
|
93 local parent = line.parent
|
Asa@0
|
94 if parent and parent.value then
|
Asa@0
|
95 return GetButtonUniqueValue(parent).."\001"..line.value
|
Asa@0
|
96 else
|
Asa@0
|
97 return line.value
|
Asa@0
|
98 end
|
Asa@0
|
99 end
|
Asa@0
|
100
|
Asa@0
|
101 local function ButtonOnClick(this)
|
Asa@0
|
102 local self = this.obj
|
Asa@0
|
103 self:Fire("OnClick",this.uniquevalue, this.selected)
|
Asa@0
|
104 if not this.selected then
|
Asa@0
|
105 self:SetSelected(this.uniquevalue)
|
Asa@0
|
106 this.selected = true
|
Asa@0
|
107 this:LockHighlight()
|
Asa@0
|
108 self:RefreshTree()
|
Asa@0
|
109 end
|
Asa@0
|
110 AceGUI:ClearFocus()
|
Asa@0
|
111 end
|
Asa@0
|
112
|
Asa@0
|
113 local function ExpandOnClick(this)
|
Asa@0
|
114 local button = this.button
|
Asa@0
|
115 local self = button.obj
|
Asa@0
|
116 local status = (self.status or self.localstatus).groups
|
Asa@0
|
117 status[button.uniquevalue] = not status[button.uniquevalue]
|
Asa@0
|
118 self:RefreshTree()
|
Asa@0
|
119 end
|
Asa@0
|
120
|
Asa@0
|
121 local function ButtonOnDoubleClick(button)
|
Asa@0
|
122 local self = button.obj
|
Asa@0
|
123 local status = self.status or self.localstatus
|
Asa@0
|
124 local status = (self.status or self.localstatus).groups
|
Asa@0
|
125 status[button.uniquevalue] = not status[button.uniquevalue]
|
Asa@0
|
126 self:RefreshTree()
|
Asa@0
|
127 end
|
Asa@0
|
128
|
Asa@0
|
129 local function EnableButtonTooltips(self, enable)
|
Asa@0
|
130 self.enabletooltips = enable
|
Asa@0
|
131 end
|
Asa@0
|
132
|
Asa@0
|
133 local function Button_OnEnter(this)
|
Asa@0
|
134 local self = this.obj
|
Asa@0
|
135 self:Fire("OnButtonEnter", this.uniquevalue, this)
|
Asa@0
|
136
|
Asa@0
|
137 if self.enabletooltips then
|
Asa@0
|
138 GameTooltip:SetOwner(this, "ANCHOR_NONE")
|
Asa@0
|
139 GameTooltip:SetPoint("LEFT",this,"RIGHT")
|
Asa@0
|
140 GameTooltip:SetText(this.text:GetText() or "", 1, .82, 0, 1)
|
Asa@0
|
141
|
Asa@0
|
142 GameTooltip:Show()
|
Asa@0
|
143 end
|
Asa@0
|
144 end
|
Asa@0
|
145
|
Asa@0
|
146 local function Button_OnLeave(this)
|
Asa@0
|
147 local self = this.obj
|
Asa@0
|
148 self:Fire("OnButtonLeave", this.uniquevalue, this)
|
Asa@0
|
149
|
Asa@0
|
150 if self.enabletooltips then
|
Asa@0
|
151 GameTooltip:Hide()
|
Asa@0
|
152 end
|
Asa@0
|
153 end
|
Asa@0
|
154
|
Asa@0
|
155
|
Asa@0
|
156 local buttoncount = 1
|
Asa@0
|
157 local function CreateButton(self)
|
Asa@0
|
158 local button = CreateFrame("Button",("AceGUI30TreeButton%d"):format(buttoncount),self.treeframe, "OptionsListButtonTemplate")
|
Asa@0
|
159 buttoncount = buttoncount + 1
|
Asa@0
|
160 button.obj = self
|
Asa@0
|
161
|
Asa@0
|
162 local icon = button:CreateTexture(nil, "OVERLAY")
|
Asa@0
|
163 icon:SetWidth(14)
|
Asa@0
|
164 icon:SetHeight(14)
|
Asa@0
|
165 button.icon = icon
|
Asa@0
|
166
|
Asa@0
|
167 button:SetScript("OnClick",ButtonOnClick)
|
Asa@0
|
168 button:SetScript("OnDoubleClick", ButtonOnDoubleClick)
|
Asa@0
|
169 button:SetScript("OnEnter",Button_OnEnter)
|
Asa@0
|
170 button:SetScript("OnLeave",Button_OnLeave)
|
Asa@0
|
171
|
Asa@0
|
172 button.toggle.button = button
|
Asa@0
|
173 button.toggle:SetScript("OnClick",ExpandOnClick)
|
Asa@0
|
174
|
Asa@0
|
175 return button
|
Asa@0
|
176 end
|
Asa@0
|
177
|
Asa@0
|
178 local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
|
Asa@0
|
179 local self = button.obj
|
Asa@0
|
180 local toggle = button.toggle
|
Asa@0
|
181 local frame = self.frame
|
Asa@0
|
182 local text = treeline.text or ""
|
Asa@0
|
183 local icon = treeline.icon
|
Asa@0
|
184 local iconCoords = treeline.iconCoords
|
Asa@0
|
185 local level = treeline.level
|
Asa@0
|
186 local value = treeline.value
|
Asa@0
|
187 local uniquevalue = treeline.uniquevalue
|
Asa@0
|
188 local disabled = treeline.disabled
|
Asa@0
|
189
|
Asa@0
|
190 button.treeline = treeline
|
Asa@0
|
191 button.value = value
|
Asa@0
|
192 button.uniquevalue = uniquevalue
|
Asa@0
|
193 if selected then
|
Asa@0
|
194 button:LockHighlight()
|
Asa@0
|
195 button.selected = true
|
Asa@0
|
196 else
|
Asa@0
|
197 button:UnlockHighlight()
|
Asa@0
|
198 button.selected = false
|
Asa@0
|
199 end
|
Asa@0
|
200 local normalTexture = button:GetNormalTexture()
|
Asa@0
|
201 local line = button.line
|
Asa@0
|
202 button.level = level
|
Asa@0
|
203 if ( level == 1 ) then
|
Asa@0
|
204 button:SetNormalFontObject("GameFontNormal")
|
Asa@0
|
205 button:SetHighlightFontObject("GameFontHighlight")
|
Asa@0
|
206 button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
Asa@0
|
207 else
|
Asa@0
|
208 button:SetNormalFontObject("GameFontHighlightSmall")
|
Asa@0
|
209 button:SetHighlightFontObject("GameFontHighlightSmall")
|
Asa@0
|
210 button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
Asa@0
|
211 end
|
Asa@0
|
212
|
Asa@0
|
213 if disabled then
|
Asa@0
|
214 button:EnableMouse(false)
|
Asa@0
|
215 button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
|
Asa@0
|
216 else
|
Asa@0
|
217 button.text:SetText(text)
|
Asa@0
|
218 button:EnableMouse(true)
|
Asa@0
|
219 end
|
Asa@0
|
220
|
Asa@0
|
221 if icon then
|
Asa@0
|
222 button.icon:SetTexture(icon)
|
Asa@0
|
223 button.icon:SetPoint("LEFT", button, "LEFT", 8 * level, (level == 1) and 0 or 1)
|
Asa@0
|
224 else
|
Asa@0
|
225 button.icon:SetTexture(nil)
|
Asa@0
|
226 end
|
Asa@0
|
227
|
Asa@0
|
228 if iconCoords then
|
Asa@0
|
229 button.icon:SetTexCoord(unpack(iconCoords))
|
Asa@0
|
230 else
|
Asa@0
|
231 button.icon:SetTexCoord(0, 1, 0, 1)
|
Asa@0
|
232 end
|
Asa@0
|
233
|
Asa@0
|
234 if canExpand then
|
Asa@0
|
235 if not isExpanded then
|
Asa@0
|
236 toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
|
Asa@0
|
237 toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
|
Asa@0
|
238 else
|
Asa@0
|
239 toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
|
Asa@0
|
240 toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
|
Asa@0
|
241 end
|
Asa@0
|
242 toggle:Show()
|
Asa@0
|
243 else
|
Asa@0
|
244 toggle:Hide()
|
Asa@0
|
245 end
|
Asa@0
|
246 end
|
Asa@0
|
247
|
Asa@0
|
248
|
Asa@0
|
249 local function OnScrollValueChanged(this, value)
|
Asa@0
|
250 if this.obj.noupdate then return end
|
Asa@0
|
251 local self = this.obj
|
Asa@0
|
252 local status = self.status or self.localstatus
|
Asa@0
|
253 status.scrollvalue = value
|
Asa@0
|
254 self:RefreshTree()
|
Asa@0
|
255 AceGUI:ClearFocus()
|
Asa@0
|
256 end
|
Asa@0
|
257
|
Asa@0
|
258 -- called to set an external table to store status in
|
Asa@0
|
259 local function SetStatusTable(self, status)
|
Asa@0
|
260 assert(type(status) == "table")
|
Asa@0
|
261 self.status = status
|
Asa@0
|
262 if not status.groups then
|
Asa@0
|
263 status.groups = {}
|
Asa@0
|
264 end
|
Asa@0
|
265 if not status.scrollvalue then
|
Asa@0
|
266 status.scrollvalue = 0
|
Asa@0
|
267 end
|
Asa@0
|
268 if not status.treewidth then
|
Asa@0
|
269 status.treewidth = DEFAULT_TREE_WIDTH
|
Asa@0
|
270 end
|
Asa@0
|
271 if not status.treesizable then
|
Asa@0
|
272 status.treesizable = DEFAULT_TREE_SIZABLE
|
Asa@0
|
273 end
|
Asa@0
|
274 self:SetTreeWidth(status.treewidth,status.treesizable)
|
Asa@0
|
275 self:RefreshTree()
|
Asa@0
|
276 end
|
Asa@0
|
277
|
Asa@0
|
278 --sets the tree to be displayed
|
Asa@0
|
279 --[[
|
Asa@0
|
280 example tree
|
Asa@0
|
281
|
Asa@0
|
282 Alpha
|
Asa@0
|
283 Bravo
|
Asa@0
|
284 -Charlie
|
Asa@0
|
285 -Delta
|
Asa@0
|
286 -Echo
|
Asa@0
|
287 Foxtrot
|
Asa@0
|
288
|
Asa@0
|
289 tree = {
|
Asa@0
|
290 {
|
Asa@0
|
291 value = "A",
|
Asa@0
|
292 text = "Alpha"
|
Asa@0
|
293 },
|
Asa@0
|
294 {
|
Asa@0
|
295 value = "B",
|
Asa@0
|
296 text = "Bravo",
|
Asa@0
|
297 children = {
|
Asa@0
|
298 {
|
Asa@0
|
299 value = "C",
|
Asa@0
|
300 text = "Charlie"
|
Asa@0
|
301 },
|
Asa@0
|
302 {
|
Asa@0
|
303 value = "D",
|
Asa@0
|
304 text = "Delta"
|
Asa@0
|
305 children = {
|
Asa@0
|
306 {
|
Asa@0
|
307 value = "E",
|
Asa@0
|
308 text = "Echo"
|
Asa@0
|
309 }
|
Asa@0
|
310 }
|
Asa@0
|
311 }
|
Asa@0
|
312 }
|
Asa@0
|
313 },
|
Asa@0
|
314 {
|
Asa@0
|
315 value = "F",
|
Asa@0
|
316 text = "Foxtrot"
|
Asa@0
|
317 },
|
Asa@0
|
318 }
|
Asa@0
|
319 ]]
|
Asa@0
|
320 local function SetTree(self, tree, filter)
|
Asa@0
|
321 self.filter = filter
|
Asa@0
|
322 if tree then
|
Asa@0
|
323 assert(type(tree) == "table")
|
Asa@0
|
324 end
|
Asa@0
|
325 self.tree = tree
|
Asa@0
|
326 self:RefreshTree()
|
Asa@0
|
327 end
|
Asa@0
|
328
|
Asa@0
|
329 local function ShouldDisplayLevel(tree)
|
Asa@0
|
330 local result = false
|
Asa@0
|
331 for k, v in ipairs(tree) do
|
Asa@0
|
332 if v.children == nil and v.visible ~= false then
|
Asa@0
|
333 result = true
|
Asa@0
|
334 elseif v.children then
|
Asa@0
|
335 result = result or ShouldDisplayLevel(v.children)
|
Asa@0
|
336 end
|
Asa@0
|
337 if result then return result end
|
Asa@0
|
338 end
|
Asa@0
|
339 return false
|
Asa@0
|
340 end
|
Asa@0
|
341
|
Asa@0
|
342 local function addLine(self, v, tree, level, parent)
|
Asa@0
|
343 local line = new()
|
Asa@0
|
344 line.value = v.value
|
Asa@0
|
345 line.text = v.text
|
Asa@0
|
346 line.icon = v.icon
|
Asa@0
|
347 line.iconCoords = v.iconCoords
|
Asa@0
|
348 line.disabled = v.disabled
|
Asa@0
|
349 line.tree = tree
|
Asa@0
|
350 line.level = level
|
Asa@0
|
351 line.parent = parent
|
Asa@0
|
352 line.visible = v.visible
|
Asa@0
|
353 line.uniquevalue = GetButtonUniqueValue(line)
|
Asa@0
|
354 if v.children then
|
Asa@0
|
355 line.hasChildren = true
|
Asa@0
|
356 else
|
Asa@0
|
357 line.hasChildren = nil
|
Asa@0
|
358 end
|
Asa@0
|
359 self.lines[#self.lines+1] = line
|
Asa@0
|
360 return line
|
Asa@0
|
361 end
|
Asa@0
|
362
|
Asa@0
|
363 local function BuildLevel(self, tree, level, parent)
|
Asa@0
|
364 local groups = (self.status or self.localstatus).groups
|
Asa@0
|
365 local hasChildren = self.hasChildren
|
Asa@0
|
366
|
Asa@0
|
367 for i, v in ipairs(tree) do
|
Asa@0
|
368 if v.children then
|
Asa@0
|
369 if not self.filter or ShouldDisplayLevel(v.children) then
|
Asa@0
|
370 local line = addLine(self, v, tree, level, parent)
|
Asa@0
|
371 if groups[line.uniquevalue] then
|
Asa@0
|
372 self:BuildLevel(v.children, level+1, line)
|
Asa@0
|
373 end
|
Asa@0
|
374 end
|
Asa@0
|
375 elseif v.visible ~= false or not self.filter then
|
Asa@0
|
376 addLine(self, v, tree, level, parent)
|
Asa@0
|
377 end
|
Asa@0
|
378 end
|
Asa@0
|
379 end
|
Asa@0
|
380
|
Asa@0
|
381 --fire an update after one frame to catch the treeframes height
|
Asa@0
|
382 local function FirstFrameUpdate(this)
|
Asa@0
|
383 local self = this.obj
|
Asa@0
|
384 this:SetScript("OnUpdate",nil)
|
Asa@0
|
385 self:RefreshTree()
|
Asa@0
|
386 end
|
Asa@0
|
387
|
Asa@0
|
388 local function ResizeUpdate(this)
|
Asa@0
|
389 this.obj:RefreshTree()
|
Asa@0
|
390 end
|
Asa@0
|
391
|
Asa@0
|
392 local function RefreshTree(self)
|
Asa@0
|
393 local buttons = self.buttons
|
Asa@0
|
394 local lines = self.lines
|
Asa@0
|
395
|
Asa@0
|
396 for i, v in ipairs(buttons) do
|
Asa@0
|
397 v:Hide()
|
Asa@0
|
398 end
|
Asa@0
|
399 while lines[1] do
|
Asa@0
|
400 local t = tremove(lines)
|
Asa@0
|
401 for k in pairs(t) do
|
Asa@0
|
402 t[k] = nil
|
Asa@0
|
403 end
|
Asa@0
|
404 del(t)
|
Asa@0
|
405 end
|
Asa@0
|
406
|
Asa@0
|
407 if not self.tree then return end
|
Asa@0
|
408 --Build the list of visible entries from the tree and status tables
|
Asa@0
|
409 local status = self.status or self.localstatus
|
Asa@0
|
410 local groupstatus = status.groups
|
Asa@0
|
411 local tree = self.tree
|
Asa@0
|
412
|
Asa@0
|
413 local treeframe = self.treeframe
|
Asa@0
|
414
|
Asa@0
|
415 self:BuildLevel(tree, 1)
|
Asa@0
|
416
|
Asa@0
|
417 local numlines = #lines
|
Asa@0
|
418
|
Asa@0
|
419 local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
|
Asa@0
|
420
|
Asa@0
|
421 local first, last
|
Asa@0
|
422
|
Asa@0
|
423 if numlines <= maxlines then
|
Asa@0
|
424 --the whole tree fits in the frame
|
Asa@0
|
425 status.scrollvalue = 0
|
Asa@0
|
426 self:ShowScroll(false)
|
Asa@0
|
427 first, last = 1, numlines
|
Asa@0
|
428 else
|
Asa@0
|
429 self:ShowScroll(true)
|
Asa@0
|
430 --scrolling will be needed
|
Asa@0
|
431 self.noupdate = true
|
Asa@0
|
432 self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
|
Asa@0
|
433 --check if we are scrolled down too far
|
Asa@0
|
434 if numlines - status.scrollvalue < maxlines then
|
Asa@0
|
435 status.scrollvalue = numlines - maxlines
|
Asa@0
|
436 self.scrollbar:SetValue(status.scrollvalue)
|
Asa@0
|
437 end
|
Asa@0
|
438 self.noupdate = nil
|
Asa@0
|
439 first, last = status.scrollvalue+1, status.scrollvalue + maxlines
|
Asa@0
|
440 end
|
Asa@0
|
441
|
Asa@0
|
442 local buttonnum = 1
|
Asa@0
|
443 for i = first, last do
|
Asa@0
|
444 local line = lines[i]
|
Asa@0
|
445 local button = buttons[buttonnum]
|
Asa@0
|
446 if not button then
|
Asa@0
|
447 button = self:CreateButton()
|
Asa@0
|
448
|
Asa@0
|
449 buttons[buttonnum] = button
|
Asa@0
|
450 button:SetParent(treeframe)
|
Asa@0
|
451 button:SetFrameLevel(treeframe:GetFrameLevel()+1)
|
Asa@0
|
452 button:ClearAllPoints()
|
Asa@0
|
453 if i == 1 then
|
Asa@0
|
454 if self.showscroll then
|
Asa@0
|
455 button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
Asa@0
|
456 button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
|
Asa@0
|
457 else
|
Asa@0
|
458 button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
Asa@0
|
459 button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
|
Asa@0
|
460 end
|
Asa@0
|
461 else
|
Asa@0
|
462 button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
|
Asa@0
|
463 button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
|
Asa@0
|
464 end
|
Asa@0
|
465 end
|
Asa@0
|
466
|
Asa@0
|
467 UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
|
Asa@0
|
468 button:Show()
|
Asa@0
|
469 buttonnum = buttonnum + 1
|
Asa@0
|
470 end
|
Asa@0
|
471
|
Asa@0
|
472 end
|
Asa@0
|
473
|
Asa@0
|
474 local function SetSelected(self, value)
|
Asa@0
|
475 local status = self.status or self.localstatus
|
Asa@0
|
476 if status.selected ~= value then
|
Asa@0
|
477 status.selected = value
|
Asa@0
|
478 self:Fire("OnGroupSelected", value)
|
Asa@0
|
479 end
|
Asa@0
|
480 end
|
Asa@0
|
481
|
Asa@0
|
482 local function BuildUniqueValue(...)
|
Asa@0
|
483 local n = select('#', ...)
|
Asa@0
|
484 if n == 1 then
|
Asa@0
|
485 return ...
|
Asa@0
|
486 else
|
Asa@0
|
487 return (...).."\001"..BuildUniqueValue(select(2,...))
|
Asa@0
|
488 end
|
Asa@0
|
489 end
|
Asa@0
|
490
|
Asa@0
|
491 local function Select(self, uniquevalue, ...)
|
Asa@0
|
492 self.filter = false
|
Asa@0
|
493 local status = self.status or self.localstatus
|
Asa@0
|
494 local groups = status.groups
|
Asa@0
|
495 for i = 1, select('#', ...) do
|
Asa@0
|
496 groups[BuildUniqueValue(select(i, ...))] = true
|
Asa@0
|
497 end
|
Asa@0
|
498 status.selected = uniquevalue
|
Asa@0
|
499 self:RefreshTree()
|
Asa@0
|
500 self:Fire("OnGroupSelected", uniquevalue)
|
Asa@0
|
501 end
|
Asa@0
|
502
|
Asa@0
|
503 local function SelectByPath(self, ...)
|
Asa@0
|
504 self:Select(BuildUniqueValue(...), ...)
|
Asa@0
|
505 end
|
Asa@0
|
506
|
Asa@0
|
507 --Selects a tree node by UniqueValue
|
Asa@0
|
508 local function SelectByValue(self, uniquevalue)
|
Asa@0
|
509 self:Select(uniquevalue, ("\001"):split(uniquevalue))
|
Asa@0
|
510 end
|
Asa@0
|
511
|
Asa@0
|
512
|
Asa@0
|
513 local function ShowScroll(self, show)
|
Asa@0
|
514 self.showscroll = show
|
Asa@0
|
515 if show then
|
Asa@0
|
516 self.scrollbar:Show()
|
Asa@0
|
517 if self.buttons[1] then
|
Asa@0
|
518 self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
Asa@0
|
519 end
|
Asa@0
|
520 else
|
Asa@0
|
521 self.scrollbar:Hide()
|
Asa@0
|
522 if self.buttons[1] then
|
Asa@0
|
523 self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
Asa@0
|
524 end
|
Asa@0
|
525 end
|
Asa@0
|
526 end
|
Asa@0
|
527
|
Asa@0
|
528 local function OnWidthSet(self, width)
|
Asa@0
|
529 local content = self.content
|
Asa@0
|
530 local treeframe = self.treeframe
|
Asa@0
|
531 local status = self.status or self.localstatus
|
Asa@0
|
532 status.fullwidth = width
|
Asa@0
|
533
|
Asa@0
|
534 local contentwidth = width - status.treewidth - 20
|
Asa@0
|
535 if contentwidth < 0 then
|
Asa@0
|
536 contentwidth = 0
|
Asa@0
|
537 end
|
Asa@0
|
538 content:SetWidth(contentwidth)
|
Asa@0
|
539 content.width = contentwidth
|
Asa@0
|
540
|
Asa@0
|
541 local maxtreewidth = math_min(400, width - 50)
|
Asa@0
|
542
|
Asa@0
|
543 if maxtreewidth > 100 and status.treewidth > maxtreewidth then
|
Asa@0
|
544 self:SetTreeWidth(maxtreewidth, status.treesizable)
|
Asa@0
|
545 end
|
Asa@0
|
546 treeframe:SetMaxResize(maxtreewidth,1600)
|
Asa@0
|
547 end
|
Asa@0
|
548
|
Asa@0
|
549
|
Asa@0
|
550 local function OnHeightSet(self, height)
|
Asa@0
|
551 local content = self.content
|
Asa@0
|
552 local contentheight = height - 20
|
Asa@0
|
553 if contentheight < 0 then
|
Asa@0
|
554 contentheight = 0
|
Asa@0
|
555 end
|
Asa@0
|
556 content:SetHeight(contentheight)
|
Asa@0
|
557 content.height = contentheight
|
Asa@0
|
558 end
|
Asa@0
|
559
|
Asa@0
|
560
|
Asa@0
|
561 local function TreeOnMouseWheel(this, delta)
|
Asa@0
|
562 local self = this.obj
|
Asa@0
|
563 if self.showscroll then
|
Asa@0
|
564 local scrollbar = self.scrollbar
|
Asa@0
|
565 local min, max = scrollbar:GetMinMaxValues()
|
Asa@0
|
566 local value = scrollbar:GetValue()
|
Asa@0
|
567 local newvalue = math_min(max,math_max(min,value - delta))
|
Asa@0
|
568 if value ~= newvalue then
|
Asa@0
|
569 scrollbar:SetValue(newvalue)
|
Asa@0
|
570 end
|
Asa@0
|
571 end
|
Asa@0
|
572 end
|
Asa@0
|
573
|
Asa@0
|
574 local function SetTreeWidth(self, treewidth, resizable)
|
Asa@0
|
575 if not resizable then
|
Asa@0
|
576 if type(treewidth) == 'number' then
|
Asa@0
|
577 resizable = false
|
Asa@0
|
578 elseif type(treewidth) == 'boolean' then
|
Asa@0
|
579 resizable = treewidth
|
Asa@0
|
580 treewidth = DEFAULT_TREE_WIDTH
|
Asa@0
|
581 else
|
Asa@0
|
582 resizable = false
|
Asa@0
|
583 treewidth = DEFAULT_TREE_WIDTH
|
Asa@0
|
584 end
|
Asa@0
|
585 end
|
Asa@0
|
586 self.treeframe:SetWidth(treewidth)
|
Asa@0
|
587 self.dragger:EnableMouse(resizable)
|
Asa@0
|
588
|
Asa@0
|
589 local status = self.status or self.localstatus
|
Asa@0
|
590 status.treewidth = treewidth
|
Asa@0
|
591 status.treesizable = resizable
|
Asa@0
|
592
|
Asa@0
|
593 -- recalculate the content width
|
Asa@0
|
594 if status.fullwidth then
|
Asa@0
|
595 self:OnWidthSet(status.fullwidth)
|
Asa@0
|
596 end
|
Asa@0
|
597 end
|
Asa@0
|
598
|
Asa@0
|
599 local function draggerLeave(this)
|
Asa@0
|
600 this:SetBackdropColor(1, 1, 1, 0)
|
Asa@0
|
601 end
|
Asa@0
|
602
|
Asa@0
|
603 local function draggerEnter(this)
|
Asa@0
|
604 this:SetBackdropColor(1, 1, 1, 0.8)
|
Asa@0
|
605 end
|
Asa@0
|
606
|
Asa@0
|
607 local function draggerDown(this)
|
Asa@0
|
608 local treeframe = this:GetParent()
|
Asa@0
|
609 treeframe:StartSizing("RIGHT")
|
Asa@0
|
610 end
|
Asa@0
|
611
|
Asa@0
|
612 local function draggerUp(this)
|
Asa@0
|
613 local treeframe = this:GetParent()
|
Asa@0
|
614 local self = treeframe.obj
|
Asa@0
|
615 local frame = treeframe:GetParent()
|
Asa@0
|
616 treeframe:StopMovingOrSizing()
|
Asa@0
|
617 --treeframe:SetScript("OnUpdate", nil)
|
Asa@0
|
618 treeframe:SetUserPlaced(false)
|
Asa@0
|
619 --Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
|
Asa@0
|
620 treeframe:SetHeight(0)
|
Asa@0
|
621 treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
|
Asa@0
|
622 treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
|
Asa@0
|
623
|
Asa@0
|
624 local status = self.status or self.localstatus
|
Asa@0
|
625 status.treewidth = treeframe:GetWidth()
|
Asa@0
|
626
|
Asa@0
|
627 treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
|
Asa@0
|
628 -- recalculate the content width
|
Asa@0
|
629 treeframe.obj:OnWidthSet(status.fullwidth)
|
Asa@0
|
630 -- update the layout of the content
|
Asa@0
|
631 treeframe.obj:DoLayout()
|
Asa@0
|
632 end
|
Asa@0
|
633
|
Asa@0
|
634 local function LayoutFinished(self, width, height)
|
Asa@0
|
635 if self.noAutoHeight then return end
|
Asa@0
|
636 self:SetHeight((height or 0) + 20)
|
Asa@0
|
637 end
|
Asa@0
|
638
|
Asa@0
|
639 local createdcount = 0
|
Asa@0
|
640 local function Constructor()
|
Asa@0
|
641 local frame = CreateFrame("Frame",nil,UIParent)
|
Asa@0
|
642 local self = {}
|
Asa@0
|
643 self.type = Type
|
Asa@0
|
644 self.lines = {}
|
Asa@0
|
645 self.levels = {}
|
Asa@0
|
646 self.buttons = {}
|
Asa@0
|
647 self.hasChildren = {}
|
Asa@0
|
648 self.localstatus = {}
|
Asa@0
|
649 self.localstatus.groups = {}
|
Asa@0
|
650 self.filter = false
|
Asa@0
|
651
|
Asa@0
|
652 local treeframe = CreateFrame("Frame",nil,frame)
|
Asa@0
|
653 treeframe.obj = self
|
Asa@0
|
654 treeframe:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
|
Asa@0
|
655 treeframe:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
|
Asa@0
|
656 treeframe:SetWidth(DEFAULT_TREE_WIDTH)
|
Asa@0
|
657 treeframe:SetScript("OnUpdate",FirstFrameUpdate)
|
Asa@0
|
658 treeframe:SetScript("OnSizeChanged",ResizeUpdate)
|
Asa@0
|
659
|
Asa@0
|
660 treeframe:EnableMouseWheel(true)
|
Asa@0
|
661 treeframe:SetScript("OnMouseWheel", TreeOnMouseWheel)
|
Asa@0
|
662 treeframe:SetBackdrop(PaneBackdrop)
|
Asa@0
|
663 treeframe:SetBackdropColor(0.1,0.1,0.1,0.5)
|
Asa@0
|
664 treeframe:SetBackdropBorderColor(0.4,0.4,0.4)
|
Asa@0
|
665
|
Asa@0
|
666 treeframe:SetResizable(true)
|
Asa@0
|
667 treeframe:SetMinResize(100, 1)
|
Asa@0
|
668 treeframe:SetMaxResize(400,1600)
|
Asa@0
|
669 local dragger = CreateFrame("Frame", nil, treeframe)
|
Asa@0
|
670 dragger:SetWidth(8)
|
Asa@0
|
671 dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
|
Asa@0
|
672 dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
|
Asa@0
|
673 dragger:SetBackdrop(DraggerBackdrop)
|
Asa@0
|
674 dragger:SetBackdropColor(1, 1, 1, 0)
|
Asa@0
|
675 dragger:SetScript("OnMouseDown", draggerDown)
|
Asa@0
|
676 dragger:SetScript("OnMouseUp", draggerUp)
|
Asa@0
|
677 dragger:SetScript("OnEnter", draggerEnter)
|
Asa@0
|
678 dragger:SetScript("OnLeave", draggerLeave)
|
Asa@0
|
679
|
Asa@0
|
680 self.dragger = dragger
|
Asa@0
|
681 self.treeframe = treeframe
|
Asa@0
|
682 self.OnRelease = OnRelease
|
Asa@0
|
683 self.OnAcquire = OnAcquire
|
Asa@0
|
684
|
Asa@0
|
685 self.SetTree = SetTree
|
Asa@0
|
686 self.SetTreeWidth = SetTreeWidth
|
Asa@0
|
687 self.RefreshTree = RefreshTree
|
Asa@0
|
688 self.SetStatusTable = SetStatusTable
|
Asa@0
|
689 self.BuildLevel = BuildLevel
|
Asa@0
|
690 self.CreateButton = CreateButton
|
Asa@0
|
691 self.SetSelected = SetSelected
|
Asa@0
|
692 self.ShowScroll = ShowScroll
|
Asa@0
|
693 self.SetStatusTable = SetStatusTable
|
Asa@0
|
694 self.Select = Select
|
Asa@0
|
695 self.SelectByValue = SelectByValue
|
Asa@0
|
696 self.SelectByPath = SelectByPath
|
Asa@0
|
697 self.OnWidthSet = OnWidthSet
|
Asa@0
|
698 self.OnHeightSet = OnHeightSet
|
Asa@0
|
699 self.EnableButtonTooltips = EnableButtonTooltips
|
Asa@0
|
700 --self.Filter = Filter
|
Asa@0
|
701 self.LayoutFinished = LayoutFinished
|
Asa@0
|
702
|
Asa@0
|
703 self.frame = frame
|
Asa@0
|
704 frame.obj = self
|
Asa@0
|
705
|
Asa@0
|
706 createdcount = createdcount + 1
|
Asa@0
|
707 local scrollbar = CreateFrame("Slider",("AceConfigDialogTreeGroup%dScrollBar"):format(createdcount),treeframe,"UIPanelScrollBarTemplate")
|
Asa@0
|
708 self.scrollbar = scrollbar
|
Asa@0
|
709 local scrollbg = scrollbar:CreateTexture(nil,"BACKGROUND")
|
Asa@0
|
710 scrollbg:SetAllPoints(scrollbar)
|
Asa@0
|
711 scrollbg:SetTexture(0,0,0,0.4)
|
Asa@0
|
712 scrollbar.obj = self
|
Asa@0
|
713 self.noupdate = true
|
Asa@0
|
714 scrollbar:SetPoint("TOPRIGHT",treeframe,"TOPRIGHT",-10,-26)
|
Asa@0
|
715 scrollbar:SetPoint("BOTTOMRIGHT",treeframe,"BOTTOMRIGHT",-10,26)
|
Asa@0
|
716 scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
|
Asa@0
|
717 scrollbar:SetMinMaxValues(0,0)
|
Asa@0
|
718 self.localstatus.scrollvalue = 0
|
Asa@0
|
719 scrollbar:SetValueStep(1)
|
Asa@0
|
720 scrollbar:SetValue(0)
|
Asa@0
|
721 scrollbar:SetWidth(16)
|
Asa@0
|
722 self.noupdate = nil
|
Asa@0
|
723
|
Asa@0
|
724 local border = CreateFrame("Frame",nil,frame)
|
Asa@0
|
725 self.border = border
|
Asa@0
|
726 border:SetPoint("TOPLEFT",treeframe,"TOPRIGHT", 0,0)
|
Asa@0
|
727 border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
|
Asa@0
|
728
|
Asa@0
|
729 border:SetBackdrop(PaneBackdrop)
|
Asa@0
|
730 border:SetBackdropColor(0.1,0.1,0.1,0.5)
|
Asa@0
|
731 border:SetBackdropBorderColor(0.4,0.4,0.4)
|
Asa@0
|
732
|
Asa@0
|
733 --Container Support
|
Asa@0
|
734 local content = CreateFrame("Frame",nil,border)
|
Asa@0
|
735 self.content = content
|
Asa@0
|
736 content.obj = self
|
Asa@0
|
737 content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-10)
|
Asa@0
|
738 content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,10)
|
Asa@0
|
739
|
Asa@0
|
740 AceGUI:RegisterAsContainer(self)
|
Asa@0
|
741 --AceGUI:RegisterAsWidget(self)
|
Asa@0
|
742 return self
|
Asa@0
|
743 end
|
Asa@0
|
744
|
Asa@0
|
745 AceGUI:RegisterWidgetType(Type,Constructor,Version)
|
Asa@0
|
746 end
|