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