annotate Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua @ 11:371e14cd2feb

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