annotate Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua @ 169:d90a740a1d0b v79

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