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