annotate Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua @ 124:e31b02b24488

Updated for 8.0 pre-patch and BfA.
author yellowfive
date Tue, 17 Jul 2018 09:57:39 -0700
parents 01b63b8ed811
children
rev   line source
yellowfive@124 1 --[[ $Id: AceGUIWidget-DropDown.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]--
yellowfive@57 2 local AceGUI = LibStub("AceGUI-3.0")
yellowfive@57 3
yellowfive@57 4 -- Lua APIs
yellowfive@57 5 local min, max, floor = math.min, math.max, math.floor
yellowfive@57 6 local select, pairs, ipairs, type = select, pairs, ipairs, type
yellowfive@57 7 local tsort = table.sort
yellowfive@57 8
yellowfive@57 9 -- WoW APIs
yellowfive@57 10 local PlaySound = PlaySound
yellowfive@57 11 local UIParent, CreateFrame = UIParent, CreateFrame
yellowfive@57 12 local _G = _G
yellowfive@57 13
yellowfive@57 14 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
yellowfive@57 15 -- List them here for Mikk's FindGlobals script
yellowfive@57 16 -- GLOBALS: CLOSE
yellowfive@57 17
yellowfive@57 18 local function fixlevels(parent,...)
yellowfive@57 19 local i = 1
yellowfive@57 20 local child = select(i, ...)
yellowfive@57 21 while child do
yellowfive@57 22 child:SetFrameLevel(parent:GetFrameLevel()+1)
yellowfive@57 23 fixlevels(child, child:GetChildren())
yellowfive@57 24 i = i + 1
yellowfive@57 25 child = select(i, ...)
yellowfive@57 26 end
yellowfive@57 27 end
yellowfive@57 28
yellowfive@57 29 local function fixstrata(strata, parent, ...)
yellowfive@57 30 local i = 1
yellowfive@57 31 local child = select(i, ...)
yellowfive@57 32 parent:SetFrameStrata(strata)
yellowfive@57 33 while child do
yellowfive@57 34 fixstrata(strata, child, child:GetChildren())
yellowfive@57 35 i = i + 1
yellowfive@57 36 child = select(i, ...)
yellowfive@57 37 end
yellowfive@57 38 end
yellowfive@57 39
yellowfive@57 40 do
yellowfive@57 41 local widgetType = "Dropdown-Pullout"
yellowfive@57 42 local widgetVersion = 3
yellowfive@57 43
yellowfive@57 44 --[[ Static data ]]--
yellowfive@57 45
yellowfive@57 46 local backdrop = {
yellowfive@57 47 bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
yellowfive@57 48 edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
yellowfive@57 49 edgeSize = 32,
yellowfive@57 50 tileSize = 32,
yellowfive@57 51 tile = true,
yellowfive@57 52 insets = { left = 11, right = 12, top = 12, bottom = 11 },
yellowfive@57 53 }
yellowfive@57 54 local sliderBackdrop = {
yellowfive@57 55 bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
yellowfive@57 56 edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
yellowfive@57 57 tile = true, tileSize = 8, edgeSize = 8,
yellowfive@57 58 insets = { left = 3, right = 3, top = 3, bottom = 3 }
yellowfive@57 59 }
yellowfive@57 60
yellowfive@57 61 local defaultWidth = 200
yellowfive@57 62 local defaultMaxHeight = 600
yellowfive@57 63
yellowfive@57 64 --[[ UI Event Handlers ]]--
yellowfive@57 65
yellowfive@57 66 -- HACK: This should be no part of the pullout, but there
yellowfive@57 67 -- is no other 'clean' way to response to any item-OnEnter
yellowfive@57 68 -- Used to close Submenus when an other item is entered
yellowfive@57 69 local function OnEnter(item)
yellowfive@57 70 local self = item.pullout
yellowfive@57 71 for k, v in ipairs(self.items) do
yellowfive@57 72 if v.CloseMenu and v ~= item then
yellowfive@57 73 v:CloseMenu()
yellowfive@57 74 end
yellowfive@57 75 end
yellowfive@57 76 end
yellowfive@57 77
yellowfive@57 78 -- See the note in Constructor() for each scroll related function
yellowfive@57 79 local function OnMouseWheel(this, value)
yellowfive@57 80 this.obj:MoveScroll(value)
yellowfive@57 81 end
yellowfive@57 82
yellowfive@57 83 local function OnScrollValueChanged(this, value)
yellowfive@57 84 this.obj:SetScroll(value)
yellowfive@57 85 end
yellowfive@57 86
yellowfive@57 87 local function OnSizeChanged(this)
yellowfive@57 88 this.obj:FixScroll()
yellowfive@57 89 end
yellowfive@57 90
yellowfive@57 91 --[[ Exported methods ]]--
yellowfive@57 92
yellowfive@57 93 -- exported
yellowfive@57 94 local function SetScroll(self, value)
yellowfive@57 95 local status = self.scrollStatus
yellowfive@57 96 local frame, child = self.scrollFrame, self.itemFrame
yellowfive@57 97 local height, viewheight = frame:GetHeight(), child:GetHeight()
yellowfive@57 98
yellowfive@57 99 local offset
yellowfive@57 100 if height > viewheight then
yellowfive@57 101 offset = 0
yellowfive@57 102 else
yellowfive@57 103 offset = floor((viewheight - height) / 1000 * value)
yellowfive@57 104 end
yellowfive@57 105 child:ClearAllPoints()
yellowfive@57 106 child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
yellowfive@57 107 child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
yellowfive@57 108 status.offset = offset
yellowfive@57 109 status.scrollvalue = value
yellowfive@57 110 end
yellowfive@57 111
yellowfive@57 112 -- exported
yellowfive@57 113 local function MoveScroll(self, value)
yellowfive@57 114 local status = self.scrollStatus
yellowfive@57 115 local frame, child = self.scrollFrame, self.itemFrame
yellowfive@57 116 local height, viewheight = frame:GetHeight(), child:GetHeight()
yellowfive@57 117
yellowfive@57 118 if height > viewheight then
yellowfive@57 119 self.slider:Hide()
yellowfive@57 120 else
yellowfive@57 121 self.slider:Show()
yellowfive@57 122 local diff = height - viewheight
yellowfive@57 123 local delta = 1
yellowfive@57 124 if value < 0 then
yellowfive@57 125 delta = -1
yellowfive@57 126 end
yellowfive@57 127 self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
yellowfive@57 128 end
yellowfive@57 129 end
yellowfive@57 130
yellowfive@57 131 -- exported
yellowfive@57 132 local function FixScroll(self)
yellowfive@57 133 local status = self.scrollStatus
yellowfive@57 134 local frame, child = self.scrollFrame, self.itemFrame
yellowfive@57 135 local height, viewheight = frame:GetHeight(), child:GetHeight()
yellowfive@57 136 local offset = status.offset or 0
yellowfive@57 137
yellowfive@57 138 if viewheight < height then
yellowfive@57 139 self.slider:Hide()
yellowfive@57 140 child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
yellowfive@57 141 self.slider:SetValue(0)
yellowfive@57 142 else
yellowfive@57 143 self.slider:Show()
yellowfive@57 144 local value = (offset / (viewheight - height) * 1000)
yellowfive@57 145 if value > 1000 then value = 1000 end
yellowfive@57 146 self.slider:SetValue(value)
yellowfive@57 147 self:SetScroll(value)
yellowfive@57 148 if value < 1000 then
yellowfive@57 149 child:ClearAllPoints()
yellowfive@57 150 child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
yellowfive@57 151 child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset)
yellowfive@57 152 status.offset = offset
yellowfive@57 153 end
yellowfive@57 154 end
yellowfive@57 155 end
yellowfive@57 156
yellowfive@57 157 -- exported, AceGUI callback
yellowfive@57 158 local function OnAcquire(self)
yellowfive@57 159 self.frame:SetParent(UIParent)
yellowfive@57 160 --self.itemFrame:SetToplevel(true)
yellowfive@57 161 end
yellowfive@57 162
yellowfive@57 163 -- exported, AceGUI callback
yellowfive@57 164 local function OnRelease(self)
yellowfive@57 165 self:Clear()
yellowfive@57 166 self.frame:ClearAllPoints()
yellowfive@57 167 self.frame:Hide()
yellowfive@57 168 end
yellowfive@57 169
yellowfive@57 170 -- exported
yellowfive@57 171 local function AddItem(self, item)
yellowfive@57 172 self.items[#self.items + 1] = item
yellowfive@57 173
yellowfive@57 174 local h = #self.items * 16
yellowfive@57 175 self.itemFrame:SetHeight(h)
yellowfive@57 176 self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
yellowfive@57 177
yellowfive@57 178 item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
yellowfive@57 179 item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
yellowfive@57 180
yellowfive@57 181 item:SetPullout(self)
yellowfive@57 182 item:SetOnEnter(OnEnter)
yellowfive@57 183 end
yellowfive@57 184
yellowfive@57 185 -- exported
yellowfive@57 186 local function Open(self, point, relFrame, relPoint, x, y)
yellowfive@57 187 local items = self.items
yellowfive@57 188 local frame = self.frame
yellowfive@57 189 local itemFrame = self.itemFrame
yellowfive@57 190
yellowfive@57 191 frame:SetPoint(point, relFrame, relPoint, x, y)
yellowfive@57 192
yellowfive@57 193
yellowfive@57 194 local height = 8
yellowfive@57 195 for i, item in pairs(items) do
yellowfive@57 196 if i == 1 then
yellowfive@57 197 item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
yellowfive@57 198 else
yellowfive@57 199 item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
yellowfive@57 200 end
yellowfive@57 201
yellowfive@57 202 item:Show()
yellowfive@57 203
yellowfive@57 204 height = height + 16
yellowfive@57 205 end
yellowfive@57 206 itemFrame:SetHeight(height)
yellowfive@57 207 fixstrata("TOOLTIP", frame, frame:GetChildren())
yellowfive@57 208 frame:Show()
yellowfive@57 209 self:Fire("OnOpen")
yellowfive@57 210 end
yellowfive@57 211
yellowfive@57 212 -- exported
yellowfive@57 213 local function Close(self)
yellowfive@57 214 self.frame:Hide()
yellowfive@57 215 self:Fire("OnClose")
yellowfive@57 216 end
yellowfive@57 217
yellowfive@57 218 -- exported
yellowfive@57 219 local function Clear(self)
yellowfive@57 220 local items = self.items
yellowfive@57 221 for i, item in pairs(items) do
yellowfive@57 222 AceGUI:Release(item)
yellowfive@57 223 items[i] = nil
yellowfive@57 224 end
yellowfive@57 225 end
yellowfive@57 226
yellowfive@57 227 -- exported
yellowfive@57 228 local function IterateItems(self)
yellowfive@57 229 return ipairs(self.items)
yellowfive@57 230 end
yellowfive@57 231
yellowfive@57 232 -- exported
yellowfive@57 233 local function SetHideOnLeave(self, val)
yellowfive@57 234 self.hideOnLeave = val
yellowfive@57 235 end
yellowfive@57 236
yellowfive@57 237 -- exported
yellowfive@57 238 local function SetMaxHeight(self, height)
yellowfive@57 239 self.maxHeight = height or defaultMaxHeight
yellowfive@57 240 if self.frame:GetHeight() > height then
yellowfive@57 241 self.frame:SetHeight(height)
yellowfive@57 242 elseif (self.itemFrame:GetHeight() + 34) < height then
yellowfive@57 243 self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
yellowfive@57 244 end
yellowfive@57 245 end
yellowfive@57 246
yellowfive@57 247 -- exported
yellowfive@57 248 local function GetRightBorderWidth(self)
yellowfive@57 249 return 6 + (self.slider:IsShown() and 12 or 0)
yellowfive@57 250 end
yellowfive@57 251
yellowfive@57 252 -- exported
yellowfive@57 253 local function GetLeftBorderWidth(self)
yellowfive@57 254 return 6
yellowfive@57 255 end
yellowfive@57 256
yellowfive@57 257 --[[ Constructor ]]--
yellowfive@57 258
yellowfive@57 259 local function Constructor()
yellowfive@57 260 local count = AceGUI:GetNextWidgetNum(widgetType)
yellowfive@57 261 local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
yellowfive@57 262 local self = {}
yellowfive@57 263 self.count = count
yellowfive@57 264 self.type = widgetType
yellowfive@57 265 self.frame = frame
yellowfive@57 266 frame.obj = self
yellowfive@57 267
yellowfive@57 268 self.OnAcquire = OnAcquire
yellowfive@57 269 self.OnRelease = OnRelease
yellowfive@57 270
yellowfive@57 271 self.AddItem = AddItem
yellowfive@57 272 self.Open = Open
yellowfive@57 273 self.Close = Close
yellowfive@57 274 self.Clear = Clear
yellowfive@57 275 self.IterateItems = IterateItems
yellowfive@57 276 self.SetHideOnLeave = SetHideOnLeave
yellowfive@57 277
yellowfive@57 278 self.SetScroll = SetScroll
yellowfive@57 279 self.MoveScroll = MoveScroll
yellowfive@57 280 self.FixScroll = FixScroll
yellowfive@57 281
yellowfive@57 282 self.SetMaxHeight = SetMaxHeight
yellowfive@57 283 self.GetRightBorderWidth = GetRightBorderWidth
yellowfive@57 284 self.GetLeftBorderWidth = GetLeftBorderWidth
yellowfive@57 285
yellowfive@57 286 self.items = {}
yellowfive@57 287
yellowfive@57 288 self.scrollStatus = {
yellowfive@57 289 scrollvalue = 0,
yellowfive@57 290 }
yellowfive@57 291
yellowfive@57 292 self.maxHeight = defaultMaxHeight
yellowfive@57 293
yellowfive@57 294 frame:SetBackdrop(backdrop)
yellowfive@57 295 frame:SetBackdropColor(0, 0, 0)
yellowfive@57 296 frame:SetFrameStrata("FULLSCREEN_DIALOG")
yellowfive@57 297 frame:SetClampedToScreen(true)
yellowfive@57 298 frame:SetWidth(defaultWidth)
yellowfive@57 299 frame:SetHeight(self.maxHeight)
yellowfive@57 300 --frame:SetToplevel(true)
yellowfive@57 301
yellowfive@57 302 -- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
yellowfive@57 303 local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
yellowfive@57 304 local itemFrame = CreateFrame("Frame", nil, scrollFrame)
yellowfive@57 305
yellowfive@57 306 self.scrollFrame = scrollFrame
yellowfive@57 307 self.itemFrame = itemFrame
yellowfive@57 308
yellowfive@57 309 scrollFrame.obj = self
yellowfive@57 310 itemFrame.obj = self
yellowfive@57 311
yellowfive@57 312 local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame)
yellowfive@57 313 slider:SetOrientation("VERTICAL")
yellowfive@57 314 slider:SetHitRectInsets(0, 0, -10, 0)
yellowfive@57 315 slider:SetBackdrop(sliderBackdrop)
yellowfive@57 316 slider:SetWidth(8)
yellowfive@57 317 slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
yellowfive@57 318 slider:SetFrameStrata("FULLSCREEN_DIALOG")
yellowfive@57 319 self.slider = slider
yellowfive@57 320 slider.obj = self
yellowfive@57 321
yellowfive@57 322 scrollFrame:SetScrollChild(itemFrame)
yellowfive@57 323 scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
yellowfive@57 324 scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
yellowfive@57 325 scrollFrame:EnableMouseWheel(true)
yellowfive@57 326 scrollFrame:SetScript("OnMouseWheel", OnMouseWheel)
yellowfive@57 327 scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
yellowfive@57 328 scrollFrame:SetToplevel(true)
yellowfive@57 329 scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
yellowfive@57 330
yellowfive@57 331 itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
yellowfive@57 332 itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
yellowfive@57 333 itemFrame:SetHeight(400)
yellowfive@57 334 itemFrame:SetToplevel(true)
yellowfive@57 335 itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
yellowfive@57 336
yellowfive@57 337 slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
yellowfive@57 338 slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
yellowfive@57 339 slider:SetScript("OnValueChanged", OnScrollValueChanged)
yellowfive@57 340 slider:SetMinMaxValues(0, 1000)
yellowfive@57 341 slider:SetValueStep(1)
yellowfive@57 342 slider:SetValue(0)
yellowfive@57 343
yellowfive@57 344 scrollFrame:Show()
yellowfive@57 345 itemFrame:Show()
yellowfive@57 346 slider:Hide()
yellowfive@57 347
yellowfive@57 348 self:FixScroll()
yellowfive@57 349
yellowfive@57 350 AceGUI:RegisterAsWidget(self)
yellowfive@57 351 return self
yellowfive@57 352 end
yellowfive@57 353
yellowfive@57 354 AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
yellowfive@57 355 end
yellowfive@57 356
yellowfive@57 357 do
yellowfive@57 358 local widgetType = "Dropdown"
yellowfive@124 359 local widgetVersion = 31
yellowfive@57 360
yellowfive@57 361 --[[ Static data ]]--
yellowfive@57 362
yellowfive@57 363 --[[ UI event handler ]]--
yellowfive@57 364
yellowfive@57 365 local function Control_OnEnter(this)
yellowfive@57 366 this.obj.button:LockHighlight()
yellowfive@57 367 this.obj:Fire("OnEnter")
yellowfive@57 368 end
yellowfive@57 369
yellowfive@57 370 local function Control_OnLeave(this)
yellowfive@57 371 this.obj.button:UnlockHighlight()
yellowfive@57 372 this.obj:Fire("OnLeave")
yellowfive@57 373 end
yellowfive@57 374
yellowfive@57 375 local function Dropdown_OnHide(this)
yellowfive@57 376 local self = this.obj
yellowfive@57 377 if self.open then
yellowfive@57 378 self.pullout:Close()
yellowfive@57 379 end
yellowfive@57 380 end
yellowfive@57 381
yellowfive@57 382 local function Dropdown_TogglePullout(this)
yellowfive@57 383 local self = this.obj
yellowfive@124 384 PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
yellowfive@57 385 if self.open then
yellowfive@57 386 self.open = nil
yellowfive@57 387 self.pullout:Close()
yellowfive@57 388 AceGUI:ClearFocus()
yellowfive@57 389 else
yellowfive@57 390 self.open = true
yellowfive@57 391 self.pullout:SetWidth(self.pulloutWidth or self.frame:GetWidth())
yellowfive@57 392 self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
yellowfive@57 393 AceGUI:SetFocus(self)
yellowfive@57 394 end
yellowfive@57 395 end
yellowfive@57 396
yellowfive@57 397 local function OnPulloutOpen(this)
yellowfive@57 398 local self = this.userdata.obj
yellowfive@57 399 local value = self.value
yellowfive@57 400
yellowfive@57 401 if not self.multiselect then
yellowfive@57 402 for i, item in this:IterateItems() do
yellowfive@57 403 item:SetValue(item.userdata.value == value)
yellowfive@57 404 end
yellowfive@57 405 end
yellowfive@57 406
yellowfive@57 407 self.open = true
yellowfive@57 408 self:Fire("OnOpened")
yellowfive@57 409 end
yellowfive@57 410
yellowfive@57 411 local function OnPulloutClose(this)
yellowfive@57 412 local self = this.userdata.obj
yellowfive@57 413 self.open = nil
yellowfive@57 414 self:Fire("OnClosed")
yellowfive@57 415 end
yellowfive@57 416
yellowfive@57 417 local function ShowMultiText(self)
yellowfive@57 418 local text
yellowfive@57 419 for i, widget in self.pullout:IterateItems() do
yellowfive@57 420 if widget.type == "Dropdown-Item-Toggle" then
yellowfive@57 421 if widget:GetValue() then
yellowfive@57 422 if text then
yellowfive@57 423 text = text..", "..widget:GetText()
yellowfive@57 424 else
yellowfive@57 425 text = widget:GetText()
yellowfive@57 426 end
yellowfive@57 427 end
yellowfive@57 428 end
yellowfive@57 429 end
yellowfive@57 430 self:SetText(text)
yellowfive@57 431 end
yellowfive@57 432
yellowfive@57 433 local function OnItemValueChanged(this, event, checked)
yellowfive@57 434 local self = this.userdata.obj
yellowfive@57 435
yellowfive@57 436 if self.multiselect then
yellowfive@57 437 self:Fire("OnValueChanged", this.userdata.value, checked)
yellowfive@57 438 ShowMultiText(self)
yellowfive@57 439 else
yellowfive@57 440 if checked then
yellowfive@57 441 self:SetValue(this.userdata.value)
yellowfive@57 442 self:Fire("OnValueChanged", this.userdata.value)
yellowfive@57 443 else
yellowfive@57 444 this:SetValue(true)
yellowfive@57 445 end
yellowfive@57 446 if self.open then
yellowfive@57 447 self.pullout:Close()
yellowfive@57 448 end
yellowfive@57 449 end
yellowfive@57 450 end
yellowfive@57 451
yellowfive@57 452 --[[ Exported methods ]]--
yellowfive@57 453
yellowfive@57 454 -- exported, AceGUI callback
yellowfive@57 455 local function OnAcquire(self)
yellowfive@57 456 local pullout = AceGUI:Create("Dropdown-Pullout")
yellowfive@57 457 self.pullout = pullout
yellowfive@57 458 pullout.userdata.obj = self
yellowfive@57 459 pullout:SetCallback("OnClose", OnPulloutClose)
yellowfive@57 460 pullout:SetCallback("OnOpen", OnPulloutOpen)
yellowfive@57 461 self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
yellowfive@57 462 fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
yellowfive@57 463
yellowfive@57 464 self:SetHeight(44)
yellowfive@57 465 self:SetWidth(200)
yellowfive@57 466 self:SetLabel()
yellowfive@57 467 self:SetPulloutWidth(nil)
yellowfive@57 468 end
yellowfive@57 469
yellowfive@57 470 -- exported, AceGUI callback
yellowfive@57 471 local function OnRelease(self)
yellowfive@57 472 if self.open then
yellowfive@57 473 self.pullout:Close()
yellowfive@57 474 end
yellowfive@57 475 AceGUI:Release(self.pullout)
yellowfive@57 476 self.pullout = nil
yellowfive@57 477
yellowfive@57 478 self:SetText("")
yellowfive@57 479 self:SetDisabled(false)
yellowfive@57 480 self:SetMultiselect(false)
yellowfive@57 481
yellowfive@57 482 self.value = nil
yellowfive@57 483 self.list = nil
yellowfive@57 484 self.open = nil
yellowfive@57 485 self.hasClose = nil
yellowfive@57 486
yellowfive@57 487 self.frame:ClearAllPoints()
yellowfive@57 488 self.frame:Hide()
yellowfive@57 489 end
yellowfive@57 490
yellowfive@57 491 -- exported
yellowfive@57 492 local function SetDisabled(self, disabled)
yellowfive@57 493 self.disabled = disabled
yellowfive@57 494 if disabled then
yellowfive@57 495 self.text:SetTextColor(0.5,0.5,0.5)
yellowfive@57 496 self.button:Disable()
yellowfive@57 497 self.button_cover:Disable()
yellowfive@57 498 self.label:SetTextColor(0.5,0.5,0.5)
yellowfive@57 499 else
yellowfive@57 500 self.button:Enable()
yellowfive@57 501 self.button_cover:Enable()
yellowfive@57 502 self.label:SetTextColor(1,.82,0)
yellowfive@57 503 self.text:SetTextColor(1,1,1)
yellowfive@57 504 end
yellowfive@57 505 end
yellowfive@57 506
yellowfive@57 507 -- exported
yellowfive@57 508 local function ClearFocus(self)
yellowfive@57 509 if self.open then
yellowfive@57 510 self.pullout:Close()
yellowfive@57 511 end
yellowfive@57 512 end
yellowfive@57 513
yellowfive@57 514 -- exported
yellowfive@57 515 local function SetText(self, text)
yellowfive@57 516 self.text:SetText(text or "")
yellowfive@57 517 end
yellowfive@57 518
yellowfive@57 519 -- exported
yellowfive@57 520 local function SetLabel(self, text)
yellowfive@57 521 if text and text ~= "" then
yellowfive@57 522 self.label:SetText(text)
yellowfive@57 523 self.label:Show()
yellowfive@57 524 self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-14)
yellowfive@57 525 self:SetHeight(40)
yellowfive@57 526 self.alignoffset = 26
yellowfive@57 527 else
yellowfive@57 528 self.label:SetText("")
yellowfive@57 529 self.label:Hide()
yellowfive@57 530 self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
yellowfive@57 531 self:SetHeight(26)
yellowfive@57 532 self.alignoffset = 12
yellowfive@57 533 end
yellowfive@57 534 end
yellowfive@57 535
yellowfive@57 536 -- exported
yellowfive@57 537 local function SetValue(self, value)
yellowfive@57 538 if self.list then
yellowfive@57 539 self:SetText(self.list[value] or "")
yellowfive@57 540 end
yellowfive@57 541 self.value = value
yellowfive@57 542 end
yellowfive@57 543
yellowfive@57 544 -- exported
yellowfive@57 545 local function GetValue(self)
yellowfive@57 546 return self.value
yellowfive@57 547 end
yellowfive@57 548
yellowfive@57 549 -- exported
yellowfive@57 550 local function SetItemValue(self, item, value)
yellowfive@57 551 if not self.multiselect then return end
yellowfive@57 552 for i, widget in self.pullout:IterateItems() do
yellowfive@57 553 if widget.userdata.value == item then
yellowfive@57 554 if widget.SetValue then
yellowfive@57 555 widget:SetValue(value)
yellowfive@57 556 end
yellowfive@57 557 end
yellowfive@57 558 end
yellowfive@57 559 ShowMultiText(self)
yellowfive@57 560 end
yellowfive@57 561
yellowfive@57 562 -- exported
yellowfive@57 563 local function SetItemDisabled(self, item, disabled)
yellowfive@57 564 for i, widget in self.pullout:IterateItems() do
yellowfive@57 565 if widget.userdata.value == item then
yellowfive@57 566 widget:SetDisabled(disabled)
yellowfive@57 567 end
yellowfive@57 568 end
yellowfive@57 569 end
yellowfive@57 570
yellowfive@57 571 local function AddListItem(self, value, text, itemType)
yellowfive@57 572 if not itemType then itemType = "Dropdown-Item-Toggle" end
yellowfive@57 573 local exists = AceGUI:GetWidgetVersion(itemType)
yellowfive@57 574 if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end
yellowfive@57 575
yellowfive@57 576 local item = AceGUI:Create(itemType)
yellowfive@57 577 item:SetText(text)
yellowfive@57 578 item.userdata.obj = self
yellowfive@57 579 item.userdata.value = value
yellowfive@57 580 item:SetCallback("OnValueChanged", OnItemValueChanged)
yellowfive@57 581 self.pullout:AddItem(item)
yellowfive@57 582 end
yellowfive@57 583
yellowfive@57 584 local function AddCloseButton(self)
yellowfive@57 585 if not self.hasClose then
yellowfive@57 586 local close = AceGUI:Create("Dropdown-Item-Execute")
yellowfive@57 587 close:SetText(CLOSE)
yellowfive@57 588 self.pullout:AddItem(close)
yellowfive@57 589 self.hasClose = true
yellowfive@57 590 end
yellowfive@57 591 end
yellowfive@57 592
yellowfive@57 593 -- exported
yellowfive@57 594 local sortlist = {}
yellowfive@57 595 local function SetList(self, list, order, itemType)
yellowfive@57 596 self.list = list
yellowfive@57 597 self.pullout:Clear()
yellowfive@57 598 self.hasClose = nil
yellowfive@57 599 if not list then return end
yellowfive@57 600
yellowfive@57 601 if type(order) ~= "table" then
yellowfive@57 602 for v in pairs(list) do
yellowfive@57 603 sortlist[#sortlist + 1] = v
yellowfive@57 604 end
yellowfive@57 605 tsort(sortlist)
yellowfive@57 606
yellowfive@57 607 for i, key in ipairs(sortlist) do
yellowfive@57 608 AddListItem(self, key, list[key], itemType)
yellowfive@57 609 sortlist[i] = nil
yellowfive@57 610 end
yellowfive@57 611 else
yellowfive@57 612 for i, key in ipairs(order) do
yellowfive@57 613 AddListItem(self, key, list[key], itemType)
yellowfive@57 614 end
yellowfive@57 615 end
yellowfive@57 616 if self.multiselect then
yellowfive@57 617 ShowMultiText(self)
yellowfive@57 618 AddCloseButton(self)
yellowfive@57 619 end
yellowfive@57 620 end
yellowfive@57 621
yellowfive@57 622 -- exported
yellowfive@57 623 local function AddItem(self, value, text, itemType)
yellowfive@57 624 if self.list then
yellowfive@57 625 self.list[value] = text
yellowfive@57 626 AddListItem(self, value, text, itemType)
yellowfive@57 627 end
yellowfive@57 628 end
yellowfive@57 629
yellowfive@57 630 -- exported
yellowfive@57 631 local function SetMultiselect(self, multi)
yellowfive@57 632 self.multiselect = multi
yellowfive@57 633 if multi then
yellowfive@57 634 ShowMultiText(self)
yellowfive@57 635 AddCloseButton(self)
yellowfive@57 636 end
yellowfive@57 637 end
yellowfive@57 638
yellowfive@57 639 -- exported
yellowfive@57 640 local function GetMultiselect(self)
yellowfive@57 641 return self.multiselect
yellowfive@57 642 end
yellowfive@57 643
yellowfive@57 644 local function SetPulloutWidth(self, width)
yellowfive@57 645 self.pulloutWidth = width
yellowfive@57 646 end
yellowfive@57 647
yellowfive@57 648 --[[ Constructor ]]--
yellowfive@57 649
yellowfive@57 650 local function Constructor()
yellowfive@57 651 local count = AceGUI:GetNextWidgetNum(widgetType)
yellowfive@57 652 local frame = CreateFrame("Frame", nil, UIParent)
yellowfive@57 653 local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
yellowfive@57 654
yellowfive@57 655 local self = {}
yellowfive@57 656 self.type = widgetType
yellowfive@57 657 self.frame = frame
yellowfive@57 658 self.dropdown = dropdown
yellowfive@57 659 self.count = count
yellowfive@57 660 frame.obj = self
yellowfive@57 661 dropdown.obj = self
yellowfive@57 662
yellowfive@57 663 self.OnRelease = OnRelease
yellowfive@57 664 self.OnAcquire = OnAcquire
yellowfive@57 665
yellowfive@57 666 self.ClearFocus = ClearFocus
yellowfive@57 667
yellowfive@57 668 self.SetText = SetText
yellowfive@57 669 self.SetValue = SetValue
yellowfive@57 670 self.GetValue = GetValue
yellowfive@57 671 self.SetList = SetList
yellowfive@57 672 self.SetLabel = SetLabel
yellowfive@57 673 self.SetDisabled = SetDisabled
yellowfive@57 674 self.AddItem = AddItem
yellowfive@57 675 self.SetMultiselect = SetMultiselect
yellowfive@57 676 self.GetMultiselect = GetMultiselect
yellowfive@57 677 self.SetItemValue = SetItemValue
yellowfive@57 678 self.SetItemDisabled = SetItemDisabled
yellowfive@57 679 self.SetPulloutWidth = SetPulloutWidth
yellowfive@57 680
yellowfive@57 681 self.alignoffset = 26
yellowfive@57 682
yellowfive@57 683 frame:SetScript("OnHide",Dropdown_OnHide)
yellowfive@57 684
yellowfive@57 685 dropdown:ClearAllPoints()
yellowfive@57 686 dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0)
yellowfive@57 687 dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0)
yellowfive@57 688 dropdown:SetScript("OnHide", nil)
yellowfive@57 689
yellowfive@57 690 local left = _G[dropdown:GetName() .. "Left"]
yellowfive@57 691 local middle = _G[dropdown:GetName() .. "Middle"]
yellowfive@57 692 local right = _G[dropdown:GetName() .. "Right"]
yellowfive@57 693
yellowfive@57 694 middle:ClearAllPoints()
yellowfive@57 695 right:ClearAllPoints()
yellowfive@57 696
yellowfive@57 697 middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
yellowfive@57 698 middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
yellowfive@57 699 right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
yellowfive@57 700
yellowfive@57 701 local button = _G[dropdown:GetName() .. "Button"]
yellowfive@57 702 self.button = button
yellowfive@57 703 button.obj = self
yellowfive@57 704 button:SetScript("OnEnter",Control_OnEnter)
yellowfive@57 705 button:SetScript("OnLeave",Control_OnLeave)
yellowfive@57 706 button:SetScript("OnClick",Dropdown_TogglePullout)
yellowfive@57 707
yellowfive@57 708 local button_cover = CreateFrame("BUTTON",nil,self.frame)
yellowfive@57 709 self.button_cover = button_cover
yellowfive@57 710 button_cover.obj = self
yellowfive@57 711 button_cover:SetPoint("TOPLEFT",self.frame,"BOTTOMLEFT",0,25)
yellowfive@57 712 button_cover:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT")
yellowfive@57 713 button_cover:SetScript("OnEnter",Control_OnEnter)
yellowfive@57 714 button_cover:SetScript("OnLeave",Control_OnLeave)
yellowfive@57 715 button_cover:SetScript("OnClick",Dropdown_TogglePullout)
yellowfive@57 716
yellowfive@57 717 local text = _G[dropdown:GetName() .. "Text"]
yellowfive@57 718 self.text = text
yellowfive@57 719 text.obj = self
yellowfive@57 720 text:ClearAllPoints()
yellowfive@57 721 text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
yellowfive@57 722 text:SetPoint("LEFT", left, "LEFT", 25, 2)
yellowfive@57 723
yellowfive@57 724 local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
yellowfive@57 725 label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
yellowfive@57 726 label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
yellowfive@57 727 label:SetJustifyH("LEFT")
yellowfive@57 728 label:SetHeight(18)
yellowfive@57 729 label:Hide()
yellowfive@57 730 self.label = label
yellowfive@57 731
yellowfive@57 732 AceGUI:RegisterAsWidget(self)
yellowfive@57 733 return self
yellowfive@57 734 end
yellowfive@57 735
yellowfive@57 736 AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
yellowfive@57 737 end