vatam icon

Untitled

vatam | PRO | 07/06/14 11:34:44 PM UTC | 0 ⭐ | 348 👁️ | Never ⏰ | []
Lua |

18.89 KB

|

None

|

0 👍

/

0 👎

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

Comments

  • Cuiznxcn icon
    05/18/26 04:38:44 AM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400