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