yellowfive@57: --[[ $Id: AceGUIWidget-DropDown.lua 1116 2014-10-12 08:15:46Z nevcairiel $ ]]-- yellowfive@57: local AceGUI = LibStub("AceGUI-3.0") yellowfive@57: yellowfive@57: -- Lua APIs yellowfive@57: local min, max, floor = math.min, math.max, math.floor yellowfive@57: local select, pairs, ipairs, type = select, pairs, ipairs, type yellowfive@57: local tsort = table.sort yellowfive@57: yellowfive@57: -- WoW APIs yellowfive@57: local PlaySound = PlaySound yellowfive@57: local UIParent, CreateFrame = UIParent, CreateFrame yellowfive@57: local _G = _G yellowfive@57: yellowfive@57: -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded yellowfive@57: -- List them here for Mikk's FindGlobals script yellowfive@57: -- GLOBALS: CLOSE yellowfive@57: yellowfive@57: local function fixlevels(parent,...) yellowfive@57: local i = 1 yellowfive@57: local child = select(i, ...) yellowfive@57: while child do yellowfive@57: child:SetFrameLevel(parent:GetFrameLevel()+1) yellowfive@57: fixlevels(child, child:GetChildren()) yellowfive@57: i = i + 1 yellowfive@57: child = select(i, ...) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function fixstrata(strata, parent, ...) yellowfive@57: local i = 1 yellowfive@57: local child = select(i, ...) yellowfive@57: parent:SetFrameStrata(strata) yellowfive@57: while child do yellowfive@57: fixstrata(strata, child, child:GetChildren()) yellowfive@57: i = i + 1 yellowfive@57: child = select(i, ...) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: do yellowfive@57: local widgetType = "Dropdown-Pullout" yellowfive@57: local widgetVersion = 3 yellowfive@57: yellowfive@57: --[[ Static data ]]-- yellowfive@57: yellowfive@57: local backdrop = { yellowfive@57: bgFile = "Interface\\ChatFrame\\ChatFrameBackground", yellowfive@57: edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", yellowfive@57: edgeSize = 32, yellowfive@57: tileSize = 32, yellowfive@57: tile = true, yellowfive@57: insets = { left = 11, right = 12, top = 12, bottom = 11 }, yellowfive@57: } yellowfive@57: local sliderBackdrop = { yellowfive@57: bgFile = "Interface\\Buttons\\UI-SliderBar-Background", yellowfive@57: edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", yellowfive@57: tile = true, tileSize = 8, edgeSize = 8, yellowfive@57: insets = { left = 3, right = 3, top = 3, bottom = 3 } yellowfive@57: } yellowfive@57: yellowfive@57: local defaultWidth = 200 yellowfive@57: local defaultMaxHeight = 600 yellowfive@57: yellowfive@57: --[[ UI Event Handlers ]]-- yellowfive@57: yellowfive@57: -- HACK: This should be no part of the pullout, but there yellowfive@57: -- is no other 'clean' way to response to any item-OnEnter yellowfive@57: -- Used to close Submenus when an other item is entered yellowfive@57: local function OnEnter(item) yellowfive@57: local self = item.pullout yellowfive@57: for k, v in ipairs(self.items) do yellowfive@57: if v.CloseMenu and v ~= item then yellowfive@57: v:CloseMenu() yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- See the note in Constructor() for each scroll related function yellowfive@57: local function OnMouseWheel(this, value) yellowfive@57: this.obj:MoveScroll(value) yellowfive@57: end yellowfive@57: yellowfive@57: local function OnScrollValueChanged(this, value) yellowfive@57: this.obj:SetScroll(value) yellowfive@57: end yellowfive@57: yellowfive@57: local function OnSizeChanged(this) yellowfive@57: this.obj:FixScroll() yellowfive@57: end yellowfive@57: yellowfive@57: --[[ Exported methods ]]-- yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetScroll(self, value) yellowfive@57: local status = self.scrollStatus yellowfive@57: local frame, child = self.scrollFrame, self.itemFrame yellowfive@57: local height, viewheight = frame:GetHeight(), child:GetHeight() yellowfive@57: yellowfive@57: local offset yellowfive@57: if height > viewheight then yellowfive@57: offset = 0 yellowfive@57: else yellowfive@57: offset = floor((viewheight - height) / 1000 * value) yellowfive@57: end yellowfive@57: child:ClearAllPoints() yellowfive@57: child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset) yellowfive@57: child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset) yellowfive@57: status.offset = offset yellowfive@57: status.scrollvalue = value yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function MoveScroll(self, value) yellowfive@57: local status = self.scrollStatus yellowfive@57: local frame, child = self.scrollFrame, self.itemFrame yellowfive@57: local height, viewheight = frame:GetHeight(), child:GetHeight() yellowfive@57: yellowfive@57: if height > viewheight then yellowfive@57: self.slider:Hide() yellowfive@57: else yellowfive@57: self.slider:Show() yellowfive@57: local diff = height - viewheight yellowfive@57: local delta = 1 yellowfive@57: if value < 0 then yellowfive@57: delta = -1 yellowfive@57: end yellowfive@57: self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000)) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function FixScroll(self) yellowfive@57: local status = self.scrollStatus yellowfive@57: local frame, child = self.scrollFrame, self.itemFrame yellowfive@57: local height, viewheight = frame:GetHeight(), child:GetHeight() yellowfive@57: local offset = status.offset or 0 yellowfive@57: yellowfive@57: if viewheight < height then yellowfive@57: self.slider:Hide() yellowfive@57: child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset) yellowfive@57: self.slider:SetValue(0) yellowfive@57: else yellowfive@57: self.slider:Show() yellowfive@57: local value = (offset / (viewheight - height) * 1000) yellowfive@57: if value > 1000 then value = 1000 end yellowfive@57: self.slider:SetValue(value) yellowfive@57: self:SetScroll(value) yellowfive@57: if value < 1000 then yellowfive@57: child:ClearAllPoints() yellowfive@57: child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset) yellowfive@57: child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset) yellowfive@57: status.offset = offset yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported, AceGUI callback yellowfive@57: local function OnAcquire(self) yellowfive@57: self.frame:SetParent(UIParent) yellowfive@57: --self.itemFrame:SetToplevel(true) yellowfive@57: end yellowfive@57: yellowfive@57: -- exported, AceGUI callback yellowfive@57: local function OnRelease(self) yellowfive@57: self:Clear() yellowfive@57: self.frame:ClearAllPoints() yellowfive@57: self.frame:Hide() yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function AddItem(self, item) yellowfive@57: self.items[#self.items + 1] = item yellowfive@57: yellowfive@57: local h = #self.items * 16 yellowfive@57: self.itemFrame:SetHeight(h) yellowfive@57: self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement yellowfive@57: yellowfive@57: item.frame:SetPoint("LEFT", self.itemFrame, "LEFT") yellowfive@57: item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT") yellowfive@57: yellowfive@57: item:SetPullout(self) yellowfive@57: item:SetOnEnter(OnEnter) yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function Open(self, point, relFrame, relPoint, x, y) yellowfive@57: local items = self.items yellowfive@57: local frame = self.frame yellowfive@57: local itemFrame = self.itemFrame yellowfive@57: yellowfive@57: frame:SetPoint(point, relFrame, relPoint, x, y) yellowfive@57: yellowfive@57: yellowfive@57: local height = 8 yellowfive@57: for i, item in pairs(items) do yellowfive@57: if i == 1 then yellowfive@57: item:SetPoint("TOP", itemFrame, "TOP", 0, -2) yellowfive@57: else yellowfive@57: item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1) yellowfive@57: end yellowfive@57: yellowfive@57: item:Show() yellowfive@57: yellowfive@57: height = height + 16 yellowfive@57: end yellowfive@57: itemFrame:SetHeight(height) yellowfive@57: fixstrata("TOOLTIP", frame, frame:GetChildren()) yellowfive@57: frame:Show() yellowfive@57: self:Fire("OnOpen") yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function Close(self) yellowfive@57: self.frame:Hide() yellowfive@57: self:Fire("OnClose") yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function Clear(self) yellowfive@57: local items = self.items yellowfive@57: for i, item in pairs(items) do yellowfive@57: AceGUI:Release(item) yellowfive@57: items[i] = nil yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function IterateItems(self) yellowfive@57: return ipairs(self.items) yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetHideOnLeave(self, val) yellowfive@57: self.hideOnLeave = val yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetMaxHeight(self, height) yellowfive@57: self.maxHeight = height or defaultMaxHeight yellowfive@57: if self.frame:GetHeight() > height then yellowfive@57: self.frame:SetHeight(height) yellowfive@57: elseif (self.itemFrame:GetHeight() + 34) < height then yellowfive@57: self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function GetRightBorderWidth(self) yellowfive@57: return 6 + (self.slider:IsShown() and 12 or 0) yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function GetLeftBorderWidth(self) yellowfive@57: return 6 yellowfive@57: end yellowfive@57: yellowfive@57: --[[ Constructor ]]-- yellowfive@57: yellowfive@57: local function Constructor() yellowfive@57: local count = AceGUI:GetNextWidgetNum(widgetType) yellowfive@57: local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent) yellowfive@57: local self = {} yellowfive@57: self.count = count yellowfive@57: self.type = widgetType yellowfive@57: self.frame = frame yellowfive@57: frame.obj = self yellowfive@57: yellowfive@57: self.OnAcquire = OnAcquire yellowfive@57: self.OnRelease = OnRelease yellowfive@57: yellowfive@57: self.AddItem = AddItem yellowfive@57: self.Open = Open yellowfive@57: self.Close = Close yellowfive@57: self.Clear = Clear yellowfive@57: self.IterateItems = IterateItems yellowfive@57: self.SetHideOnLeave = SetHideOnLeave yellowfive@57: yellowfive@57: self.SetScroll = SetScroll yellowfive@57: self.MoveScroll = MoveScroll yellowfive@57: self.FixScroll = FixScroll yellowfive@57: yellowfive@57: self.SetMaxHeight = SetMaxHeight yellowfive@57: self.GetRightBorderWidth = GetRightBorderWidth yellowfive@57: self.GetLeftBorderWidth = GetLeftBorderWidth yellowfive@57: yellowfive@57: self.items = {} yellowfive@57: yellowfive@57: self.scrollStatus = { yellowfive@57: scrollvalue = 0, yellowfive@57: } yellowfive@57: yellowfive@57: self.maxHeight = defaultMaxHeight yellowfive@57: yellowfive@57: frame:SetBackdrop(backdrop) yellowfive@57: frame:SetBackdropColor(0, 0, 0) yellowfive@57: frame:SetFrameStrata("FULLSCREEN_DIALOG") yellowfive@57: frame:SetClampedToScreen(true) yellowfive@57: frame:SetWidth(defaultWidth) yellowfive@57: frame:SetHeight(self.maxHeight) yellowfive@57: --frame:SetToplevel(true) yellowfive@57: yellowfive@57: -- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame yellowfive@57: local scrollFrame = CreateFrame("ScrollFrame", nil, frame) yellowfive@57: local itemFrame = CreateFrame("Frame", nil, scrollFrame) yellowfive@57: yellowfive@57: self.scrollFrame = scrollFrame yellowfive@57: self.itemFrame = itemFrame yellowfive@57: yellowfive@57: scrollFrame.obj = self yellowfive@57: itemFrame.obj = self yellowfive@57: yellowfive@57: local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame) yellowfive@57: slider:SetOrientation("VERTICAL") yellowfive@57: slider:SetHitRectInsets(0, 0, -10, 0) yellowfive@57: slider:SetBackdrop(sliderBackdrop) yellowfive@57: slider:SetWidth(8) yellowfive@57: slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical") yellowfive@57: slider:SetFrameStrata("FULLSCREEN_DIALOG") yellowfive@57: self.slider = slider yellowfive@57: slider.obj = self yellowfive@57: yellowfive@57: scrollFrame:SetScrollChild(itemFrame) yellowfive@57: scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12) yellowfive@57: scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12) yellowfive@57: scrollFrame:EnableMouseWheel(true) yellowfive@57: scrollFrame:SetScript("OnMouseWheel", OnMouseWheel) yellowfive@57: scrollFrame:SetScript("OnSizeChanged", OnSizeChanged) yellowfive@57: scrollFrame:SetToplevel(true) yellowfive@57: scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG") yellowfive@57: yellowfive@57: itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0) yellowfive@57: itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0) yellowfive@57: itemFrame:SetHeight(400) yellowfive@57: itemFrame:SetToplevel(true) yellowfive@57: itemFrame:SetFrameStrata("FULLSCREEN_DIALOG") yellowfive@57: yellowfive@57: slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0) yellowfive@57: slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0) yellowfive@57: slider:SetScript("OnValueChanged", OnScrollValueChanged) yellowfive@57: slider:SetMinMaxValues(0, 1000) yellowfive@57: slider:SetValueStep(1) yellowfive@57: slider:SetValue(0) yellowfive@57: yellowfive@57: scrollFrame:Show() yellowfive@57: itemFrame:Show() yellowfive@57: slider:Hide() yellowfive@57: yellowfive@57: self:FixScroll() yellowfive@57: yellowfive@57: AceGUI:RegisterAsWidget(self) yellowfive@57: return self yellowfive@57: end yellowfive@57: yellowfive@57: AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion) yellowfive@57: end yellowfive@57: yellowfive@57: do yellowfive@57: local widgetType = "Dropdown" yellowfive@57: local widgetVersion = 30 yellowfive@57: yellowfive@57: --[[ Static data ]]-- yellowfive@57: yellowfive@57: --[[ UI event handler ]]-- yellowfive@57: yellowfive@57: local function Control_OnEnter(this) yellowfive@57: this.obj.button:LockHighlight() yellowfive@57: this.obj:Fire("OnEnter") yellowfive@57: end yellowfive@57: yellowfive@57: local function Control_OnLeave(this) yellowfive@57: this.obj.button:UnlockHighlight() yellowfive@57: this.obj:Fire("OnLeave") yellowfive@57: end yellowfive@57: yellowfive@57: local function Dropdown_OnHide(this) yellowfive@57: local self = this.obj yellowfive@57: if self.open then yellowfive@57: self.pullout:Close() yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function Dropdown_TogglePullout(this) yellowfive@57: local self = this.obj yellowfive@57: PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound yellowfive@57: if self.open then yellowfive@57: self.open = nil yellowfive@57: self.pullout:Close() yellowfive@57: AceGUI:ClearFocus() yellowfive@57: else yellowfive@57: self.open = true yellowfive@57: self.pullout:SetWidth(self.pulloutWidth or self.frame:GetWidth()) yellowfive@57: self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0) yellowfive@57: AceGUI:SetFocus(self) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function OnPulloutOpen(this) yellowfive@57: local self = this.userdata.obj yellowfive@57: local value = self.value yellowfive@57: yellowfive@57: if not self.multiselect then yellowfive@57: for i, item in this:IterateItems() do yellowfive@57: item:SetValue(item.userdata.value == value) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: self.open = true yellowfive@57: self:Fire("OnOpened") yellowfive@57: end yellowfive@57: yellowfive@57: local function OnPulloutClose(this) yellowfive@57: local self = this.userdata.obj yellowfive@57: self.open = nil yellowfive@57: self:Fire("OnClosed") yellowfive@57: end yellowfive@57: yellowfive@57: local function ShowMultiText(self) yellowfive@57: local text yellowfive@57: for i, widget in self.pullout:IterateItems() do yellowfive@57: if widget.type == "Dropdown-Item-Toggle" then yellowfive@57: if widget:GetValue() then yellowfive@57: if text then yellowfive@57: text = text..", "..widget:GetText() yellowfive@57: else yellowfive@57: text = widget:GetText() yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: self:SetText(text) yellowfive@57: end yellowfive@57: yellowfive@57: local function OnItemValueChanged(this, event, checked) yellowfive@57: local self = this.userdata.obj yellowfive@57: yellowfive@57: if self.multiselect then yellowfive@57: self:Fire("OnValueChanged", this.userdata.value, checked) yellowfive@57: ShowMultiText(self) yellowfive@57: else yellowfive@57: if checked then yellowfive@57: self:SetValue(this.userdata.value) yellowfive@57: self:Fire("OnValueChanged", this.userdata.value) yellowfive@57: else yellowfive@57: this:SetValue(true) yellowfive@57: end yellowfive@57: if self.open then yellowfive@57: self.pullout:Close() yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: --[[ Exported methods ]]-- yellowfive@57: yellowfive@57: -- exported, AceGUI callback yellowfive@57: local function OnAcquire(self) yellowfive@57: local pullout = AceGUI:Create("Dropdown-Pullout") yellowfive@57: self.pullout = pullout yellowfive@57: pullout.userdata.obj = self yellowfive@57: pullout:SetCallback("OnClose", OnPulloutClose) yellowfive@57: pullout:SetCallback("OnOpen", OnPulloutOpen) yellowfive@57: self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1) yellowfive@57: fixlevels(self.pullout.frame, self.pullout.frame:GetChildren()) yellowfive@57: yellowfive@57: self:SetHeight(44) yellowfive@57: self:SetWidth(200) yellowfive@57: self:SetLabel() yellowfive@57: self:SetPulloutWidth(nil) yellowfive@57: end yellowfive@57: yellowfive@57: -- exported, AceGUI callback yellowfive@57: local function OnRelease(self) yellowfive@57: if self.open then yellowfive@57: self.pullout:Close() yellowfive@57: end yellowfive@57: AceGUI:Release(self.pullout) yellowfive@57: self.pullout = nil yellowfive@57: yellowfive@57: self:SetText("") yellowfive@57: self:SetDisabled(false) yellowfive@57: self:SetMultiselect(false) yellowfive@57: yellowfive@57: self.value = nil yellowfive@57: self.list = nil yellowfive@57: self.open = nil yellowfive@57: self.hasClose = nil yellowfive@57: yellowfive@57: self.frame:ClearAllPoints() yellowfive@57: self.frame:Hide() yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetDisabled(self, disabled) yellowfive@57: self.disabled = disabled yellowfive@57: if disabled then yellowfive@57: self.text:SetTextColor(0.5,0.5,0.5) yellowfive@57: self.button:Disable() yellowfive@57: self.button_cover:Disable() yellowfive@57: self.label:SetTextColor(0.5,0.5,0.5) yellowfive@57: else yellowfive@57: self.button:Enable() yellowfive@57: self.button_cover:Enable() yellowfive@57: self.label:SetTextColor(1,.82,0) yellowfive@57: self.text:SetTextColor(1,1,1) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function ClearFocus(self) yellowfive@57: if self.open then yellowfive@57: self.pullout:Close() yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetText(self, text) yellowfive@57: self.text:SetText(text or "") yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetLabel(self, text) yellowfive@57: if text and text ~= "" then yellowfive@57: self.label:SetText(text) yellowfive@57: self.label:Show() yellowfive@57: self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-14) yellowfive@57: self:SetHeight(40) yellowfive@57: self.alignoffset = 26 yellowfive@57: else yellowfive@57: self.label:SetText("") yellowfive@57: self.label:Hide() yellowfive@57: self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0) yellowfive@57: self:SetHeight(26) yellowfive@57: self.alignoffset = 12 yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetValue(self, value) yellowfive@57: if self.list then yellowfive@57: self:SetText(self.list[value] or "") yellowfive@57: end yellowfive@57: self.value = value yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function GetValue(self) yellowfive@57: return self.value yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetItemValue(self, item, value) yellowfive@57: if not self.multiselect then return end yellowfive@57: for i, widget in self.pullout:IterateItems() do yellowfive@57: if widget.userdata.value == item then yellowfive@57: if widget.SetValue then yellowfive@57: widget:SetValue(value) yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: ShowMultiText(self) yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetItemDisabled(self, item, disabled) yellowfive@57: for i, widget in self.pullout:IterateItems() do yellowfive@57: if widget.userdata.value == item then yellowfive@57: widget:SetDisabled(disabled) yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function AddListItem(self, value, text, itemType) yellowfive@57: if not itemType then itemType = "Dropdown-Item-Toggle" end yellowfive@57: local exists = AceGUI:GetWidgetVersion(itemType) yellowfive@57: if not exists then error(("The given item type, %q, does not exist within AceGUI-3.0"):format(tostring(itemType)), 2) end yellowfive@57: yellowfive@57: local item = AceGUI:Create(itemType) yellowfive@57: item:SetText(text) yellowfive@57: item.userdata.obj = self yellowfive@57: item.userdata.value = value yellowfive@57: item:SetCallback("OnValueChanged", OnItemValueChanged) yellowfive@57: self.pullout:AddItem(item) yellowfive@57: end yellowfive@57: yellowfive@57: local function AddCloseButton(self) yellowfive@57: if not self.hasClose then yellowfive@57: local close = AceGUI:Create("Dropdown-Item-Execute") yellowfive@57: close:SetText(CLOSE) yellowfive@57: self.pullout:AddItem(close) yellowfive@57: self.hasClose = true yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local sortlist = {} yellowfive@57: local function SetList(self, list, order, itemType) yellowfive@57: self.list = list yellowfive@57: self.pullout:Clear() yellowfive@57: self.hasClose = nil yellowfive@57: if not list then return end yellowfive@57: yellowfive@57: if type(order) ~= "table" then yellowfive@57: for v in pairs(list) do yellowfive@57: sortlist[#sortlist + 1] = v yellowfive@57: end yellowfive@57: tsort(sortlist) yellowfive@57: yellowfive@57: for i, key in ipairs(sortlist) do yellowfive@57: AddListItem(self, key, list[key], itemType) yellowfive@57: sortlist[i] = nil yellowfive@57: end yellowfive@57: else yellowfive@57: for i, key in ipairs(order) do yellowfive@57: AddListItem(self, key, list[key], itemType) yellowfive@57: end yellowfive@57: end yellowfive@57: if self.multiselect then yellowfive@57: ShowMultiText(self) yellowfive@57: AddCloseButton(self) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function AddItem(self, value, text, itemType) yellowfive@57: if self.list then yellowfive@57: self.list[value] = text yellowfive@57: AddListItem(self, value, text, itemType) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function SetMultiselect(self, multi) yellowfive@57: self.multiselect = multi yellowfive@57: if multi then yellowfive@57: ShowMultiText(self) yellowfive@57: AddCloseButton(self) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: -- exported yellowfive@57: local function GetMultiselect(self) yellowfive@57: return self.multiselect yellowfive@57: end yellowfive@57: yellowfive@57: local function SetPulloutWidth(self, width) yellowfive@57: self.pulloutWidth = width yellowfive@57: end yellowfive@57: yellowfive@57: --[[ Constructor ]]-- yellowfive@57: yellowfive@57: local function Constructor() yellowfive@57: local count = AceGUI:GetNextWidgetNum(widgetType) yellowfive@57: local frame = CreateFrame("Frame", nil, UIParent) yellowfive@57: local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate") yellowfive@57: yellowfive@57: local self = {} yellowfive@57: self.type = widgetType yellowfive@57: self.frame = frame yellowfive@57: self.dropdown = dropdown yellowfive@57: self.count = count yellowfive@57: frame.obj = self yellowfive@57: dropdown.obj = self yellowfive@57: yellowfive@57: self.OnRelease = OnRelease yellowfive@57: self.OnAcquire = OnAcquire yellowfive@57: yellowfive@57: self.ClearFocus = ClearFocus yellowfive@57: yellowfive@57: self.SetText = SetText yellowfive@57: self.SetValue = SetValue yellowfive@57: self.GetValue = GetValue yellowfive@57: self.SetList = SetList yellowfive@57: self.SetLabel = SetLabel yellowfive@57: self.SetDisabled = SetDisabled yellowfive@57: self.AddItem = AddItem yellowfive@57: self.SetMultiselect = SetMultiselect yellowfive@57: self.GetMultiselect = GetMultiselect yellowfive@57: self.SetItemValue = SetItemValue yellowfive@57: self.SetItemDisabled = SetItemDisabled yellowfive@57: self.SetPulloutWidth = SetPulloutWidth yellowfive@57: yellowfive@57: self.alignoffset = 26 yellowfive@57: yellowfive@57: frame:SetScript("OnHide",Dropdown_OnHide) yellowfive@57: yellowfive@57: dropdown:ClearAllPoints() yellowfive@57: dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0) yellowfive@57: dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0) yellowfive@57: dropdown:SetScript("OnHide", nil) yellowfive@57: yellowfive@57: local left = _G[dropdown:GetName() .. "Left"] yellowfive@57: local middle = _G[dropdown:GetName() .. "Middle"] yellowfive@57: local right = _G[dropdown:GetName() .. "Right"] yellowfive@57: yellowfive@57: middle:ClearAllPoints() yellowfive@57: right:ClearAllPoints() yellowfive@57: yellowfive@57: middle:SetPoint("LEFT", left, "RIGHT", 0, 0) yellowfive@57: middle:SetPoint("RIGHT", right, "LEFT", 0, 0) yellowfive@57: right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17) yellowfive@57: yellowfive@57: local button = _G[dropdown:GetName() .. "Button"] yellowfive@57: self.button = button yellowfive@57: button.obj = self yellowfive@57: button:SetScript("OnEnter",Control_OnEnter) yellowfive@57: button:SetScript("OnLeave",Control_OnLeave) yellowfive@57: button:SetScript("OnClick",Dropdown_TogglePullout) yellowfive@57: yellowfive@57: local button_cover = CreateFrame("BUTTON",nil,self.frame) yellowfive@57: self.button_cover = button_cover yellowfive@57: button_cover.obj = self yellowfive@57: button_cover:SetPoint("TOPLEFT",self.frame,"BOTTOMLEFT",0,25) yellowfive@57: button_cover:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT") yellowfive@57: button_cover:SetScript("OnEnter",Control_OnEnter) yellowfive@57: button_cover:SetScript("OnLeave",Control_OnLeave) yellowfive@57: button_cover:SetScript("OnClick",Dropdown_TogglePullout) yellowfive@57: yellowfive@57: local text = _G[dropdown:GetName() .. "Text"] yellowfive@57: self.text = text yellowfive@57: text.obj = self yellowfive@57: text:ClearAllPoints() yellowfive@57: text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2) yellowfive@57: text:SetPoint("LEFT", left, "LEFT", 25, 2) yellowfive@57: yellowfive@57: local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") yellowfive@57: label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) yellowfive@57: label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0) yellowfive@57: label:SetJustifyH("LEFT") yellowfive@57: label:SetHeight(18) yellowfive@57: label:Hide() yellowfive@57: self.label = label yellowfive@57: yellowfive@57: AceGUI:RegisterAsWidget(self) yellowfive@57: return self yellowfive@57: end yellowfive@57: yellowfive@57: AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion) yellowfive@57: end