local DF = _G ["DetailsFramework"] if (not DF or not DetailsFrameworkCanLoad) then return end local _ local loadedAPIDropDownFunctions = false do local metaPrototype = { WidgetType = "dropdown", dversion = DF.dversion, } --check if there's a metaPrototype already existing if (_G[DF.GlobalWidgetControlNames["dropdown"]]) then --get the already existing metaPrototype local oldMetaPrototype = _G[DF.GlobalWidgetControlNames["dropdown"]] --check if is older if ( (not oldMetaPrototype.dversion) or (oldMetaPrototype.dversion < DF.dversion) ) then --the version is older them the currently loading one --copy the new values into the old metatable for funcName, _ in pairs(metaPrototype) do oldMetaPrototype[funcName] = metaPrototype[funcName] end end else --first time loading the framework _G[DF.GlobalWidgetControlNames["dropdown"]] = metaPrototype end end local DropDownMetaFunctions = _G[DF.GlobalWidgetControlNames["dropdown"]] DF:Mixin(DropDownMetaFunctions, DF.SetPointMixin) DF:Mixin(DropDownMetaFunctions, DF.FrameMixin) DF:Mixin(DropDownMetaFunctions, DF.TooltipHandlerMixin) DF:Mixin(DropDownMetaFunctions, DF.ScriptHookMixin) ------------------------------------------------------------------------------------------------------------ --metatables DropDownMetaFunctions.__call = function(object, value) --unknown end ------------------------------------------------------------------------------------------------------------ --members --selected value local gmember_value = function(object) return object:GetValue() end --tooltip local gmember_tooltip = function(object) return object:GetTooltip() end --shown local gmember_shown = function(object) return object:IsShown() end --frame width local gmember_width = function(object) return object.button:GetWidth() end --frame height local gmember_height = function(object) return object.button:GetHeight() end --current text local gmember_text = function(object) return object.label:GetText() end --menu creation function local gmember_function = function(object) return object:GetFunction() end --menu width local gmember_menuwidth = function(object) return rawget(object, "realsizeW") end --menu height local gmember_menuheight = function(object) return rawget(object, "realsizeH") end DropDownMetaFunctions.GetMembers = DropDownMetaFunctions.GetMembers or {} DropDownMetaFunctions.GetMembers["value"] = gmember_value DropDownMetaFunctions.GetMembers["text"] = gmember_text DropDownMetaFunctions.GetMembers["shown"] = gmember_shown DropDownMetaFunctions.GetMembers["width"] = gmember_width DropDownMetaFunctions.GetMembers["menuwidth"] = gmember_menuwidth DropDownMetaFunctions.GetMembers["height"] = gmember_height DropDownMetaFunctions.GetMembers["menuheight"] = gmember_menuheight DropDownMetaFunctions.GetMembers["tooltip"] = gmember_tooltip DropDownMetaFunctions.GetMembers["func"] = gmember_function DropDownMetaFunctions.__index = function(object, key) local func = DropDownMetaFunctions.GetMembers[key] if (func) then return func(object, key) end local alreadyHaveKey = rawget(object, key) if (alreadyHaveKey) then return alreadyHaveKey end return DropDownMetaFunctions[key] end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --tooltip local smember_tooltip = function(object, value) return object:SetTooltip(value) end --show local smember_show = function(object, value) if (value) then return object:Show() else return object:Hide() end end --hide local smember_hide = function(object, value) if (not value) then return object:Show() else return object:Hide() end end --frame width local smember_width = function(object, value) return object.dropdown:SetWidth(value) end --frame height local smember_height = function(object, value) return object.dropdown:SetHeight(value) end --menu creation function local smember_function = function(object, value) return object:SetFunction(value) end --menu width local smember_menuwidth = function(object, value) object:SetMenuSize(value, nil) end --menu height local smember_menuheight = function(object, value) object:SetMenuSize(nil, value) end DropDownMetaFunctions.SetMembers = DropDownMetaFunctions.SetMembers or {} DropDownMetaFunctions.SetMembers["tooltip"] = smember_tooltip DropDownMetaFunctions.SetMembers["show"] = smember_show DropDownMetaFunctions.SetMembers["hide"] = smember_hide DropDownMetaFunctions.SetMembers["width"] = smember_width DropDownMetaFunctions.SetMembers["menuwidth"] = smember_menuwidth DropDownMetaFunctions.SetMembers["height"] = smember_height DropDownMetaFunctions.SetMembers["menuheight"] = smember_menuheight DropDownMetaFunctions.SetMembers["func"] = smember_function DropDownMetaFunctions.__newindex = function(object, key, value) local func = DropDownMetaFunctions.SetMembers[key] if (func) then return func(object, value) else return rawset(object, key, value) end end ------------------------------------------------------------------------------------------------------------ --menu width and height function DropDownMetaFunctions:SetMenuSize(width, height) if (width) then return rawset(self, "realsizeW", width) end if (height) then return rawset(self, "realsizeH", height) end end function DropDownMetaFunctions:GetMenuSize() return rawget(self, "realsizeW"), rawget(self, "realsizeH") end --function function DropDownMetaFunctions:SetFunction(func) return rawset(self, "func", func) end function DropDownMetaFunctions:GetFunction() return rawget(self, "func") end --value function DropDownMetaFunctions:GetValue() return rawget(self, "myvalue") end function DropDownMetaFunctions:SetValue(value) return rawset(self, "myvalue", value) end --frame levels function DropDownMetaFunctions:SetFrameLevel(level, frame) if (not frame) then return self.dropdown:SetFrameLevel(level) else local framelevel = frame:GetFrameLevel(frame) + level return self.dropdown:SetFrameLevel(framelevel) end end --enabled function DropDownMetaFunctions:IsEnabled() return self.dropdown:IsEnabled() end function DropDownMetaFunctions:Enable() self:SetAlpha(1) rawset(self, "lockdown", false) if (self.OnEnable) then self.OnEnable(self) end end function DropDownMetaFunctions:Disable() self:SetAlpha(.4) rawset(self, "lockdown", true) if (self.OnDisable) then self.OnDisable(self) end end --fixed value function DropDownMetaFunctions:SetFixedParameter(value) rawset(self, "FixedValue", value) end ------------------------------------------------------------------------------------------------------------ --scripts local lastOpened = false local isOptionVisible = function(self, thisOption) if (type(thisOption.shown) == "boolean") then return thisOption.shown elseif (type(thisOption.shown) == "function") then local result = DF:Dispatch(thisOption.shown, self) return result end return true end --return a table containing all frames of options in the menu function DropDownMetaFunctions:GetMenuFrames() --not tested if (self.MyObject) then self = self.MyObject end return self.menus end function DropDownMetaFunctions:GetFrameForOption(optionsTable, value) --not tested if (self.MyObject) then self = self.MyObject end if (type(value) == "string") then for i = 1, #optionsTable do local thisOption = optionsTable[i] if (thisOption.value == value or thisOption.label == value) then return self.menus[i] end end elseif (type(value) == "number") then return self.menus[value] end end function DropDownMetaFunctions:Refresh() local optionsTable = DF:Dispatch(self.func, self) if (#optionsTable == 0) then self:NoOption(true) self.no_options = true return false elseif (self.no_options) then self.no_options = false self:NoOption(false) self:NoOptionSelected() return true end return true end function DropDownMetaFunctions:NoOptionSelected() if (self.no_options) then return end self.label:SetText(self.empty_text or "no option selected") self.label:SetPoint("left", self.icon, "right", 2, 0) self.label:SetTextColor(1, 1, 1, 0.4) if (self.empty_icon) then self.icon:SetTexture(self.empty_icon) else self.icon:SetTexture([[Interface\COMMON\UI-ModelControlPanel]]) self.icon:SetTexCoord(0.625, 0.78125, 0.328125, 0.390625) end self.icon:SetVertexColor(1, 1, 1, 0.4) self.last_select = nil end function DropDownMetaFunctions:NoOption(state) if (state) then self:Disable() self:SetAlpha(0.5) self.no_options = true self.label:SetText("no options") self.label:SetPoint("left", self.icon, "right", 2, 0) self.label:SetTextColor(1, 1, 1, 0.4) self.icon:SetTexture([[Interface\CHARACTERFRAME\UI-Player-PlayTimeUnhealthy]]) self.icon:SetTexCoord(0, 1, 0, 1) self.icon:SetVertexColor(1, 1, 1, 0.4) else self.no_options = false self:Enable() self:SetAlpha(1) end end --@button: the frame button of the option --button.table refers to the optionTable local runCallbackFunctionForButton = function(button) --exec function if any if (button.table.onclick) then --need: the the callback func, the object of the dropdown (capsule), the object (capsule) of the button to get FixedValue and the last need the value of the optionTable local success, errorText = pcall(button.table.onclick, button:GetParent():GetParent():GetParent().MyObject, button.object.FixedValue, button.table.value) if (not success) then error("Details! Framework: dropdown " .. button:GetParent():GetParent():GetParent().MyObject:GetName() .. " error: " .. errorText) end button:GetParent():GetParent():GetParent().MyObject:RunHooksForWidget("OnOptionSelected", button:GetParent():GetParent():GetParent().MyObject, button.object.FixedValue, button.table.value) end end local canRunCallbackFunctionForOption = function(canRunCallback, optionTable, dropdownObject) if (canRunCallback) then local fixedValue = rawget(dropdownObject, "FixedValue") if (optionTable.onclick) then local success, errorText = pcall(optionTable.onclick, dropdownObject, fixedValue, optionTable.value) if (not success) then error("Details! Framework: dropdown " .. dropdownObject:GetName() .. " error: " .. errorText) end dropdownObject:RunHooksForWidget("OnOptionSelected", dropdownObject, fixedValue, optionTable.value) end end end --if onlyShown is true it'll first create a table with visible options that has .shown and then select in this table the index passed (if byOptionNumber) --@optionName: value or string shown in the name of the option --@byOptionNumber: the option name is considered a number and selects the index of the menu --@onlyShown: the selected option index when selecting by option number must be visible --@runCallback: run the callback (onclick) function after selecting the option function DropDownMetaFunctions:Select(optionName, byOptionNumber, onlyShown, runCallback) if (type(optionName) == "boolean" and not optionName) then self:NoOptionSelected() return false end local optionsTable = DF:Dispatch(self.func, self) if (#optionsTable == 0) then self:NoOption(true) return true else self:NoOption(false) end if (byOptionNumber and type(optionName) == "number") then local optionIndex = optionName if (onlyShown) then local onlyShownOptions = {} for i = 1, #optionsTable do local thisOption = optionsTable[i] if (thisOption.shown) then --only accept a function or a boolean into shown member if (type(thisOption.shown) == "function") then local isOptionShown = DF:Dispatch(thisOption.shown, self) if (isOptionShown) then onlyShownOptions[#onlyShownOptions+1] = thisOption end elseif (type(thisOption.shown) == "boolean" and thisOption.shown) then onlyShownOptions[#onlyShownOptions+1] = thisOption end end end local optionTableSelected = onlyShownOptions[optionIndex] if (not optionTableSelected) then self:NoOptionSelected() return false end self:Selected(optionTableSelected) canRunCallbackFunctionForOption(runCallback, optionTableSelected, self) return true else local optionTableSelected = optionsTable[optionIndex] --is an invalid index? if (not optionTableSelected) then self:NoOptionSelected() return false end self:Selected(optionTableSelected) canRunCallbackFunctionForOption(runCallback, optionTableSelected, self) return true end else for i = 1, #optionsTable do local thisOption = optionsTable[i] if ((thisOption.label == optionName or thisOption.value == optionName) and isOptionVisible(self, thisOption)) then self:Selected(thisOption) canRunCallbackFunctionForOption(runCallback, thisOption, self) return true end end end return false end function DropDownMetaFunctions:SetEmptyTextAndIcon(text, icon) if (text) then self.empty_text = text end if (icon) then self.empty_icon = icon end self:Selected(self.last_select) end function DropDownMetaFunctions:Selected(thisOption) if (not thisOption) then --does not have any options? if (not self:Refresh()) then self.last_select = nil return end --exists options but none selected self:NoOptionSelected() return end self.last_select = thisOption self:NoOption(false) self.label:SetText(thisOption.label) self.icon:SetTexture(thisOption.icon) if (thisOption.icon) then self.label:SetPoint("left", self.icon, "right", 2, 0) if (thisOption.texcoord) then self.icon:SetTexCoord(unpack(thisOption.texcoord)) else self.icon:SetTexCoord(0, 1, 0, 1) end if (thisOption.iconcolor) then local r, g, b, a = DF:ParseColors(thisOption.iconcolor) self.icon:SetVertexColor(r, g, b, a) else self.icon:SetVertexColor(1, 1, 1, 1) end self.icon:SetSize(self:GetHeight()-4, self:GetHeight()-4) else self.label:SetPoint("left", self.label:GetParent(), "left", 4, 0) end if (thisOption.statusbar) then self.statusbar:SetTexture(thisOption.statusbar) if (thisOption.statusbarcolor) then self.statusbar:SetVertexColor(unpack(thisOption.statusbarcolor)) end else self.statusbar:SetTexture([[Interface\Tooltips\CHATBUBBLE-BACKGROUND]]) end if (thisOption.color) then local r, g, b, a = DF:ParseColors(thisOption.color) self.label:SetTextColor(r, g, b, a) else self.label:SetTextColor(1, 1, 1, 1) end if (thisOption.font) then self.label:SetFont(thisOption.font, 10) else self.label:SetFont("GameFontHighlightSmall", 10) end self:SetValue(thisOption.value) end function DetailsFrameworkDropDownOptionClick(button) --update name and icon on main frame button.object:Selected(button.table) --close menu frame button.object:Close() --run callbacks runCallbackFunctionForButton(button) --set the value of selected option in main object button.object.myvalue = button.table.value button.object.myvaluelabel = button.table.label end function DropDownMetaFunctions:Open() self.dropdown.dropdownframe:Show() self.dropdown.dropdownborder:Show() self.opened = true if (lastOpened) then lastOpened:Close() end lastOpened = self end function DropDownMetaFunctions:Close() --when menu is being close, just hide the border and the script will call back this again if (self.dropdown.dropdownborder:IsShown()) then self.dropdown.dropdownborder:Hide() return end self.dropdown.dropdownframe:Hide() local selectedTexture = _G[self:GetName() .. "_ScrollFrame_ScrollChild_SelectedTexture"] selectedTexture:Hide() self.opened = false lastOpened = false end --close by escape key function DetailsFrameworkDropDownOptionsFrameOnHide(self) self:GetParent().MyObject:Close() end function DetailsFrameworkDropDownOptionOnEnter(self) if (self.table.desc) then GameCooltip2:Preset(2) GameCooltip2:AddLine(self.table.desc) if (self.table.descfont) then GameCooltip2:SetOption("TextFont", self.table.descfont) end if (self.table.tooltipwidth) then GameCooltip2:SetOption("FixedWidth", self.table.tooltipwidth) end GameCooltip2:SetHost(self, "topleft", "topright", 10, 0) GameCooltip2:ShowCooltip(nil, "tooltip") self.tooltip = true end self:GetParent().mouseover:SetPoint("left", self) self:GetParent().mouseover:Show() end function DetailsFrameworkDropDownOptionOnLeave(frame) if (frame.table.desc) then GameCooltip2:ShowMe(false) end frame:GetParent().mouseover:Hide() end --@button is the raw button frame, object is the button capsule function DetailsFrameworkDropDownOnMouseDown(button, buttontype) local object = button.MyObject --click to open if (not object.opened and not rawget(object, "lockdown")) then local optionsTable = DF:Dispatch(object.func, object) object.builtMenu = optionsTable local frameWitdh = object.realsizeW --has at least 1 option? if (optionsTable and optionsTable[1]) then local scrollFrame = _G[button:GetName() .. "_ScrollFrame"] local scrollChild = _G[button:GetName() .. "_ScrollFrame_ScrollChild"] local scrollBorder = _G[button:GetName() .. "_Border"] local selectedTexture = _G[button:GetName() .. "_ScrollFrame_ScrollChild_SelectedTexture"] local mouseOverTexture = _G[button:GetName() .. "_ScrollFrame_ScrollChild_MouseOverTexture"] local i = 1 local showing = 0 local currentText = button.text:GetText() or "" local currentIndex if (object.OnMouseDownHook) then local interrupt = object.OnMouseDownHook(button, buttontype, optionsTable, scrollFrame, scrollChild, selectedTexture) if (interrupt) then return end end for tindex, thisOption in ipairs(optionsTable) do local show = isOptionVisible(button, thisOption) if (show) then local thisOptionFrame = object.menus[i] showing = showing + 1 if (not thisOptionFrame) then local name = button:GetName() .. "Row" .. i local parent = scrollChild thisOptionFrame = DF:CreateDropdownButton(parent, name) local optionIndex = i - 1 thisOptionFrame:SetPoint("topleft", parent, "topleft", 1, (-optionIndex*20)-0) thisOptionFrame:SetPoint("topright", parent, "topright", 0, (-optionIndex*20)-0) thisOptionFrame.object = object object.menus[i] = thisOptionFrame end thisOptionFrame:SetFrameStrata(thisOptionFrame:GetParent():GetFrameStrata()) thisOptionFrame:SetFrameLevel(thisOptionFrame:GetParent():GetFrameLevel()+10) thisOptionFrame.icon:SetTexture(thisOption.icon) if (thisOption.icon) then thisOptionFrame.label:SetPoint("left", thisOptionFrame.icon, "right", 5, 0) if (thisOption.texcoord) then thisOptionFrame.icon:SetTexCoord(unpack(thisOption.texcoord)) else thisOptionFrame.icon:SetTexCoord(0, 1, 0, 1) end if (thisOption.iconcolor) then local r, g, b, a = DF:ParseColors(thisOption.iconcolor) thisOptionFrame.icon:SetVertexColor(r, g, b, a) else thisOptionFrame.icon:SetVertexColor(1, 1, 1, 1) end else thisOptionFrame.label:SetPoint("left", thisOptionFrame.statusbar, "left", 2, 0) end if (thisOption.iconsize) then thisOptionFrame.icon:SetSize(thisOption.iconsize[1], thisOption.iconsize[2]) else thisOptionFrame.icon:SetSize(thisOptionFrame:GetHeight()-6, thisOptionFrame:GetHeight()-6) end if (thisOption.font) then thisOptionFrame.label:SetFont(thisOption.font, 10.5) else thisOptionFrame.label:SetFont("GameFontHighlightSmall", 10.5) end if (thisOption.statusbar) then thisOptionFrame.statusbar:SetTexture(thisOption.statusbar) if (thisOption.statusbarcolor) then thisOptionFrame.statusbar:SetVertexColor(unpack(thisOption.statusbarcolor)) end else thisOptionFrame.statusbar:SetTexture([[Interface\Tooltips\CHATBUBBLE-BACKGROUND]]) end --an extra button in the right side of the row --run a given function passing the button in the first argument, the row on 2nd and the thisOption in the 3rd if (thisOption.rightbutton) then DF:Dispatch(thisOption.rightbutton, thisOptionFrame.rightButton, thisOptionFrame, thisOption) else thisOptionFrame.rightButton:Hide() end thisOptionFrame.label:SetText(thisOption.label) if (currentText and currentText == thisOption.label) then if (thisOption.icon) then selectedTexture:SetPoint("left", thisOptionFrame.icon, "left", -3, 0) else selectedTexture:SetPoint("left", thisOptionFrame.statusbar, "left", 0, 0) end selectedTexture:Show() selectedTexture:SetVertexColor(1, 1, 1, .3) selectedTexture:SetTexCoord(0, 29/32, 5/32, 27/32) currentIndex = tindex currentText = nil end if (thisOption.color) then local r, g, b, a = DF:ParseColors(thisOption.color) thisOptionFrame.label:SetTextColor(r, g, b, a) else thisOptionFrame.label:SetTextColor(1, 1, 1, 1) end thisOptionFrame.table = thisOption local labelwitdh = thisOptionFrame.label:GetStringWidth() if (labelwitdh+40 > frameWitdh) then frameWitdh = labelwitdh+40 end thisOptionFrame:Show() i = i + 1 end end if (currentText) then selectedTexture:Hide() else selectedTexture:SetWidth(frameWitdh - 20) end for o = showing + 1, #object.menus do object.menus[o]:Hide() end local size = object.realsizeH if (showing*20 > size) then --show scrollbar and setup scroll object:ShowScroll() scrollFrame:EnableMouseWheel(true) object.scroll:Altura(size-35) --height object.scroll:SetMinMaxValues(0, (showing * 20) - size + 2) --width scrollBorder:SetWidth(frameWitdh+20) scrollFrame:SetWidth(frameWitdh+20) scrollChild:SetWidth(frameWitdh+20) --height scrollBorder:SetHeight(size+2) scrollFrame:SetHeight(size+2) scrollChild:SetHeight((showing * 20) + 20) --mouse over texture mouseOverTexture:SetWidth(frameWitdh - 7) --selected selectedTexture:SetWidth(frameWitdh - 9) for index, row in ipairs(object.menus) do row:SetPoint("topright", scrollChild, "topright", -22, ((-index-1) * 20) - 5) end else --hide scrollbar and disable wheel object:HideScroll() scrollFrame:EnableMouseWheel(false) --width scrollBorder:SetWidth(frameWitdh) scrollFrame:SetWidth(frameWitdh) scrollChild:SetWidth(frameWitdh) --height scrollBorder:SetHeight((showing * 20) + 1) scrollFrame:SetHeight((showing * 20) + 1) --mouse over texture mouseOverTexture:SetWidth(frameWitdh - 1) --selected selectedTexture:SetWidth(frameWitdh - 1) for index, row in ipairs(object.menus) do row:SetPoint("topright", scrollChild, "topright", -5, ((-index-1) * 20) -5) end end if (object.myvaluelabel and currentIndex and scrollFrame.slider:IsShown()) then object.scroll:SetValue(max((currentIndex * 20) - 80, 0)) else object.scroll:SetValue(0) end object:Open() else --clear menu end else --click to close object:Close() end end function DetailsFrameworkDropDownOnEnter(self) local object = self.MyObject local kill = object:RunHooksForWidget("OnEnter", self, object) if (kill) then return end if (object.onenter_backdrop) then self:SetBackdropColor(unpack(object.onenter_backdrop)) else self:SetBackdropColor(.2, .2, .2, .2) end if (object.onenter_backdrop_border_color) then self:SetBackdropBorderColor(unpack(object.onenter_backdrop_border_color)) end self.arrowTexture2:Show() object:ShowTooltip() end function DetailsFrameworkDropDownOnLeave(self) local object = self.MyObject local kill = object:RunHooksForWidget("OnLeave", self, object) if (kill) then return end if (object.onleave_backdrop) then self:SetBackdropColor(unpack(object.onleave_backdrop)) else self:SetBackdropColor(1, 1, 1, .5) end if (object.onleave_backdrop_border_color) then self:SetBackdropBorderColor(unpack(object.onleave_backdrop_border_color)) end self.arrowTexture2:Hide() object:HideTooltip() end function DetailsFrameworkDropDownOnSizeChanged(self) local object = self.MyObject object.label:SetSize(self:GetWidth() - 40, 10) end function DetailsFrameworkDropDownOnShow(self) local object = self.MyObject local kill = object:RunHooksForWidget("OnShow", self, object) if (kill) then return end end function DetailsFrameworkDropDownOnHide(self) local object = self.MyObject local kill = object:RunHooksForWidget("OnHide", self, object) if (kill) then return end object:Close() end function DF:BuildDropDownFontList(onClick, icon, iconTexcoord, iconSize) local fontTable = {} local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0") for name, fontPath in pairs(SharedMedia:HashTable("font")) do fontTable[#fontTable+1] = {value = name, label = name, onclick = onClick, icon = icon, iconsize = iconSize, texcoord = iconTexcoord, font = fontPath, descfont = "abcdefg ABCDEFG"} end table.sort(fontTable, function(t1, t2) return t1.label < t2.label end) return fontTable end ------------------------------------------------------------------------------------------------------------ --template function DropDownMetaFunctions:SetTemplate(template) self.template = template if (template.width) then self:SetWidth(template.width) end if (template.height) then self:SetHeight(template.height) end if (template.backdrop) then self:SetBackdrop(template.backdrop) end if (template.backdropcolor) then local r, g, b, a = DF:ParseColors(template.backdropcolor) self:SetBackdropColor(r, g, b, a) self.onleave_backdrop = {r, g, b, a} end if (template.backdropbordercolor) then local r, g, b, a = DF:ParseColors(template.backdropbordercolor) self:SetBackdropBorderColor(r, g, b, a) self.onleave_backdrop_border_color = {r, g, b, a} end if (template.onentercolor) then local r, g, b, a = DF:ParseColors(template.onentercolor) self.onenter_backdrop = {r, g, b, a} end if (template.onleavecolor) then local r, g, b, a = DF:ParseColors(template.onleavecolor) self.onleave_backdrop = {r, g, b, a} end if (template.onenterbordercolor) then local r, g, b, a = DF:ParseColors(template.onenterbordercolor) self.onenter_backdrop_border_color = {r, g, b, a} end if (template.onleavebordercolor) then local r, g, b, a = DF:ParseColors(template.onleavebordercolor) self.onleave_backdrop_border_color = {r, g, b, a} end self:RefreshDropIcon() end function DropDownMetaFunctions:RefreshDropIcon() local template = self.template if (not template) then return end if (template.dropicon) then self.dropdown.arrowTexture:SetTexture(template.dropicon) self.dropdown.arrowTexture2:SetTexture(template.dropicon) if (template.dropiconsize) then self.dropdown.arrowTexture:SetSize(unpack(template.dropiconsize)) self.dropdown.arrowTexture2:SetSize(unpack(template.dropiconsize)) end if (template.dropiconcoords) then self.dropdown.arrowTexture:SetTexCoord(unpack(template.dropiconcoords)) else self.dropdown.arrowTexture:SetTexCoord(0, 1, 0, 1) end if (template.dropiconpoints) then self.dropdown.arrowTexture:ClearAllPoints() self.dropdown.arrowTexture2:ClearAllPoints() self.dropdown.arrowTexture:SetPoint("right", self.dropdown, "right", unpack(template.dropiconpoints)) self.dropdown.arrowTexture2:SetPoint("right", self.dropdown, "right", unpack(template.dropiconpoints)) end end end ------------------------------------------------------------------------------------------------------------ --object constructor function DF:CreateDropDown(parent, func, default, width, height, member, name, template) return DF:NewDropDown(parent, parent, name, member, width, height, func, default, template) end function DF:NewDropDown(parent, container, name, member, width, height, func, default, template) if (not name) then name = "DetailsFrameworkDropDownNumber" .. DF.DropDownCounter DF.DropDownCounter = DF.DropDownCounter + 1 elseif (not parent) then return error("Details! Framework: parent not found.", 2) end if (not container) then container = parent end if (name:find("$parent")) then local parentName = DF.GetParentName(parent) name = name:gsub("$parent", parentName) end local dropDownObject = {type = "dropdown", dframework = true} if (member) then parent[member] = dropDownObject end if (parent.dframework) then parent = parent.widget end if (container.dframework) then container = container.widget end if (default == nil) then default = 1 end dropDownObject.dropdown = DF:CreateNewDropdownFrame(parent, name) dropDownObject.dropdown:SetWidth(width) dropDownObject.dropdown:SetHeight(height) dropDownObject.container = container dropDownObject.widget = dropDownObject.dropdown dropDownObject.dropdown.MyObject = dropDownObject if (not loadedAPIDropDownFunctions) then loadedAPIDropDownFunctions = true local idx = getmetatable(dropDownObject.dropdown).__index for funcName, funcAddress in pairs(idx) do if (not DropDownMetaFunctions[funcName]) then DropDownMetaFunctions[funcName] = function(object, ...) local x = loadstring( "return _G['"..object.dropdown:GetName().."']:"..funcName.."(...)") return x(...) end end end end dropDownObject.func = func dropDownObject.realsizeW = 150 dropDownObject.realsizeH = 150 dropDownObject.FixedValue = nil dropDownObject.opened = false dropDownObject.menus = {} dropDownObject.myvalue = nil dropDownObject.label = _G[name .. "_Text"] dropDownObject.icon = _G[name .. "_IconTexture"] dropDownObject.statusbar = _G[name .. "_StatusBarTexture"] dropDownObject.select = _G[name .. "_SelectedTexture"] local scroll = _G[dropDownObject.dropdown:GetName() .. "_ScrollFrame"] dropDownObject.scroll = DF:NewScrollBar(scroll, _G[dropDownObject.dropdown:GetName() .. "_ScrollFrame" .. "_ScrollChild"], -18, -18) DF:ReskinSlider(scroll) function dropDownObject:HideScroll() scroll.baixo:Hide() scroll.cima:Hide() scroll.slider:Hide() end function dropDownObject:ShowScroll() scroll.baixo:Show() scroll.cima:Show() scroll.slider:Show() end dropDownObject:HideScroll() dropDownObject.label:SetSize(dropDownObject.dropdown:GetWidth()-40, 10) --hook list dropDownObject.HookList = { OnEnter = {}, OnLeave = {}, OnHide = {}, OnShow = {}, OnOptionSelected = {}, } --set default scripts dropDownObject.dropdown:SetScript("OnShow", DetailsFrameworkDropDownOnShow) dropDownObject.dropdown:SetScript("OnHide", DetailsFrameworkDropDownOnHide) dropDownObject.dropdown:SetScript("OnEnter", DetailsFrameworkDropDownOnEnter) dropDownObject.dropdown:SetScript("OnLeave", DetailsFrameworkDropDownOnLeave) setmetatable(dropDownObject, DropDownMetaFunctions) --initialize first menu selected if (type(default) == "string") then dropDownObject:Select(default) elseif (type(default) == "number") then if (not dropDownObject:Select(default)) then dropDownObject:Select(default, true) end end if (template) then dropDownObject:SetTemplate(template) end return dropDownObject end local defaultBackdrop = {bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]], edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]], edgeSize = 1, tile = true, tileSize = 16, insets = {left = 1, right = 1, top = 0, bottom = 1}} local borderBackdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, insets = {left = 0, right = 0, top = 0, bottom = 0}} local childBackdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 256, insets = {left = 0, right = 0, top = 0, bottom = 0}} function DF:CreateNewDropdownFrame(parent, name) local newDropdownFrame = CreateFrame("button", name, parent, "BackdropTemplate") newDropdownFrame:SetBackdrop(defaultBackdrop) newDropdownFrame:SetBackdropColor(1, 1, 1, .5) newDropdownFrame:SetSize(150, 20) local statusbar = newDropdownFrame:CreateTexture("$parent_StatusBarTexture", "BACKGROUND") statusbar:SetPoint("topleft", newDropdownFrame, "topleft", 0, 0) statusbar:SetPoint("bottomright", newDropdownFrame, "bottomright", 0, 0) newDropdownFrame.statusbar = statusbar local icon = newDropdownFrame:CreateTexture("$parent_IconTexture", "ARTWORK") icon:SetPoint("left", newDropdownFrame, "left", 2, 0) icon:SetSize(20, 20) icon:SetTexture([[Interface\COMMON\UI-ModelControlPanel]]) icon:SetTexCoord(0.625, 0.78125, 0.328125, 0.390625) icon:SetVertexColor(1, 1, 1, 0.4) newDropdownFrame.icon = icon local text = newDropdownFrame:CreateFontString("$parent_Text", "ARTWORK", "GameFontHighlightSmall") text:SetPoint("left", icon, "right", 5, 0) text:SetJustifyH("left") text:SetText("no option selected") text:SetTextColor(1, 1, 1, 0.4) DF:SetFontSize(text, 10) newDropdownFrame.text = text local arrowHightlight = newDropdownFrame:CreateTexture("$parent_ArrowTexture2", "OVERLAY", nil, 2) arrowHightlight:SetPoint("right", newDropdownFrame, "right", 5, -1) arrowHightlight:SetBlendMode("ADD") arrowHightlight:SetTexture([[Interface\Buttons\UI-ScrollBar-ScrollDownButton-Highlight]]) arrowHightlight:Hide() arrowHightlight:SetSize(32, 28) newDropdownFrame.arrowTexture2 = arrowHightlight local arrowTexture = newDropdownFrame:CreateTexture("$parent_ArrowTexture", "OVERLAY", nil, 1) arrowTexture:SetPoint("right", newDropdownFrame, "right", 5, -1) arrowTexture:SetTexture([[Interface\Buttons\UI-ScrollBar-ScrollDownButton-Up]]) arrowTexture:SetSize(32, 28) newDropdownFrame.arrowTexture = arrowTexture --scripts newDropdownFrame:SetScript("OnSizeChanged", DetailsFrameworkDropDownOnSizeChanged) newDropdownFrame:SetScript("OnMouseDown", DetailsFrameworkDropDownOnMouseDown) --dropdown local border = CreateFrame("frame", "$Parent_Border", newDropdownFrame, "BackdropTemplate") border:Hide() border:SetFrameStrata("FULLSCREEN") border:SetSize(150, 150) border:SetPoint("topleft", newDropdownFrame, "bottomleft", 0, 0) border:SetBackdrop(borderBackdrop) border:SetScript("OnHide", DetailsFrameworkDropDownOptionsFrameOnHide) border:SetBackdropColor(0, 0, 0, 0.92) border:SetBackdropBorderColor(0, 0, 0, 1) newDropdownFrame.dropdownborder = border local scroll = CreateFrame("ScrollFrame", "$Parent_ScrollFrame", newDropdownFrame, "BackdropTemplate") scroll:SetFrameStrata("FULLSCREEN") scroll:SetSize(150, 150) scroll:SetPoint("topleft", newDropdownFrame, "bottomleft", 0, 0) scroll:Hide() newDropdownFrame.dropdownframe = scroll local child = CreateFrame("frame", "$Parent_ScrollChild", scroll, "BackdropTemplate") child:SetSize(150, 150) child:SetPoint("topleft", scroll, "topleft", 0, 0) child:SetBackdrop(childBackdrop) child:SetBackdropColor(0, 0, 0, 1) local backgroundTexture = child:CreateTexture(nil, "background") backgroundTexture:SetAllPoints() backgroundTexture:SetColorTexture(0, 0, 0, 1) DF:ApplyStandardBackdrop(child) local selected = child:CreateTexture("$parent_SelectedTexture", "BACKGROUND") selected:SetSize(150, 16) selected:SetPoint("left", child, "left", 2, 0) selected:SetTexture([[Interface\RAIDFRAME\Raid-Bar-Hp-Fill]]) selected:Hide() child.selected = selected local mouseover = child:CreateTexture("$parent_MouseOverTexture", "ARTWORK") mouseover:SetBlendMode("ADD") mouseover:SetTexture([[Interface\Buttons\UI-Listbox-Highlight]]) mouseover:SetSize(150, 15) mouseover:SetPoint("left", child, "left", 2, 0) mouseover:Hide() child.mouseover = mouseover scroll:SetScrollChild(child) tinsert(UISpecialFrames, newDropdownFrame.dropdownborder:GetName()) --tinsert(UISpecialFrames, f.dropdownframe:GetName()) --not adding this solves an issue with ConsolePort addon and stackoverflows on Hide... return newDropdownFrame end function DF:CreateDropdownButton(parent, name) local newButton = CreateFrame("button", name, parent, "BackdropTemplate") newButton:SetSize(150, 20) local statusbar = newButton:CreateTexture("$parent_StatusBarTexture", "ARTWORK") statusbar:SetPoint("topleft", newButton, "topleft", 0, 0) statusbar:SetPoint("bottomright", newButton, "bottomright", 0, 0) statusbar:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]]) newButton.statusbar = statusbar local icon = newButton:CreateTexture("$parent_IconTexture", "OVERLAY") icon:SetPoint("left", newButton, "left", 2, 0) icon:SetSize(20, 20) icon:SetTexture([[Interface\ICONS\Spell_ChargePositive]]) newButton.icon = icon local text = newButton:CreateFontString("$parent_Text", "OVERLAY", "GameFontHighlightSmall") text:SetPoint("left", icon, "right", 5, 0) text:SetJustifyH("left") DF:SetFontSize(text, 10) newButton.label = text local rightButton = DF:CreateButton(newButton, function()end, 16, 16, "", 0, 0, "", "rightButton", "$parentRightButton", nil, DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")) rightButton:SetPoint("right", newButton, "right", -2, 0) rightButton:Hide() newButton:SetScript("OnMouseDown", DetailsFrameworkDropDownOptionClick) newButton:SetScript("OnEnter", DetailsFrameworkDropDownOptionOnEnter) newButton:SetScript("OnLeave", DetailsFrameworkDropDownOptionOnLeave) return newButton end