John@52
|
1 local Type, Version = "SelectorList", 34
|
John@52
|
2 local AceGUI = LibStub and LibStub("AceGUI-3.0",true)
|
John@52
|
3 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
John@52
|
4
|
John@54
|
5 local con = LibStub("AceConsole-3.0",true)
|
John@52
|
6 local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
John@52
|
7 local math_min, math_max, floor = math.min, math.max, floor
|
John@52
|
8 local select, tremove, unpack, tconcat = select, table.remove, unpack, table.concat
|
John@52
|
9
|
John@52
|
10 local CreateFrame, UIParent = CreateFrame, UIParent
|
John@52
|
11
|
John@52
|
12 local new, del
|
John@52
|
13 do
|
John@52
|
14 local pool = setmetatable({},{__mode='k'})
|
John@52
|
15 function new()
|
John@52
|
16 local t = next(pool)
|
John@52
|
17 if t then
|
John@52
|
18 pool[t] = nil
|
John@52
|
19 return t
|
John@52
|
20 else
|
John@52
|
21 return {}
|
John@52
|
22 end
|
John@52
|
23 end
|
John@52
|
24 function del(t)
|
John@52
|
25 for k in pairs(t) do
|
John@52
|
26 t[k] = nil
|
John@52
|
27 end
|
John@52
|
28 pool[t] = true
|
John@52
|
29 end
|
John@52
|
30 end
|
John@52
|
31
|
John@52
|
32 local DEFAULT_SL_WIDTH = 175
|
John@52
|
33 --local DEFAULT_TREE_SIZABLE = true
|
John@52
|
34
|
John@53
|
35 local function SL_OnMouseWheel(frame, delta)
|
John@53
|
36 local self = frame.obj
|
John@53
|
37 if self.showscroll then
|
John@53
|
38 local scrollbar = self.scrollbar
|
John@53
|
39 local min, max = scrollbar:GetMinMaxValues()
|
John@53
|
40 local value = scrollbar:GetValue()
|
John@53
|
41 local newvalue = math_min(max,math_max(min,value - delta))
|
John@53
|
42 if value ~= newvalue then
|
John@53
|
43 scrollbar:SetValue(newvalue)
|
John@53
|
44 end
|
John@53
|
45 end
|
John@53
|
46 end
|
John@53
|
47
|
John@53
|
48 local function OnScrollValueChanged(frame, value)
|
John@53
|
49 if frame.obj.noupdate then return end
|
John@53
|
50 local self = frame.obj
|
John@53
|
51 local status = self.status or self.localstatus
|
John@53
|
52 status.scrollvalue = value
|
John@53
|
53 self:Refresh()
|
John@53
|
54 AceGUI:ClearFocus()
|
John@53
|
55 end
|
John@53
|
56
|
John@54
|
57 local function Button_OnClick(frame)
|
John@54
|
58 local self = frame.obj
|
John@54
|
59 local status = self.status or self.localstatus
|
John@54
|
60 if status.selected == frame.value then
|
John@54
|
61 status.selected = nil
|
John@61
|
62 self:Fire("OnSelectionCleared")
|
John@54
|
63 else
|
John@54
|
64 status.selected = frame.value
|
John@61
|
65 self:Fire("OnSelection", frame.line)
|
John@54
|
66 end
|
John@54
|
67 self:Refresh()
|
John@54
|
68 AceGUI:ClearFocus()
|
John@54
|
69 end
|
John@53
|
70
|
John@54
|
71 local function Button_OnEnter(frame)
|
John@54
|
72 local self = frame.obj
|
John@54
|
73 --self:Fire("OnButtonEnter", frame.uniquevalue, frame)
|
John@54
|
74
|
John@54
|
75 if self.localstatus.enabletooltips then
|
John@54
|
76 GameTooltip:SetOwner(frame, "ANCHOR_NONE")
|
John@64
|
77 GameTooltip:SetPoint("BOTTOMLEFT",frame,"RIGHT")
|
John@54
|
78 if frame.link then
|
John@54
|
79 GameTooltip:SetHyperlink(frame.link)
|
John@54
|
80 else
|
John@54
|
81 GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1)
|
John@54
|
82 end
|
John@54
|
83
|
John@54
|
84 GameTooltip:Show()
|
John@54
|
85 end
|
John@54
|
86 end
|
John@54
|
87
|
John@54
|
88 local function Button_OnLeave(frame)
|
John@54
|
89 local self = frame.obj
|
John@54
|
90 --self:Fire("OnButtonLeave", frame.uniquevalue, frame)
|
John@54
|
91
|
John@54
|
92 if self.localstatus.enabletooltips then
|
John@54
|
93 GameTooltip:Hide()
|
John@54
|
94 end
|
John@54
|
95 end
|
John@52
|
96
|
John@52
|
97 local function Layout(self)
|
John@52
|
98 self:SetHeight(self.numlines * 18 + 20)
|
John@52
|
99
|
John@52
|
100 end
|
John@52
|
101
|
John@52
|
102 local function CreateButton(widget)
|
John@52
|
103 local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
|
John@52
|
104 local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), widget.slframe, "OptionsListButtonTemplate")
|
John@52
|
105 button.obj = widget
|
John@52
|
106
|
John@52
|
107 local icon = button:CreateTexture(nil, "OVERLAY")
|
John@52
|
108 icon:SetWidth(14)
|
John@52
|
109 icon:SetHeight(14)
|
John@52
|
110 button.icon = icon
|
John@52
|
111
|
John@52
|
112 button:SetScript("OnClick",Button_OnClick)
|
John@52
|
113 button:SetScript("OnDoubleClick", Button_OnDoubleClick)
|
John@52
|
114 button:SetScript("OnEnter",Button_OnEnter)
|
John@52
|
115 button:SetScript("OnLeave",Button_OnLeave)
|
John@52
|
116
|
John@52
|
117 return button
|
John@52
|
118 end
|
John@52
|
119
|
John@52
|
120 local function UpdateButton(button, line, selected)
|
John@52
|
121 local self = button.obj
|
John@52
|
122 local frame = self.frame
|
John@52
|
123 local text = line.text or ""
|
John@52
|
124 local icon = line.icon
|
John@52
|
125 local iconCoords = line.iconCoords
|
John@52
|
126 local level = line.level or 1
|
John@52
|
127 local value = line.value
|
John@54
|
128 local link = line.link
|
John@52
|
129 local uniquevalue = line.uniquevalue
|
John@52
|
130 local disabled = line.disabled
|
John@54
|
131 local status = self.localstatus
|
John@52
|
132
|
John@52
|
133 button.line = line
|
John@52
|
134 button.value = value
|
John@54
|
135 button.link = link
|
John@52
|
136 button.uniquevalue = uniquevalue
|
John@54
|
137 if selected and status.enableInteractive then
|
John@52
|
138 button:LockHighlight()
|
John@52
|
139 button.selected = true
|
John@52
|
140 else
|
John@52
|
141 button:UnlockHighlight()
|
John@52
|
142 button.selected = false
|
John@52
|
143 end
|
John@54
|
144 if status.enableInteractive then
|
John@54
|
145 button:Enable()
|
John@54
|
146 else
|
John@54
|
147 button:Disable()
|
John@54
|
148 end
|
John@52
|
149 local normalTexture = button:GetNormalTexture()
|
John@52
|
150 local line = button.line
|
John@52
|
151 button.level = level
|
John@52
|
152 if ( level == 1 ) then
|
John@52
|
153 button:SetNormalFontObject("GameFontNormal")
|
John@52
|
154 button:SetHighlightFontObject("GameFontHighlight")
|
John@52
|
155 button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
John@52
|
156 else
|
John@52
|
157 button:SetNormalFontObject("GameFontHighlightSmall")
|
John@52
|
158 button:SetHighlightFontObject("GameFontHighlightSmall")
|
John@52
|
159 button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
John@52
|
160 end
|
John@52
|
161
|
John@52
|
162 if disabled then
|
John@52
|
163 button:EnableMouse(false)
|
John@54
|
164 local newText = text
|
John@54
|
165 newText = newText:gsub("\124c[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F](.*)"..FONT_COLOR_CODE_CLOSE,"%1")
|
John@54
|
166 button.text:SetText("|cff808080"..newText..FONT_COLOR_CODE_CLOSE)
|
John@52
|
167 else
|
John@52
|
168 button.text:SetText(text)
|
John@52
|
169 button:EnableMouse(true)
|
John@52
|
170 end
|
John@52
|
171
|
John@52
|
172 if icon then
|
John@52
|
173 button.icon:SetTexture(icon)
|
John@52
|
174 button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
|
John@52
|
175 else
|
John@52
|
176 button.icon:SetTexture(nil)
|
John@52
|
177 end
|
John@52
|
178
|
John@52
|
179 if iconCoords then
|
John@52
|
180 button.icon:SetTexCoord(unpack(iconCoords))
|
John@52
|
181 else
|
John@52
|
182 button.icon:SetTexCoord(0, 1, 0, 1)
|
John@52
|
183 end
|
John@52
|
184 end
|
John@52
|
185
|
John@52
|
186
|
John@53
|
187
|
John@52
|
188 local methods = {
|
John@52
|
189
|
John@52
|
190 ["OnAcquire"] = function(self)
|
John@52
|
191 self:SetWidth(DEFAULT_SL_WIDTH)
|
John@52
|
192 self:SetNumLines()
|
John@54
|
193 self:EnableButtonTooltips(false)
|
John@54
|
194 self:SetInteractive(true)
|
John@52
|
195 end,
|
John@54
|
196
|
John@52
|
197 ["SetNumLines"] = function(self,value)
|
John@52
|
198 if not value or value < 4 then
|
John@52
|
199 value = 4
|
John@52
|
200 end
|
John@52
|
201 self.numlines = value
|
John@52
|
202 Layout(self)
|
John@52
|
203 end,
|
John@54
|
204
|
John@54
|
205 ["EnableButtonTooltips"] = function(self, enable)
|
John@54
|
206 self.localstatus.enabletooltips = enable
|
John@54
|
207 end,
|
John@54
|
208
|
John@52
|
209 ["SetList"] = function(self, list)
|
John@53
|
210 self.lines = {}
|
John@52
|
211 for i,v in ipairs(list) do
|
John@52
|
212 self.lines[i] = v
|
John@52
|
213 end
|
John@54
|
214 local status = self.status or self.localstatus
|
John@54
|
215 status.selected = nil
|
John@54
|
216 status.scrollvalue = 0
|
John@52
|
217 self:Refresh()
|
John@52
|
218 end,
|
John@53
|
219
|
John@54
|
220 ["SetInteractive"] = function(self, value)
|
John@54
|
221 self.localstatus.enableInteractive = value
|
John@54
|
222 end,
|
John@54
|
223
|
John@54
|
224 ["ShowScroll"] = function(self, show) -- todo: not a user function. hide.
|
John@53
|
225 self.showscroll = show
|
John@53
|
226 if show then
|
John@53
|
227 self.scrollbar:Show()
|
John@53
|
228 if self.buttons[1] then
|
John@53
|
229 self.buttons[1]:SetPoint("TOPRIGHT", self.slframe,"TOPRIGHT",-22,-10)
|
John@53
|
230 end
|
John@53
|
231 else
|
John@53
|
232 self.scrollbar:Hide()
|
John@53
|
233 if self.buttons[1] then
|
John@53
|
234 self.buttons[1]:SetPoint("TOPRIGHT", self.slframe,"TOPRIGHT",0,-10)
|
John@53
|
235 end
|
John@53
|
236 end
|
John@53
|
237 end,
|
John@53
|
238
|
John@52
|
239 ["Refresh"] = function(self)
|
John@52
|
240 local f = self.slframe
|
John@52
|
241 local buttons = self.buttons
|
John@52
|
242 local lines = self.lines
|
John@53
|
243 local status = self.status or self.localstatus
|
John@53
|
244
|
John@53
|
245 for i, v in ipairs(buttons) do
|
John@53
|
246 v:Hide()
|
John@53
|
247 end
|
John@53
|
248 local numlines = #lines
|
John@53
|
249 local maxlines = self.numlines
|
John@53
|
250
|
John@53
|
251 if numlines <= maxlines then
|
John@53
|
252 status.scrollvalue = 0
|
John@53
|
253 self:ShowScroll(false)
|
John@53
|
254 first, last = 1, numlines
|
John@53
|
255 else
|
John@53
|
256 self:ShowScroll(true)
|
John@53
|
257 self.noupdate = true
|
John@53
|
258 self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
|
John@53
|
259 if numlines - status.scrollvalue < maxlines then
|
John@53
|
260 status.scrollvalue = numlines - maxlines
|
John@53
|
261 end
|
John@53
|
262 self.noupdate = nil
|
John@53
|
263 first, last = status.scrollvalue+1, status.scrollvalue + maxlines
|
John@53
|
264
|
John@53
|
265 if self.scrollbar:GetValue() ~= status.scrollvalue then
|
John@53
|
266 self.scrollbar:SetValue(status.scrollvalue)
|
John@53
|
267 end
|
John@53
|
268 end
|
John@52
|
269
|
John@52
|
270 local bnum = 1
|
John@53
|
271 for i= first, last do
|
John@52
|
272 local l = lines[i]
|
John@52
|
273 local b = buttons[bnum]
|
John@52
|
274 if not b then
|
John@52
|
275 b = CreateButton(self)
|
John@52
|
276 buttons[bnum] = b
|
John@52
|
277 b:SetParent(f)
|
John@52
|
278 b:SetFrameLevel(f:GetFrameLevel()+1)
|
John@52
|
279 b:ClearAllPoints()
|
John@52
|
280 if bnum == 1 then
|
John@53
|
281 if self.showscroll then
|
John@53
|
282 b:SetPoint("TOPRIGHT",-22,-10)
|
John@53
|
283 else
|
John@53
|
284 b:SetPoint("TOPRIGHT",0,-10)
|
John@53
|
285 end
|
John@52
|
286 b:SetPoint("TOPLEFT",0,-10)
|
John@52
|
287 else
|
John@52
|
288 b:SetPoint("TOPRIGHT", buttons[bnum-1], "BOTTOMRIGHT", 0, 0)
|
John@52
|
289 b:SetPoint("TOPLEFT", buttons[bnum-1], "BOTTOMLEFT", 0, 0)
|
John@52
|
290 end
|
John@52
|
291 end
|
John@54
|
292 UpdateButton(b, l, status.selected == l.value)
|
John@52
|
293 b:Show()
|
John@52
|
294 bnum = bnum + 1
|
John@52
|
295 end
|
John@52
|
296 end,
|
John@52
|
297 }
|
John@52
|
298
|
John@52
|
299
|
John@52
|
300
|
John@52
|
301
|
John@52
|
302
|
John@52
|
303
|
John@52
|
304
|
John@52
|
305
|
John@52
|
306
|
John@52
|
307 local PaneBackdrop = {
|
John@52
|
308 bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
John@52
|
309 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
John@52
|
310 tile = true, tileSize = 16, edgeSize = 16,
|
John@52
|
311 insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
John@52
|
312 }
|
John@52
|
313
|
John@52
|
314 local function Constructor()
|
John@52
|
315 local num = AceGUI:GetNextWidgetNum(Type)
|
John@52
|
316 local frame = CreateFrame("Frame", nil, UIParent)
|
John@52
|
317
|
John@52
|
318 local slframe = CreateFrame("Frame", nil, frame)
|
John@52
|
319 slframe:SetAllPoints()
|
John@52
|
320 slframe:EnableMouseWheel(true)
|
John@52
|
321 slframe:SetBackdrop(PaneBackdrop)
|
John@52
|
322 slframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
John@52
|
323 slframe:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
John@52
|
324 --slframe:SetResizable(true)
|
John@52
|
325 --slframe:SetMinResize(100, 1)
|
John@52
|
326 --slframe:SetMaxResize(400, 1600)
|
John@52
|
327 --slframe:SetScript("OnUpdate", FirstFrameUpdate)
|
John@52
|
328 --slframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
|
John@53
|
329 slframe:SetScript("OnMouseWheel", SL_OnMouseWheel)
|
John@52
|
330
|
John@53
|
331 local scrollbar = CreateFrame("Slider", ("SelectorList%dScrollBar"):format(num), slframe, "UIPanelScrollBarTemplate")
|
John@53
|
332 scrollbar:SetScript("OnValueChanged", nil)
|
John@53
|
333 scrollbar:SetPoint("TOPRIGHT", -10, -26)
|
John@53
|
334 scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
|
John@53
|
335 scrollbar:SetMinMaxValues(0,0)
|
John@53
|
336 scrollbar:SetValueStep(1)
|
John@53
|
337 scrollbar:SetValue(0)
|
John@53
|
338 scrollbar:SetWidth(16)
|
John@53
|
339 scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
|
John@52
|
340
|
John@53
|
341 local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
|
John@53
|
342 scrollbg:SetAllPoints(scrollbar)
|
John@53
|
343 scrollbg:SetTexture(0,0,0,0.4)
|
John@52
|
344
|
John@52
|
345 local widget = {
|
John@52
|
346 frame = frame,
|
John@52
|
347 lines = {},
|
John@52
|
348 buttons = {},
|
John@52
|
349 localstatus = {
|
John@52
|
350 --groups = {},
|
John@54
|
351 enabletooltips= false,
|
John@54
|
352 scrollvalue = 0,
|
John@54
|
353 },
|
John@52
|
354 slframe = slframe,
|
John@53
|
355 scrollbar = scrollbar,
|
John@52
|
356 type = Type
|
John@52
|
357 }
|
John@52
|
358 if methods then
|
John@52
|
359 for method, func in pairs(methods) do
|
John@52
|
360 widget[method] = func
|
John@52
|
361 end
|
John@52
|
362 end
|
John@52
|
363 slframe.obj = widget
|
John@53
|
364 scrollbar.obj = widget
|
John@52
|
365
|
John@52
|
366 return AceGUI:RegisterAsWidget(widget)
|
John@52
|
367 end
|
John@52
|
368
|
John@52
|
369 AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
John@52
|
370
|
John@52
|
371
|
John@52
|
372
|
John@52
|
373
|