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