annotate Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua @ 0:c6ff7ba0e8f6

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