local _ , addon = ...
local L = addon.L ;
local API = addon.API ;
local Clamp = API.Clamp ;
local ThemeUtil = addon.ThemeUtil ;
local InCombatLockdown = InCombatLockdown ;
local CreateFrame = CreateFrame ;
local type = type ;
local GetDBValue = addon.GetDBValue ;
local SetDBValue = addon.SetDBValue ;
local INPUT_DEVICE_GAME_PAD = false ;
local INPUT_DEVICE_ID = 1 ;
local GAME_PAD_ACTIVE = false ;
local BUTTON_PADDING_LARGE = 12 ;
local FONT_HEIGHT_LARGE = 12 ;
local FONT_HEIGHT_NORMAL = 12 ;
local FRAME_PADDING = 14 ;
local OPTIONBUTTON_HEIGHT = 36 ; --Adaptive
local OPTIONBUTTON_WIDTH = OPTIONBUTTON_HEIGHT * 12 ; --Adaptive
local OPTIONBUTTON_FROM_Y = 4 ;
local OPTIONBUTTON_LABEL_OFFSET = 14 ;
local OPTION_WIDGET_SIZE = 24 ;
local NUM_VISIBLE_OPTIONS = 10.5 ;
local ARROWOPTION_VALUETEXT_OFFSET_Y = - 2 ;
local ARROWOTPION_WIDTH_RATIO = 7 ; --Adaptive
local ARROWOTPION_BAR_HEIGHT = 5 ; --Adaptive
local ARROWOTPION_CYCLING = false ;
local HOTKEYFRAME_VALUETEXT_GAP = 4 ;
local TAB_BUTTON_GAP = 4 ;
local DISABLED_TEXTURE_ALPHA = 0.2 ;
local PREVIEW_PATH = " Interface/AddOns/DialogueUI/Art/PreviewPicture/ " ;
local MainFrame ;
local function Reposition_OnDragStart ( self )
if self.OnMouseUp then
self : OnMouseUp ( ) ;
end
MainFrame : StartMoving ( ) ;
end
local function Reposition_OnDragStop ( self )
MainFrame : StopMovingOrSizing ( ) ;
MainFrame : UpdateScrollFrameBound ( ) ;
end
local function SetupRepositionObject ( obj )
obj : SetScript ( " OnDragStart " , Reposition_OnDragStart ) ;
obj : SetScript ( " OnDragStop " , Reposition_OnDragStop ) ;
obj : RegisterForDrag ( " LeftButton " ) ;
end
DUIDialogSettingsMixin = { } ;
function DUIDialogSettingsMixin : OnLoad ( )
MainFrame = self ;
addon.SettingsUI = self ;
addon.PixelUtil : AddPixelPerfectObject ( self ) ;
SetupRepositionObject ( self.Header ) ;
end
function DUIDialogSettingsMixin : OnShow_First ( )
if self.Init then
self : Init ( ) ;
end
self : Layout ( ) ;
self : UpdatePixel ( ) ;
self : SetScript ( " OnShow " , self.OnShow ) ;
self.tabID = 1 ;
self : OnShow ( ) ;
end
function DUIDialogSettingsMixin : OnShow ( )
self : UpdateCurrentTab ( ) ;
self : EnableGamePadButton ( true ) ;
self : RegisterEvent ( " GAME_PAD_ACTIVE_CHANGED " ) ;
self : RegisterEvent ( " GAME_PAD_DISCONNECTED " ) ;
self : MoveToBestPosition ( ) ;
addon.CallbackRegistry : Trigger ( " SettingsUI.Show " ) ;
end
function DUIDialogSettingsMixin : MoveToBestPosition ( )
if addon.DialogueUI : IsShown ( ) then
local viewportWidth , viewportHeight = WorldFrame : GetSize ( ) ; --height unaffected by screen resolution
viewportWidth = math.min ( viewportWidth , viewportHeight * 16 / 9 ) ;
local frameWidth = self : GetWidth ( ) ;
self : ClearAllPoints ( ) ;
self : SetPoint ( " CENTER " , nil , " CENTER " , 0.5 * frameWidth - 0.5 * viewportWidth + 16 , 0 ) ;
else
self : ClearAllPoints ( ) ;
self : SetPoint ( " CENTER " , nil , " CENTER " , 0 , 0 ) ;
end
self : UpdateScrollFrameBound ( ) ;
end
function DUIDialogSettingsMixin : UpdateScrollFrameBound ( )
self.scrollFrameTop = self.ScrollFrame : GetTop ( ) ;
self.scrollFrameBottom = self.ScrollFrame : GetBottom ( ) ;
end
function DUIDialogSettingsMixin : OnKeyDown ( key )
local valid = false ;
if key == " ESCAPE " or key == " F1 " then
self : Hide ( ) ;
valid = true ;
end
if not InCombatLockdown ( ) then
self : SetPropagateKeyboardInput ( not valid ) ;
end
end
function DUIDialogSettingsMixin : OnGamePadButtonDown ( button )
--print(button)
GAME_PAD_ACTIVE = true ;
local valid = false ;
if button == " PADFORWARD " or button == " PADBACK " or button == " PAD2 " then
self : Hide ( ) ;
valid = true ;
elseif button == " PADLSHOULDER " then
self : SelectTabByDelta ( - 1 ) ;
valid = true ;
elseif button == " PADRSHOULDER " then
self : SelectTabByDelta ( 1 ) ;
valid = true ;
elseif button == " PADDUP " then
self : FocusObjectByDelta ( 1 ) ;
valid = true ;
elseif button == " PADDDOWN " then
self : FocusObjectByDelta ( - 1 ) ;
valid = true ;
elseif button == " PADDLEFT " or button == " PADDRIGHT " or button == " PAD1 " then
self : ClickFocusedObject ( button ) ;
valid = true ;
end
if not InCombatLockdown ( ) then
self : SetPropagateKeyboardInput ( not valid ) ;
end
end
function DUIDialogSettingsMixin : OnMouseWheel ( delta )
end
function DUIDialogSettingsMixin : LoadTheme ( )
if self.Init then return end ;
local filePath = ThemeUtil : GetTexturePath ( ) ;
self.Background : SetTexture ( filePath .. " Settings-Background.png " ) ;
self.BackgroundShadow : SetTexture ( filePath .. " Settings-BackgroundShadow.png " ) ;
self.HeaderDivider : SetTexture ( filePath .. " Settings-Divider-H.png " ) ;
self.VerticalDivider : SetTexture ( filePath .. " Settings-Divider-V.png " ) ;
self.PreviewBorder : SetTexture ( filePath .. " Settings-PreviewBorder.png " ) ;
self.Header . Selection : SetTexture ( filePath .. " Settings-TabButton-Selection.png " ) ;
self.ButtonHighlight . BackTexture : SetTexture ( filePath .. " Settings-ButtonHighlight.png " ) ;
local file1 = filePath .. " Settings-CloseButton.png " ;
self.Header . CloseButton.Background : SetTexture ( file1 ) ;
self.Header . CloseButton.Highlight : SetTexture ( file1 ) ;
self.Header . CloseButton.Icon : SetTexture ( file1 ) ;
local file2 = filePath .. " Settings-Checkbox.png " ;
self.checkboxPool : ProcessAllObjects ( function ( widget )
widget : SetTexture ( file2 ) ;
end ) ;
local file3 = filePath .. " Settings-ArrowOption.png " ;
local file4 = filePath .. " Settings-ArrowOption.png " ;
self.arrowOptionPool : ProcessAllObjects ( function ( widget )
widget : SetTexture ( file3 ) ;
widget.barPool : ProcessAllObjects ( function ( bar )
bar : SetTexture ( file4 ) ;
end ) ;
end ) ;
if self.hotkeyFramePool then
self.hotkeyFramePool : CallAllObjects ( " LoadTheme " ) ;
end
self.BackgroundDecor : SetTexture ( filePath .. " Settings-BackgroundDecor.png " ) ;
local themeID ;
if ThemeUtil : IsDarkMode ( ) then
themeID = 2 ;
self.BackgroundDecor : SetBlendMode ( " ADD " ) ;
else
themeID = 1 ;
self.BackgroundDecor : SetBlendMode ( " BLEND " ) ;
end
self.ScrollBar : SetTheme ( themeID ) ;
for i , button in ipairs ( self.tabButtons ) do
local isSelected = button.isSelected ;
button.isSelected = true ;
button : SetSelected ( isSelected ) ;
end
end
function DUIDialogSettingsMixin : UpdatePixel ( scale )
if not scale then
scale = self : GetEffectiveScale ( ) ;
end
local pixelOffset = 10.0 ;
local offset = API.GetPixelForScale ( scale , pixelOffset ) ;
self.BackgroundShadow : ClearAllPoints ( ) ;
self.BackgroundShadow : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , - offset , offset ) ;
self.BackgroundShadow : SetPoint ( " BOTTOMRIGHT " , self , " BOTTOMRIGHT " , offset , - offset ) ;
API.UpdateTextureSliceScale ( self.Background ) ;
API.UpdateTextureSliceScale ( self.BackgroundShadow ) ;
API.UpdateTextureSliceScale ( self.PreviewBorder ) ;
end
function DUIDialogSettingsMixin : HighlightButton ( button )
self.ButtonHighlight : Hide ( ) ;
self.ButtonHighlight : ClearAllPoints ( ) ;
if button and button : IsEnabled ( ) then
self.ButtonHighlight : SetParent ( button ) ;
self.ButtonHighlight : SetPoint ( " TOPLEFT " , button , " TOPLEFT " , 0 , 0 ) ;
self.ButtonHighlight : SetPoint ( " BOTTOMRIGHT " , button , " BOTTOMRIGHT " , 0 , 0 ) ;
self.ButtonHighlight : Show ( ) ;
end
end
function DUIDialogSettingsMixin : OnHide ( )
self.focusedObject = nil ;
self.focusedObjectOffsetY = nil ;
self.scrollFrameTop = nil ;
self.scrollFrameBottom = nil ;
self : EnableGamePadButton ( false ) ;
self : UnregisterEvent ( " GAME_PAD_ACTIVE_CHANGED " ) ;
self : UnregisterEvent ( " GAME_PAD_DISCONNECTED " ) ;
addon.CallbackRegistry : Trigger ( " SettingsUI.Hide " ) ;
end
function DUIDialogSettingsMixin : OnEvent ( event , ... )
if event == " GAME_PAD_ACTIVE_CHANGED " then
local isActive = ...
GAME_PAD_ACTIVE = isActive ;
elseif event == " GAME_PAD_DISCONNECTED " then
GAME_PAD_ACTIVE = false ;
end
end
function DUIDialogSettingsMixin : SetPreviewTexture ( optionData )
if optionData.preview and ( type ( optionData.preview ) == " string " ) then
self.Preview : SetTexture ( PREVIEW_PATH .. optionData.preview ) ;
end
if optionData.ratio == 1 then
self.Preview : SetWidth ( self.previewHeight ) ;
elseif optionData.ratio == 2 then
self.Preview : SetWidth ( 2 * self.previewHeight ) ;
else
end
end
function DUIDialogSettingsMixin : DisplayOptionInfo ( optionData , choiceTooltip )
local hasPreview ;
if optionData.preview then
hasPreview = true ;
self : SetPreviewTexture ( optionData ) ;
else
hasPreview = false ;
end
self.Preview : SetShown ( hasPreview ) ;
self.PreviewBorder : SetShown ( hasPreview ) ;
if hasPreview then
if not self.hasPreview then
self.hasPreview = true ;
self.Description : ClearAllPoints ( ) ;
self.Description : SetPoint ( " TOP " , self.Preview , " BOTTOM " , 0 , - FRAME_PADDING ) ;
end
else
if self.hasPreview then
self.hasPreview = nil ;
self.Description : ClearAllPoints ( ) ;
self.Description : SetPoint ( " TOP " , self.Preview , " TOP " , 0 , - 8 ) ;
end
end
if choiceTooltip and optionData.description then
self.Description : SetText ( optionData.description .. " \n \n " .. choiceTooltip ) ;
else
self.Description : SetText ( optionData.description ) ;
end
end
local function ValueTextFormatter_PrimaryControlKey ( arrowOptionButton , dbValue )
local f = arrowOptionButton.HotkeyFrame ;
if not f then
f = MainFrame.hotkeyFramePool : Acquire ( ) ;
arrowOptionButton.HotkeyFrame = f ;
end
f : SetBaseHeight ( 20 ) ;
local key , keyDesc , errorText ;
if dbValue == 1 then
key = " SPACE " ;
keyDesc = L [ " Key Space " ] ;
elseif dbValue == 2 then
key , errorText = API.GetBestInteractKey ( ) ;
keyDesc = L [ " Key Interact " ] ;
elseif dbValue == 0 then
key = " DISABLED " ;
keyDesc = L [ " Key Disabled " ] ;
end
local fontString = arrowOptionButton.ValueText ;
f : SetKey ( key or " ERROR " ) ;
fontString : SetText ( keyDesc ) ;
local widgetWidth = f : GetWidth ( ) + HOTKEYFRAME_VALUETEXT_GAP ;
fontString : ClearAllPoints ( ) ;
fontString : SetPoint ( " TOP " , arrowOptionButton , " TOP " , widgetWidth * 0.5 , ARROWOPTION_VALUETEXT_OFFSET_Y ) ;
f : ClearAllPoints ( ) ;
f : SetPoint ( " RIGHT " , fontString , " LEFT " , - HOTKEYFRAME_VALUETEXT_GAP , 0 ) ;
end
local function PrimaryControlKey_Interact_Tooltip ( )
local key , errorText = API.GetBestInteractKey ( ) ;
if errorText then
local additionalTooltip = errorText .. " \n \n " .. L [ " Use Default Control Key Alert " ] ;
return additionalTooltip
end
end
local function TTSHotkey_Tooltip ( )
local device ;
if INPUT_DEVICE_ID == 1 then
device = " PC " ;
elseif INPUT_DEVICE_ID == 2 then
device = " Xbox " ;
elseif INPUT_DEVICE_ID == 3 then
device = " PlayStation " ;
elseif INPUT_DEVICE_ID == 4 then
device = " Switch " ;
else
device = " PC " ;
end
return L [ " TTS Use Hotkey Tooltip " .. device ]
end
local function QuestItemDisplay_Move_OnClick ( )
addon.QuestItemDisplay : EnterEditMode ( ) ;
end
local function QuestItemDisplay_Reset_OnClick ( )
addon.QuestItemDisplay : ResetPosition ( ) ;
end
local function QuestItemDisplayPosition_Validation ( )
local f = addon.QuestItemDisplay ;
return f and f : IsUsingCustomPosition ( )
end
local function RPAddOn_Validation ( )
return addon.GetInstalledRPAddOnName ( ) ~= nil
end
local function RPAddOn_ReplaceName_Tooltip ( )
local addOnName = addon.GetInstalledRPAddOnName ( ) ;
if addOnName then
return L [ " Format Functionality Handled By " ] : format ( addOnName ) ;
end
end
local Schematic = {
{
tabName = L [ " UI " ] ,
options = {
{ type = " ArrowOption " , name = L [ " Theme " ] , description = L [ " Theme Desc " ] , dbKey = " Theme " , preview = " Theme " , ratio = 2 ,
choices = {
{ dbValue = 1 , valueText = L [ " Theme Brown " ] } ,
{ dbValue = 2 , valueText = L [ " Theme Dark " ] } ,
} ,
} ,
{ type = " ArrowOption " , name = L [ " Frame Size " ] , description = L [ " Frame Size Desc " ] , dbKey = " FrameSize " ,
choices = {
{ dbValue = 0 , valueText = L [ " Size Extra Small " ] } ,
{ dbValue = 1 , valueText = L [ " Size Small " ] } ,
{ dbValue = 2 , valueText = L [ " Size Medium " ] } ,
{ dbValue = 3 , valueText = L [ " Size Large " ] } ,
} ,
} ,
{ type = " ArrowOption " , name = L [ " Font Size " ] , description = L [ " Font Size Desc " ] , dbKey = " FontSizeBase " , realignAfterClicks = true ,
choices = {
{ dbValue = 0 , valueText = " 10 " } ,
{ dbValue = 1 , valueText = " 12 " } ,
{ dbValue = 2 , valueText = " 14 " } ,
{ dbValue = 3 , valueText = " 16 " } ,
} ,
} ,
{ type = " Checkbox " , name = L [ " Hide UI " ] , description = L [ " Hide UI Desc " ] , dbKey = " HideUI " } ,
{ type = " Checkbox " , name = L [ " Hide Unit Names " ] , description = L [ " Hide Unit Names Desc " ] , dbKey = " HideUnitNames " , parentKey = " HideUI " , requiredParentValue = true } ,
{ type = " Checkbox " , name = L [ " Show Copy Text Button " ] , description = L [ " Show Copy Text Button Desc " ] , preview = " CopyTextButton " , ratio = 1 , dbKey = " ShowCopyTextButton " } ,
{ type = " Checkbox " , name = L [ " Show NPC Name On Page " ] , description = L [ " Show NPC Name On Page Desc " ] , dbKey = " ShowNPCNameOnPage " } ,
{ type = " Subheader " , name = L [ " Quest " ] } ,
{ type = " Checkbox " , name = L [ " Mark Highest Sell Price " ] , description = L [ " Mark Highest Sell Price Desc " ] , dbKey = " MarkHighestSellPrice " , preview = " MarkHighestSellPrice " , ratio = 1 } ,
{ type = " Checkbox " , name = L [ " Show Quest Type Text " ] , description = L [ " Show Quest Type Text Desc " ] , dbKey = " QuestTypeText " , preview = " QuestTypeText " , ratio = 1 } ,
{ type = " Checkbox " , name = L [ " Simplify Currency Rewards " ] , description = L [ " Simplify Currency Rewards Desc " ] , dbKey = " SimplifyCurrencyReward " , preview = " SimplifyCurrencyReward " , ratio = 2 } ,
{ type = " Subheader " , name = L [ " Roleplaying " ] , validationFunc = RPAddOn_Validation } ,
{ type = " Checkbox " , name = L [ " Use RP Name In Dialogues " ] , description = L [ " Use RP Name In Dialogues Desc " ] , tooltip = RPAddOn_ReplaceName_Tooltip , dbKey = " UseRoleplayName " , validationFunc = RPAddOn_Validation } ,
} ,
} ,
{
tabName = L [ " Camera " ] ,
options = {
{ type = " ArrowOption " , name = L [ " Camera Movement " ] , dbKey = " CameraMovement " ,
choices = {
{ dbValue = 0 , valueText = L [ " Camera Movement Off " ] } ,
{ dbValue = 1 , valueText = L [ " Camera Movement Zoom In " ] } ,
{ dbValue = 2 , valueText = L [ " Camera Movement Horizontal " ] } ,
} ,
} ,
{ type = " Checkbox " , name = L [ " Change FOV " ] , description = L [ " Change FOV Desc " ] , dbKey = " CameraChangeFov " , parentKey = " CameraMovement " , requiredParentValue = 1 , preview = " CameraChangeFov " , ratio = 2 } ,
{ type = " Checkbox " , name = L [ " Maintain Camera Position " ] , description = L [ " Maintain Camera Position Desc " ] , dbKey = " CameraMovement1MaintainPosition " , parentKey = " CameraMovement " , requiredParentValue = 1 } ,
--{type = "Checkbox", name = L["Maintain Camera Position"], description = L["Maintain Camera Position Desc"], dbKey = "CameraMovement2MaintainPosition", parentKey = "CameraMovement", requiredParentValue = 2, },
{ type = " Checkbox " , name = L [ " Maintain Offset While Mounted " ] , description = L [ " Maintain Offset While Mounted Desc " ] , dbKey = " CameraMovementMountedCamera " , parentKey = " CameraMovement " , requiredParentValue = { 1 , 2 } } ,
{ type = " Checkbox " , name = L [ " Disable Camera Movement Instance " ] , description = L [ " Disable Camera Movement Instance Desc " ] , dbKey = " CameraMovementDisableInstance " , parentKey = " CameraMovement " , requiredParentValue = { 1 , 2 } } ,
} ,
} ,
{
tabName = L [ " Control " ] ,
options = {
{ type = " ArrowOption " , name = L [ " Input Device " ] , dbKey = " InputDevice " , description = L [ " Input Device Desc " ] ,
choices = {
{ dbValue = 1 , valueText = L [ " Input Device KBM " ] } ,
{ dbValue = 2 , valueText = L [ " Input Device Xbox " ] , tooltip = L [ " Input Device Xbox Tooltip " ] } ,
{ dbValue = 3 , valueText = L [ " Input Device PlayStation " ] , tooltip = L [ " Input Device PlayStation Tooltip " ] } ,
{ dbValue = 4 , valueText = L [ " Input Device Switch " ] , tooltip = L [ " Input Device Switch Tooltip " ] } ,
} ,
} ,
{ type = " ArrowOption " , name = L [ " Primary Control Key " ] , description = L [ " Primary Control Key Desc " ] , dbKey = " PrimaryControlKey " , valueTextFormatter = ValueTextFormatter_PrimaryControlKey , hasHotkey = true , parentKey = " InputDevice " , requiredParentValue = 1 ,
choices = {
{ dbValue = 1 , valueText = L [ " Key Space " ] } ,
{ dbValue = 2 , valueText = L [ " Key Interact " ] , tooltip = PrimaryControlKey_Interact_Tooltip } ,
{ dbValue = 0 , valueText = L [ " Key Disabled " ] , tooltip = L [ " Key Disabled Tooltip " ] } ,
} ,
} ,
{ type = " Subheader " , name = L [ " Quest " ] } ,
{ type = " Checkbox " , name = L [ " Press Button To Scroll Down " ] , description = L [ " Press Button To Scroll Down Desc " ] , dbKey = " ScrollDownThenAcceptQuest " } ,
} ,
} ,
{
tabName = L [ " Gameplay " ] ,
options = {
{ type = " Checkbox " , name = L [ " Quest Item Display " ] , description = L [ " Quest Item Display Desc " ] , dbKey = " QuestItemDisplay " , preview = " QuestItemDisplay " , ratio = 2 } ,
{ type = " Checkbox " , name = L [ " Quest Item Display Hide Seen " ] , description = L [ " Quest Item Display Hide Seen Desc " ] , dbKey = " QuestItemDisplayHideSeen " , parentKey = " QuestItemDisplay " , requiredParentValue = true } ,
{ type = " Custom " , name = L [ " Move Position " ] , icon = " Settings-Move.png " , parentKey = " QuestItemDisplay " , requiredParentValue = true , onClickFunc = QuestItemDisplay_Move_OnClick } ,
{ type = " Custom " , name = L [ " Reset Position " ] , icon = " Settings-Reset.png " , description = L [ " Quest Item Display Reset Position Desc " ] , parentKey = " QuestItemDisplay " , requiredParentValue = true , validationFunc = QuestItemDisplayPosition_Validation , onClickFunc = QuestItemDisplay_Reset_OnClick } ,
{ type = " Subheader " , name = L [ " Gossip " ] } ,
{ type = " Checkbox " , name = L [ " Auto Select Gossip " ] , description = L [ " Auto Select Gossip Desc " ] , dbKey = " AutoSelectGossip " } ,
{ type = " Checkbox " , name = L [ " Force Gossip " ] , description = L [ " Force Gossip Desc " ] , dbKey = " ForceGossip " } ,
--{type = "Checkbox", name = L["Nameplate Dialog"], description = L["Nameplate Dialog Desc"], dbKey = "NameplateDialogEnabled", preview = "NameplateDialogEnabled", ratio = 1},
} ,
} ,
{
tabName = L [ " Accessibility " ] ,
options = {
{ type = " Checkbox " , name = L [ " TTS " ] , description = L [ " TTS Desc " ] , dbKey = " TTSEnabled " , preview = " TTSButton " , ratio = 1 } ,
{ type = " Checkbox " , name = L [ " TTS Use Hotkey " ] , description = L [ " TTS Use Hotkey Desc " ] , tooltip = TTSHotkey_Tooltip , dbKey = " TTSUseHotkey " , parentKey = " TTSEnabled " , requiredParentValue = true } ,
{ type = " Checkbox " , name = L [ " TTS Auto Play " ] , description = L [ " TTS Auto Play Desc " ] , dbKey = " TTSAutoPlay " , parentKey = " TTSEnabled " , requiredParentValue = true } ,
{ type = " Checkbox " , name = L [ " TTS Auto Stop " ] , description = L [ " TTS Auto Stop Desc " ] , dbKey = " TTSAutoStop " , parentKey = " TTSEnabled " , requiredParentValue = true } ,
} ,
} ,
} ;
local CloseButtonScripts = { } ;
function CloseButtonScripts : OnClick ( )
MainFrame : Hide ( ) ;
end
function CloseButtonScripts : OnEnter ( )
self.Highlight : Show ( ) ;
end
function CloseButtonScripts : OnLeave ( )
self.Highlight : Hide ( ) ;
end
function CloseButtonScripts : OnMouseDown ( )
self.Icon : SetPoint ( " CENTER " , 0 , - 1 ) ;
end
function CloseButtonScripts : OnMouseUp ( )
self.Icon : SetPoint ( " CENTER " , 0 , 0 ) ;
end
function CloseButtonScripts : OnHide ( )
self.Highlight : Hide ( ) ;
self.Icon : SetPoint ( " CENTER " , 0 , 0 ) ;
end
local function RemoveWidget ( widget )
widget : Hide ( ) ;
widget : ClearAllPoints ( ) ;
widget : SetParent ( MainFrame ) ;
widget.HotkeyFrame = nil ;
end
local function CreateOptionButton ( )
local optionButton = CreateFrame ( " Button " , nil , MainFrame , " DUIDialogSettingsOptionTemplate " ) ;
return optionButton
end
local function CreateCheckbox ( )
local checkbox = CreateFrame ( " Button " , nil , MainFrame , " DUIDialogSettingsCheckboxTemplate " ) ;
return checkbox
end
local function OnAcquireCheckbox ( checkbox )
checkbox : SetTexture ( ThemeUtil : GetTextureFile ( " Settings-Checkbox.png " ) ) ;
end
local function CreateArrowOption ( )
local widget = CreateFrame ( " Frame " , nil , MainFrame , " DUIDialogSettingsArrowOptionTemplate " ) ;
return widget
end
local function OnAcquireArrowOption ( widget )
widget : SetTexture ( ThemeUtil : GetTextureFile ( " Settings-ArrowOption.png " ) ) ;
end
local TextureFrameMixin = { } ;
function TextureFrameMixin : SetTexture ( file )
self.Texture : SetTexture ( file ) ;
end
function TextureFrameMixin : SetVertexColor ( r , g , b , a )
self.Texture : SetVertexColor ( r , g , b , a )
end
local function CreateTexture ( )
local f = CreateFrame ( " Frame " , nil , MainFrame , " DUIDialogSettingsTextureFrameTemplate " ) ;
API.Mixin ( f , TextureFrameMixin ) ;
return f
end
local ScrollFrameMixin = { } ;
function ScrollFrameMixin : SetViewSize ( height )
self.viewSize = height ;
self : SetHeight ( height ) ;
end
function ScrollFrameMixin : GetViewSize ( )
return self.viewSize or 0
end
function ScrollFrameMixin : SetScrollRange ( range )
if range < 0 then
range = 0 ;
self.scrollBar : Hide ( ) ;
MainFrame.VerticalDivider : Show ( ) ;
else
self.scrollBar : Show ( ) ;
MainFrame.VerticalDivider : Hide ( ) ;
end
self.maxScrollOffset = range ;
self.scrollBar : UpdateThumbSize ( ) ;
end
function ScrollFrameMixin : GetScrollRange ( )
return self.maxScrollOffset or 0
end
function ScrollFrameMixin : SetContentHeight ( contentHeight )
self : SetScrollRange ( contentHeight - self : GetViewSize ( ) ) ;
end
function ScrollFrameMixin : GetScrollOffset ( )
return self.scrollOffset or 0
end
function ScrollFrameMixin : SetScrollOffset ( scrollOffset )
scrollOffset = Clamp ( scrollOffset , 0 , self.maxScrollOffset ) ;
if scrollOffset ~= self.scrollOffset then
self.scrollOffset = scrollOffset ;
self.Reference : SetPoint ( " TOPLEFT " , 0 , scrollOffset ) ;
self.scrollBar : UpdateThumbPosition ( ) ;
end
end
function ScrollFrameMixin : IsAtBottom ( )
return self : GetScrollOffset ( ) + 0.1 >= self : GetScrollRange ( ) ;
end
function ScrollFrameMixin : ScrollBy ( offset )
self : SetScrollOffset ( self : GetScrollOffset ( ) + offset ) ;
end
function ScrollFrameMixin : ScrollToBottom ( )
self : SetScrollOffset ( self : GetScrollRange ( ) ) ;
end
function ScrollFrameMixin : OnMouseWheel ( delta )
if delta > 0 then
self : ScrollBy ( - OPTIONBUTTON_HEIGHT ) ;
else
self : ScrollBy ( OPTIONBUTTON_HEIGHT ) ;
end
end
function DUIDialogSettingsMixin : Init ( )
--Tab Buttons
if not self.tabButtons then
self.tabButtons = { } ;
end
self.optionButtonPool = API.CreateObjectPool ( CreateOptionButton , RemoveWidget ) ;
self.checkboxPool = API.CreateObjectPool ( CreateCheckbox , RemoveWidget , OnAcquireCheckbox ) ;
self.arrowOptionPool = API.CreateObjectPool ( CreateArrowOption , RemoveWidget , OnAcquireArrowOption ) ;
self.texturePool = API.CreateObjectPool ( CreateTexture ) ;
local function CreateHotkeyFrame ( )
local f = CreateFrame ( " Frame " , nil , self , " DUIDialogHotkeyTemplate " ) ;
f : SetShowDisabledKey ( true ) ;
return f
end
local function RemoveHotkeyFrame ( f )
f : ClearKey ( ) ;
f : ClearAllPoints ( ) ;
f : SetParent ( self ) ;
end
self.hotkeyFramePool = API.CreateObjectPool ( CreateHotkeyFrame , RemoveHotkeyFrame ) ;
self.numTabs = # Schematic ;
for i , tabData in ipairs ( Schematic ) do
if not self.tabButtons [ i ] then
self.tabButtons [ i ] = CreateFrame ( " Button " , nil , self.Header . Container , " DUIDialogSettingsTabButtonTemplate " ) ;
SetupRepositionObject ( self.tabButtons [ i ] ) ;
end
self.tabButtons [ i ] . tabID = i ;
self.tabButtons [ i ] : SetName ( tabData.tabName ) ;
end
--Close Button
local CloseButton = self.Header . CloseButton ;
for method , func in pairs ( CloseButtonScripts ) do
CloseButton : SetScript ( method , func ) ;
end
CloseButton.Background : SetTexCoord ( 0 , 0.5 , 0 , 0.5 ) ;
CloseButton.Highlight : SetTexCoord ( 0.5 , 1 , 0 , 0.5 ) ;
CloseButton.Icon : SetTexCoord ( 0.0625 , 0.1875 , 0.625 , 0.875 ) ;
API.Mixin ( self.ScrollFrame , ScrollFrameMixin ) ;
self.ScrollFrame : SetScript ( " OnMouseWheel " , ScrollFrameMixin.OnMouseWheel ) ;
--ScrollBar
local ScrollBar = addon.CreateScrollBar ( self ) ;
self.ScrollBar = ScrollBar ;
self.ScrollFrame . scrollBar = ScrollBar ;
ScrollBar : SetOwner ( self.ScrollFrame ) ;
ScrollBar : SetAlwaysVisible ( false ) ;
ScrollBar : ShowScrollToBottomButton ( false ) ;
ScrollBar : Show ( ) ;
self.Init = nil ;
self : LoadTheme ( ) ;
end
function DUIDialogSettingsMixin : Layout ( )
OPTIONBUTTON_HEIGHT = FONT_HEIGHT_NORMAL + 2 * BUTTON_PADDING_LARGE ;
--Header
local tabButtonHeight = FONT_HEIGHT_LARGE + 2 * BUTTON_PADDING_LARGE ;
local minTabButtonWidth = 2 * tabButtonHeight ;
local headerHeight = tabButtonHeight ;
self.Header : ClearAllPoints ( ) ;
self.Header : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , FRAME_PADDING , - FRAME_PADDING ) ;
self.Header : SetPoint ( " TOPRIGHT " , self , " TOPRIGHT " , - FRAME_PADDING , - FRAME_PADDING ) ;
self.Header : SetHeight ( headerHeight ) ;
local tabButtonContainer = self.Header . Container ;
self.Header . CloseButton : ClearAllPoints ( ) ;
self.Header . CloseButton : SetParent ( tabButtonContainer ) ;
self.Header . CloseButton : SetPoint ( " RIGHT " , tabButtonContainer , " RIGHT " , 0 , 0 ) ;
self.Header . CloseButton : SetSize ( minTabButtonWidth , tabButtonHeight ) ;
self.Header . CloseButton.Icon : SetSize ( FONT_HEIGHT_LARGE , FONT_HEIGHT_LARGE ) ;
self.HeaderDivider : ClearAllPoints ( ) ;
self.HeaderDivider : SetPoint ( " TOPLEFT " , self.Header , " BOTTOMLEFT " , 0 , - TAB_BUTTON_GAP ) ;
self.HeaderDivider : SetPoint ( " TOPRIGHT " , self.Header , " BOTTOMRIGHT " , 0 , - TAB_BUTTON_GAP ) ;
self.HeaderDivider : SetHeight ( 9 ) ;
--Tab Buttons
local buttonWidth ;
local tabButtonsSpan = 0 ;
for i , button in ipairs ( self.tabButtons ) do
buttonWidth = API.Round ( button.Name : GetWrappedWidth ( ) + 2 * FONT_HEIGHT_LARGE ) ;
if buttonWidth < minTabButtonWidth then
buttonWidth = minTabButtonWidth ;
end
button : SetSize ( buttonWidth , tabButtonHeight ) ;
tabButtonsSpan = tabButtonsSpan + buttonWidth ;
button : ClearAllPoints ( ) ;
if i > 1 then
button : SetPoint ( " LEFT " , self.tabButtons [ i - 1 ] , " RIGHT " , TAB_BUTTON_GAP , 0 ) ;
tabButtonsSpan = tabButtonsSpan + TAB_BUTTON_GAP ;
end
end
local tabFromOffsetX = ( INPUT_DEVICE_GAME_PAD and 60 ) or 0 ;
local firstTabButton = self.tabButtons [ 1 ] ;
firstTabButton : ClearAllPoints ( ) ;
firstTabButton : SetPoint ( " LEFT " , tabButtonContainer , " LEFT " , tabFromOffsetX , 0 ) ;
--ScrollFrame
local scrollFrameWidth = OPTIONBUTTON_WIDTH ;
local scrollFrameHeight = NUM_VISIBLE_OPTIONS * OPTIONBUTTON_HEIGHT ;
local ScrollFrame = self.ScrollFrame ;
local gapToHeader = 12 ;
ScrollFrame : ClearAllPoints ( ) ;
ScrollFrame : SetPoint ( " TOPLEFT " , self.Header , " BOTTOMLEFT " , 0 , - gapToHeader ) ;
ScrollFrame : SetWidth ( scrollFrameWidth ) ;
ScrollFrame : SetViewSize ( scrollFrameHeight ) ;
--ScrollBar
local ScrollBar = self.ScrollBar ;
local scrollBarOffsetX = OPTIONBUTTON_FROM_Y ;
ScrollBar : SetPoint ( " TOPLEFT " , ScrollFrame , " TOPRIGHT " , scrollBarOffsetX , 0 ) ;
ScrollBar : SetPoint ( " BOTTOMLEFT " , ScrollFrame , " BOTTOMRIGHT " , scrollBarOffsetX , 0 ) ;
ScrollBar : OnSizeChanged ( ) ;
self.VerticalDivider : ClearAllPoints ( ) ;
self.VerticalDivider : SetPoint ( " TOPLEFT " , ScrollBar , " TOP " , - 2 , 0 ) ;
self.VerticalDivider : SetPoint ( " BOTTOMLEFT " , ScrollBar , " BOTTOM " , - 2 , 0 ) ;
local frameWidth = API.Round ( ( scrollFrameWidth + 1.5 * FRAME_PADDING ) / 0.618 ) ;
local frameHeight = FRAME_PADDING + headerHeight + gapToHeader + scrollFrameHeight + FRAME_PADDING ;
local rightAreaWidth = API.Round ( frameWidth - scrollFrameWidth - 2 * FRAME_PADDING ) ;
local descriptionWidth = API.Round ( frameWidth - scrollFrameWidth - 3 * FRAME_PADDING - BUTTON_PADDING_LARGE ) ;
local previewShrink = 1 ;
self.Preview : ClearAllPoints ( ) ;
self.Preview : SetPoint ( " TOP " , self , " TOPRIGHT " , - rightAreaWidth * 0.5 - previewShrink , - ( headerHeight + 2.5 * FRAME_PADDING ) ) ;
local previewWidth = descriptionWidth - 2 * previewShrink ;
local previewHeight = 0.5 * previewWidth ;
self.Preview : SetSize ( previewWidth , 0.5 * previewWidth ) ;
self.previewHeight = previewHeight ;
self.Description : SetWidth ( descriptionWidth ) ;
self.Description : ClearAllPoints ( ) ;
self.Description : SetPoint ( " TOP " , self.Preview , " TOP " , 0 , - 8 ) ;
self : SetSize ( frameWidth , frameHeight ) ;
--self.BackgroundGradient:SetWidth(frameHeight);
self.BackgroundDecor : SetSize ( rightAreaWidth , rightAreaWidth ) ;
self.DecorMask : SetSize ( rightAreaWidth , rightAreaWidth ) ;
self.DecorMask : ClearAllPoints ( ) ;
self.DecorMask : SetPoint ( " BOTTOM " , self.Description , " BOTTOM " , 0 , - 16 ) ;
--Reduce tab button size if necessary
local headerObjectWidth = tabButtonsSpan + minTabButtonWidth + TAB_BUTTON_GAP ;
if INPUT_DEVICE_GAME_PAD then
headerObjectWidth = headerObjectWidth + tabFromOffsetX + 4 * TAB_BUTTON_GAP + minTabButtonWidth ;
end
local headerWidth = frameWidth - 2 * FRAME_PADDING ;
if headerObjectWidth > headerWidth then
if headerObjectWidth * 0.8 < headerWidth then
tabButtonContainer : SetScale ( 0.8 ) ;
else
tabButtonContainer : SetScale ( 0.6 ) ;
end
else
tabButtonContainer : SetScale ( 1 ) ;
end
end
function DUIDialogSettingsMixin : SelectTabByID ( tabID , forceUpdate )
if tabID == self.tabID and not forceUpdate then return false end ;
if self.tabID then --Save Scroll Position
self [ " tabOffset " .. self.tabID ] = self.ScrollFrame : GetScrollOffset ( ) ;
self [ " tab " .. self.tabID .. " gamepadFocusIndex " ] = self.gamepadFocusIndex ;
end
self.tabID = tabID ;
--Update Options
self.optionButtonPool : Release ( ) ;
self.checkboxPool : Release ( ) ;
self.arrowOptionPool : Release ( ) ;
self.texturePool : Release ( ) ;
self.hotkeyFramePool : Release ( ) ;
self : ResetGamePadObjects ( ) ;
--Highlight Button
self.Header . Selection : ClearAllPoints ( ) ;
self.Header . Selection : Hide ( ) ;
for i , button in ipairs ( self.tabButtons ) do
if button.tabID == tabID then
button : SetSelected ( true ) ;
self.Header . Selection : SetPoint ( " TOPLEFT " , button , " TOPLEFT " , 0 , 0 ) ;
self.Header . Selection : SetPoint ( " BOTTOMRIGHT " , button , " BOTTOMRIGHT " , 0 , 0 ) ;
self.Header . Selection : Show ( ) ;
else
button : SetSelected ( false ) ;
end
end
if INPUT_DEVICE_GAME_PAD then
local gap = 4 * TAB_BUTTON_GAP ;
local lb = self.hotkeyFramePool : Acquire ( ) ;
lb : SetKey ( " PADLSHOULDER " ) ;
lb : SetPoint ( " LEFT " , self.Header . Container , " LEFT " , 0 , 0 ) ;
local firstTabButton = self.tabButtons [ 1 ] ;
firstTabButton : ClearAllPoints ( ) ;
firstTabButton : SetPoint ( " LEFT " , lb , " RIGHT " , gap , 0 ) ;
local rb = self.hotkeyFramePool : Acquire ( ) ;
rb : SetKey ( " PADRSHOULDER " ) ;
rb : SetPoint ( " LEFT " , self.tabButtons [ # self.tabButtons ] , " RIGHT " , gap , 0 ) ;
end
local tabData = Schematic [ tabID ] ;
local optionButton ;
local numShownOptions = 0 ;
local isOptionValid ;
local dbKeyToWidget = { } ;
for i , optionData in ipairs ( tabData.options ) do
if optionData.parentKey then
isOptionValid = false ;
local requirement = optionData.requiredParentValue ;
local dbValue = GetDBValue ( optionData.parentKey ) ;
if type ( requirement ) == " table " then
for _ , requiredParentValue in ipairs ( requirement ) do
if dbValue == requiredParentValue then
isOptionValid = true ;
break
end
end
else
if dbValue == optionData.requiredParentValue then
isOptionValid = true ;
end
end
if dbKeyToWidget [ optionData.parentKey ] then
dbKeyToWidget [ optionData.parentKey ] . isParentOption = true ;
end
else
isOptionValid = true ;
end
if isOptionValid and optionData.validationFunc then
isOptionValid = optionData.validationFunc ( ) ;
end
if isOptionValid then
numShownOptions = numShownOptions + 1 ;
optionButton = self.optionButtonPool : Acquire ( ) ;
optionButton.isParentOption = nil ;
optionButton : SetParent ( self.ScrollFrame ) ;
optionButton : SetData ( optionData ) ;
optionButton : SetSize ( OPTIONBUTTON_WIDTH , OPTIONBUTTON_HEIGHT ) ;
optionButton : SetPoint ( " TOPLEFT " , self.ScrollFrame . Reference , " TOPLEFT " , 0 , ( 1 - numShownOptions ) * OPTIONBUTTON_HEIGHT ) ;
if optionData.dbKey then
dbKeyToWidget [ optionData.dbKey ] = optionButton ;
end
end
end
self.ScrollFrame : SetContentHeight ( numShownOptions * OPTIONBUTTON_HEIGHT ) ;
self.ScrollFrame : SetScrollOffset ( self [ " tabOffset " .. self.tabID ] or 0 ) ;
self.dbKeyToWidget = dbKeyToWidget ;
if GAME_PAD_ACTIVE then
self : FocusObjectByIndex ( self [ " tab " .. self.tabID .. " gamepadFocusIndex " ] or 1 ) ;
end
end
function DUIDialogSettingsMixin : SelectTabByDelta ( delta )
local tabID = self.tabID or 0 ;
if delta > 0 and tabID < self.numTabs then
self : SelectTabByID ( tabID + 1 ) ;
elseif delta < 0 and tabID > 1 then
self : SelectTabByID ( tabID - 1 ) ;
end
end
function DUIDialogSettingsMixin : UpdateCurrentTab ( )
self : SelectTabByID ( self.tabID , true )
end
function DUIDialogSettingsMixin : RequestUpdate ( )
if self : IsVisible ( ) then
self : UpdateCurrentTab ( ) ;
end
end
function DUIDialogSettingsMixin : SetFocusedObject ( object )
self.focusedObject = object ;
if object then
local _ ;
_ , self.focusedObjectOffsetY = object : GetCenter ( ) ;
else
self.focusedObjectOffsetY = nil ;
end
end
function DUIDialogSettingsMixin : ReAlignToFocusedObject ( )
--The UI's dimension change with Font Size, so we need maintain the option's offsetY so players don't click another option by accident
if self.focusedObject and self.focusedObject : IsShown ( ) and self.focusedObjectOffsetY then
local _ , newOffsetY = self.focusedObject : GetCenter ( ) ;
local point , relativeTo , relativePoint , offsetX , offsetY = self : GetPoint ( 1 ) ;
self : ClearAllPoints ( ) ;
self : SetPoint ( point , relativeTo , relativePoint , offsetX , offsetY + self.focusedObjectOffsetY - newOffsetY ) ;
self : UpdateScrollFrameBound ( ) ;
end
end
function DUIDialogSettingsMixin : ToggleUI ( )
self : SetShown ( not self : IsShown ( ) ) ;
end
DUIDialogSettingsTabButtonMixin = { } ;
function DUIDialogSettingsTabButtonMixin : OnEnter ( )
MainFrame : HighlightButton ( self ) ;
end
function DUIDialogSettingsTabButtonMixin : OnLeave ( )
MainFrame : HighlightButton ( nil ) ;
end
function DUIDialogSettingsTabButtonMixin : OnMouseDown ( button )
if button ~= " LeftButton " or self.isSelected then return end ;
self.Name : SetPoint ( " CENTER " , 0 , - 1 ) ;
end
function DUIDialogSettingsTabButtonMixin : OnMouseUp ( )
self.Name : SetPoint ( " CENTER " , 0 , 0 ) ;
end
function DUIDialogSettingsTabButtonMixin : OnClick ( )
MainFrame : SelectTabByID ( self.tabID ) ;
end
function DUIDialogSettingsTabButtonMixin : SetName ( name )
self.Name : SetText ( string.upper ( name ) ) ;
end
function DUIDialogSettingsTabButtonMixin : SetSelected ( state )
if state then
self.isSelected = true ;
self.Name : SetFontObject ( " DUIFont_Quest_Quest " ) ;
else
if self.isSelected then
self.isSelected = nil ;
self.Name : SetFontObject ( " DUIFont_Quest_Gossip " ) ;
end
end
end
DUIDialogSettingsOptionMixin = { } ;
function DUIDialogSettingsOptionMixin : OnEnter ( )
local choiceTooltip ;
if not self.isSubheader then
MainFrame : HighlightButton ( self ) ;
MainFrame : SetGamePadFocus ( self ) ;
if self.widget then
choiceTooltip = self.widget : GetSelectedChoiceTooltip ( ) ;
end
end
MainFrame : DisplayOptionInfo ( self.optionData , choiceTooltip ) ;
end
function DUIDialogSettingsOptionMixin : OnLeave ( )
if not self : IsMouseOver ( ) then
MainFrame : HighlightButton ( nil ) ;
end
end
function DUIDialogSettingsOptionMixin : OnClick ( button )
MainFrame : SetFocusedObject ( self ) ;
if self.widget and self.widget . OnClick and self.widget : IsEnabled ( ) then
self.widget : OnClick ( button ) ;
elseif self.optionData . onClickFunc then
self.optionData . onClickFunc ( self ) ;
end
MainFrame : HighlightButton ( nil ) ;
self : OnEnter ( ) ;
end
function DUIDialogSettingsOptionMixin : SetCheckbox ( optionData )
self.widget = MainFrame.checkboxPool : Acquire ( ) ;
self.widget : SetParent ( self ) ;
self.widget : SetPoint ( " RIGHT " , self , " RIGHT " , - BUTTON_PADDING_LARGE , 0 ) ;
self.widget : SetWidgetHeight ( OPTION_WIDGET_SIZE ) ;
self.widget : SetChecked ( GetDBValue ( self.dbKey ) == true ) ;
end
function DUIDialogSettingsOptionMixin : SetArrowOption ( optionData )
self.widget = MainFrame.arrowOptionPool : Acquire ( ) ;
self.widget : SetParent ( self ) ;
self.widget : SetPoint ( " RIGHT " , self , " RIGHT " , - BUTTON_PADDING_LARGE , 0 ) ;
self.widget : SetWidgetHeight ( OPTION_WIDGET_SIZE ) ;
self.widget : SetData ( optionData ) ;
end
function DUIDialogSettingsOptionMixin : SetCustomButton ( optionData )
self.widget = nil ;
end
function DUIDialogSettingsOptionMixin : SetSubheader ( )
--[[
local icon = MainFrame.texturePool : Acquire ( ) ;
icon : SetSize ( FONT_HEIGHT_NORMAL , FONT_HEIGHT_NORMAL ) ;
icon : SetTexture ( FILE_PATH .. " Settings-SubheaderIcon.png " ) ;
icon : SetVertexColor ( 0.50 , 0.36 , 0.24 ) ;
icon : SetPoint ( " LEFT " , self , " LEFT " , 4 , 0 ) ;
icon : SetParent ( self ) ;
--]]
end
function DUIDialogSettingsOptionMixin : SetData ( optionData )
self.optionData = optionData ;
self.dbKey = optionData.dbKey ;
self.updateTabAfterClicks = optionData.updateTabAfterClicks ;
local isSubheader ;
if optionData.type == " Subheader " then
isSubheader = true ;
self : SetSubheader ( ) ;
elseif optionData.type == " Checkbox " then
self : SetCheckbox ( optionData ) ;
elseif optionData.type == " ArrowOption " then
self : SetArrowOption ( optionData ) ;
elseif optionData.type == " Custom " then
self : SetCustomButton ( optionData ) ;
end
self.widgetType = optionData.type ;
if isSubheader then
self.Label : SetText ( string.upper ( optionData.name ) ) ;
if not self.isSubheader then
self.Label : SetFontObject ( " DUIFont_Settings_Disabled " ) ;
end
else
self.Label : SetText ( optionData.name ) ;
if self.isSubheader then
self.Label : SetFontObject ( " DUIFont_Quest_Paragraph " ) ;
end
MainFrame : IndexGamePadObject ( self ) ;
end
self.isSubheader = isSubheader ;
local nameOffset ;
if optionData.parentKey then
nameOffset = OPTIONBUTTON_LABEL_OFFSET + 24 ;
local branch = MainFrame.texturePool : Acquire ( ) ;
branch : SetSize ( OPTIONBUTTON_HEIGHT * 0.5 , OPTIONBUTTON_HEIGHT * 0.5 ) ;
branch : SetTexture ( ThemeUtil : GetTextureFile ( " Settings-SubOptionIcon.png " ) ) ;
branch : SetVertexColor ( 1 , 1 , 1 , 0.5 ) ;
branch : SetPoint ( " BOTTOM " , self , " LEFT " , OPTIONBUTTON_LABEL_OFFSET + 2 , 0 ) ;
branch : SetParent ( self ) ;
else
nameOffset = OPTIONBUTTON_LABEL_OFFSET ;
end
if optionData.icon then
local icon = MainFrame.texturePool : Acquire ( ) ;
local iconSize = OPTION_WIDGET_SIZE ;
local iconOffset = - 0.125 * iconSize ;
icon : SetSize ( iconSize , iconSize ) ;
icon : SetTexture ( ThemeUtil : GetTextureFile ( optionData.icon ) ) ;
icon : SetVertexColor ( 1 , 1 , 1 , 1 ) ;
icon : SetPoint ( " LEFT " , self , " LEFT " , nameOffset + iconOffset , 0 ) ;
icon : SetParent ( self ) ;
nameOffset = nameOffset + iconSize ;
end
self.Label : ClearAllPoints ( ) ;
self.Label : SetPoint ( " LEFT " , self , " LEFT " , nameOffset , 0 ) ;
end
DUIDialogSettingsArrowOptionMixin = { } ;
local function ArrowButton_OnClick ( self )
self : GetParent ( ) : SelectChoiceByDelta ( self.delta ) ;
end
local function ArrowButton_OnEnter ( self )
self : GetParent ( ) : GetParent ( ) : OnEnter ( ) ;
end
local function ArrowButton_OnLeave ( self )
self : GetParent ( ) : GetParent ( ) : OnLeave ( ) ;
end
local function ArrowButton_OnMouseDown ( self )
if not self : IsEnabled ( ) then return end ;
if self.delta < 0 then
self.Texture : SetPoint ( " CENTER " , - 1 , 0 ) ;
else
self.Texture : SetPoint ( " CENTER " , 1 , 0 ) ;
end
end
local function ArrowButton_OnMouseUp ( self )
self.Texture : SetPoint ( " CENTER " , 0 , 0 ) ;
end
local function ArrowButton_OnEnable ( self )
self : SetAlpha ( 1 ) ;
end
local function ArrowButton_OnDisable ( self )
self : SetAlpha ( DISABLED_TEXTURE_ALPHA ) ;
end
local function RemoveBar ( bar )
bar : Hide ( ) ;
bar : ClearAllPoints ( ) ;
end
local function OnAcquireBar ( bar )
bar : SetTexture ( ThemeUtil : GetTextureFile ( " Settings-ArrowOption.png " ) ) ;
end
function DUIDialogSettingsArrowOptionMixin : OnLoad ( )
self.ValueText : SetPoint ( " TOP " , self , " TOP " , 0 , ARROWOPTION_VALUETEXT_OFFSET_Y ) ;
self.LeftArrow . delta = - 1 ;
self.LeftArrow : SetScript ( " OnEnter " , ArrowButton_OnEnter ) ;
self.LeftArrow : SetScript ( " OnLeave " , ArrowButton_OnLeave ) ;
self.LeftArrow : SetScript ( " OnClick " , ArrowButton_OnClick ) ;
self.LeftArrow : SetScript ( " OnMouseDown " , ArrowButton_OnMouseDown ) ;
self.LeftArrow : SetScript ( " OnMouseUp " , ArrowButton_OnMouseUp ) ;
self.LeftArrow : SetScript ( " OnEnable " , ArrowButton_OnEnable ) ;
self.LeftArrow : SetScript ( " OnDisable " , ArrowButton_OnDisable ) ;
self.RightArrow . delta = 1 ;
self.RightArrow : SetScript ( " OnEnter " , ArrowButton_OnEnter ) ;
self.RightArrow : SetScript ( " OnLeave " , ArrowButton_OnLeave ) ;
self.RightArrow : SetScript ( " OnClick " , ArrowButton_OnClick ) ;
self.RightArrow : SetScript ( " OnMouseDown " , ArrowButton_OnMouseDown ) ;
self.RightArrow : SetScript ( " OnMouseUp " , ArrowButton_OnMouseUp ) ;
self.RightArrow : SetScript ( " OnEnable " , ArrowButton_OnEnable ) ;
self.RightArrow : SetScript ( " OnDisable " , ArrowButton_OnDisable ) ;
local function CreateBar ( )
local bar = self : CreateTexture ( nil , " OVERLAY " ) ;
bar : SetTextureSliceMargins ( 1 , 1 , 1 , 1 ) ;
bar : SetTextureSliceMode ( 1 ) ;
bar : SetTexCoord ( 0 , 16 / 128 , 124 / 128 , 1 ) ;
return bar
end
self.barPool = API.CreateObjectPool ( CreateBar , RemoveBar , OnAcquireBar ) ;
end
function DUIDialogSettingsArrowOptionMixin : SetNumChoices ( numChoices , forceUpdate )
if numChoices ~= self.numChoices or forceUpdate then
self.barPool : Release ( ) ;
self.numChoices = numChoices ;
self.bars = { } ;
local barHeight = API.GetPixelForWidget ( self , ARROWOTPION_BAR_HEIGHT ) ;
local gap = API.GetPixelForWidget ( self , 4 ) ;
local buttonWidth = self.LeftArrow : GetWidth ( ) ;
local barShrink = 4 ;
local fromOffsetX = buttonWidth + barShrink ;
local barWidth = ( self : GetWidth ( ) - 2 * barShrink - 2 * buttonWidth - ( numChoices - 1 ) * gap ) / numChoices ;
local bar ;
for i = 1 , numChoices do
bar = self.barPool : Acquire ( ) ;
bar : SetSize ( barWidth , barHeight ) ;
bar : SetPoint ( " BOTTOMLEFT " , self , " BOTTOMLEFT " , fromOffsetX + ( gap + barWidth ) * ( i - 1 ) , 2 ) ;
self.bars [ i ] = bar ;
end
end
end
function DUIDialogSettingsArrowOptionMixin : GetCentralWidth ( )
return self : GetWidth ( ) - 2 * self.LeftArrow : GetWidth ( ) ;
end
function DUIDialogSettingsArrowOptionMixin : SetWidgetWidth ( width )
local centralWidth = self : GetCentralWidth ( ) ;
end
function DUIDialogSettingsArrowOptionMixin : SetWidgetHeight ( height )
self.LeftArrow . Texture : SetSize ( height , height ) ;
self.RightArrow . Texture : SetSize ( height , height ) ;
self : SetHeight ( height ) ;
self : SetWidth ( height * ARROWOTPION_WIDTH_RATIO ) ;
end
function DUIDialogSettingsArrowOptionMixin : SetValueTextByID ( id )
if self.valueTextFormatter then
self.valueTextFormatter ( self , self.choices [ id ] . dbValue ) ;
else
local valueText = self.choices [ id ] . valueText ;
self.ValueText : SetText ( valueText ) ;
end
end
function DUIDialogSettingsArrowOptionMixin : SelectChoiceByID ( id )
if not self.choices [ id ] then
id = 1 ;
end
local choiceData = self.choices [ id ] ;
if choiceData then
self : SetValueTextByID ( id ) ;
end
self.selectedID = id ;
for i , bar in ipairs ( self.bars ) do
if i == id then
bar : SetAlpha ( 1 ) ;
else
bar : SetAlpha ( DISABLED_TEXTURE_ALPHA ) ;
end
end
self.LeftArrow : SetEnabled ( id ~= 1 ) ;
self.RightArrow : SetEnabled ( id ~= self.numChoices ) ;
end
function DUIDialogSettingsArrowOptionMixin : SelectNextChoice ( )
if ARROWOTPION_CYCLING then
self.selectedID = self.selectedID + 1 ;
if self.selectedID > self.numChoices then
self.selectedID = 1 ;
end
else
if self.selectedID < self.numChoices then
self.selectedID = self.selectedID + 1 ;
else
return false
end
end
self : SelectChoiceByID ( self.selectedID ) ;
return true
end
function DUIDialogSettingsArrowOptionMixin : SelectPreviousChoice ( )
if ARROWOTPION_CYCLING then
self.selectedID = self.selectedID - 1 ;
if self.selectedID < 1 then
self.selectedID = self.numChoices ;
end
else
if self.selectedID > 1 then
self.selectedID = self.selectedID - 1 ;
else
return false
end
end
self : SelectChoiceByID ( self.selectedID ) ;
return true
end
function DUIDialogSettingsArrowOptionMixin : SelectChoiceByDelta ( delta )
--right = 1, left = -1
local anyChange ;
if delta > 0 then
anyChange = self : SelectNextChoice ( ) ;
else
anyChange = self : SelectPreviousChoice ( ) ;
end
if anyChange then
self : PostClick ( ) ;
end
end
function DUIDialogSettingsArrowOptionMixin : PostClick ( )
local optionButton = self : GetParent ( ) ;
MainFrame : SetFocusedObject ( optionButton ) ;
local value = self.choices [ self.selectedID ] . dbValue ;
SetDBValue ( optionButton.dbKey , value ) ;
if optionButton.isParentOption or optionButton.updateTabAfterClicks then
MainFrame : UpdateCurrentTab ( ) ;
end
if self.realignAfterClicks then
MainFrame : ReAlignToFocusedObject ( ) ;
end
self : GetParent ( ) : OnEnter ( ) ;
end
function DUIDialogSettingsArrowOptionMixin : SetData ( optionData )
self.choices = optionData.choices ;
self.dbKey = optionData.dbKey ;
self.valueTextFormatter = optionData.valueTextFormatter ;
self.realignAfterClicks = optionData.realignAfterClicks ;
self : SetNumChoices ( # self.choices ) ;
if not optionData.hasHotkey then
self.ValueText : ClearAllPoints ( ) ;
self.ValueText : SetPoint ( " TOP " , self , " TOP " , 0 , ARROWOPTION_VALUETEXT_OFFSET_Y ) ;
end
local selectedID = 1 ;
local dbValue = GetDBValue ( self.dbKey ) ;
for id , choiceData in ipairs ( self.choices ) do
if dbValue == choiceData.dbValue then
selectedID = id ;
break
end
end
self : SelectChoiceByID ( selectedID ) ;
end
function DUIDialogSettingsArrowOptionMixin : SetTexture ( file )
self.LeftArrow . Texture : SetTexture ( file ) ;
self.LeftArrow . Highlight : SetTexture ( file ) ;
self.RightArrow . Texture : SetTexture ( file ) ;
self.RightArrow . Highlight : SetTexture ( file ) ;
end
function DUIDialogSettingsArrowOptionMixin : GetSelectedChoiceTooltip ( )
if self.selectedID and self.choices and self.choices [ self.selectedID ] then
local tooltip = self.choices [ self.selectedID ] . tooltip ;
if type ( tooltip ) == " function " then
return tooltip ( )
else
return tooltip
end
end
end
DUIDialogSettingsCheckboxMixin = { } ;
function DUIDialogSettingsCheckboxMixin : OnEnter ( )
self : GetParent ( ) : OnEnter ( ) ;
end
function DUIDialogSettingsCheckboxMixin : OnLeave ( )
self : GetParent ( ) : OnLeave ( ) ;
end
function DUIDialogSettingsCheckboxMixin : SetTexture ( file )
self.Background : SetTexture ( file ) ;
self.Check : SetTexture ( file ) ;
end
function DUIDialogSettingsCheckboxMixin : OnClick ( )
self : Toggle ( ) ;
local optionButton = self : GetParent ( ) ;
SetDBValue ( optionButton.dbKey , self.checked ) ;
if optionButton.isParentOption or optionButton.updateTabAfterClicks then
MainFrame : UpdateCurrentTab ( ) ;
end
self : OnEnter ( ) ;
end
function DUIDialogSettingsCheckboxMixin : SetChecked ( state )
self.checked = state ;
self.Check : SetShown ( state ) ;
if state then
self.Background : SetTexCoord ( 0.5 , 1 , 0 , 0.5 ) ;
else
self.Background : SetTexCoord ( 0 , 0.5 , 0 , 0.5 ) ;
end
end
function DUIDialogSettingsCheckboxMixin : GetChecked ( )
return self.checked == true
end
function DUIDialogSettingsCheckboxMixin : Toggle ( )
self.checked = not self.checked ;
self : SetChecked ( self.checked ) ;
end
function DUIDialogSettingsCheckboxMixin : SetWidgetHeight ( height )
self : SetSize ( height , height ) ;
self.Check : SetSize ( height * 0.5 , height * 0.5 ) ;
end
function DUIDialogSettingsCheckboxMixin : GetSelectedChoiceTooltip ( )
local optionButton = self : GetParent ( ) ;
local tooltip = optionButton.optionData and optionButton.optionData . tooltip ;
if tooltip then
if type ( tooltip ) == " function " then
return tooltip ( self.checked )
else
return tooltip
end
end
end
do --GamePad/Controller
function DUIDialogSettingsMixin : ResetGamePadObjects ( )
self.gamepadMaxIndex = 0 ;
self.gamepadFocusIndex = nil ;
self.gamepadFocus = nil ;
self.gamepadObjects = { } ;
end
function DUIDialogSettingsMixin : IndexGamePadObject ( object )
self.gamepadMaxIndex = self.gamepadMaxIndex + 1 ;
self.gamepadObjects [ self.gamepadMaxIndex ] = object ;
object.gamepadIndex = self.gamepadMaxIndex ;
end
function DUIDialogSettingsMixin : ClearGamePadFocus ( )
if self.gamepadFocus then
--self.gamepadFocus:OnLeave();
self.gamepadFocus = nil ;
end
end
function DUIDialogSettingsMixin : SetGamePadFocus ( optionButton )
self.gamepadFocusIndex = optionButton.gamepadIndex ;
self.gamepadFocus = optionButton ;
end
function DUIDialogSettingsMixin : FocusObjectByIndex ( index )
local object = self.gamepadObjects [ index ] ;
if object then
self.gamepadFocusIndex = index ;
self.gamepadFocus = object ;
self.gamepadFocus : OnEnter ( ) ;
return true
end
end
function DUIDialogSettingsMixin : FocusObjectByDelta ( delta )
local maxIndex = self.gamepadMaxIndex or 0 ;
local index = self.gamepadFocusIndex ;
if not index then
index = 0 ;
end
if delta < 0 and index < maxIndex then
index = index + 1 ;
elseif delta > 0 and index > 1 then
index = index - 1 ;
elseif index == 0 then
index = 1 ;
else
return
end
self : ClearGamePadFocus ( ) ;
if self : FocusObjectByIndex ( index ) then
local threshold = 2 * OPTIONBUTTON_HEIGHT ;
if delta > 0 then
local top = self.gamepadFocus : GetTop ( ) ;
if top + threshold >= self.scrollFrameTop then
self.ScrollFrame : ScrollBy ( - OPTIONBUTTON_HEIGHT ) ;
end
else
local bottom = self.gamepadFocus : GetBottom ( ) ;
if bottom - threshold <= self.scrollFrameBottom then
self.ScrollFrame : ScrollBy ( OPTIONBUTTON_HEIGHT ) ;
end
end
return true
end
end
function DUIDialogSettingsMixin : FocusNextObject ( )
if self : FocusObjectByDelta ( 1 ) then
return
end
end
function DUIDialogSettingsMixin : FocusPreviousObject ( )
if self : FocusObjectByDelta ( - 1 ) then
return
end
end
function DUIDialogSettingsMixin : ClickFocusedObject ( gamepadButton )
if self.gamepadFocus then
local optionButton = self.gamepadFocus ;
if gamepadButton == " PAD1 " then
optionButton : OnClick ( ) ;
elseif gamepadButton == " PADDLEFT " then
if optionButton.widgetType == " ArrowOption " then
optionButton.widget : SelectChoiceByDelta ( - 1 ) ;
end
elseif gamepadButton == " PADDRIGHT " then
if optionButton.widgetType == " ArrowOption " then
optionButton.widget : SelectChoiceByDelta ( 1 ) ;
end
end
return true
end
return false
end
end
function DialogueUI_ShowSettingsFrame ( )
MainFrame : ToggleUI ( ) ;
end
function DialogueUI_AddonCompartmentOnEnterLeave ( addonName , button )
end
do
local function OnFontSizeChanged ( baseFontSize , fontSizeID )
FONT_HEIGHT_LARGE = baseFontSize ;
FONT_HEIGHT_NORMAL = baseFontSize ;
BUTTON_PADDING_LARGE = FONT_HEIGHT_NORMAL ;
OPTIONBUTTON_HEIGHT = 3 * FONT_HEIGHT_NORMAL ;
OPTION_WIDGET_SIZE = 2 * FONT_HEIGHT_NORMAL ;
local widthMultiplier ;
if fontSizeID <= 1 then
NUM_VISIBLE_OPTIONS = 10.5 ;
widthMultiplier = 12 ;
ARROWOTPION_WIDTH_RATIO = 7 ;
ARROWOTPION_BAR_HEIGHT = 5 ;
elseif fontSizeID == 2 then
NUM_VISIBLE_OPTIONS = 9.5 ;
widthMultiplier = 11 ;
ARROWOTPION_WIDTH_RATIO = 7 ;
ARROWOTPION_BAR_HEIGHT = 6 ;
elseif fontSizeID == 3 then
NUM_VISIBLE_OPTIONS = 8.5 ;
widthMultiplier = 10 ;
ARROWOTPION_WIDTH_RATIO = 6 ;
ARROWOTPION_BAR_HEIGHT = 6 ;
else
NUM_VISIBLE_OPTIONS = 8.5 ;
widthMultiplier = 10 ;
ARROWOTPION_WIDTH_RATIO = 6 ;
ARROWOTPION_BAR_HEIGHT = 6 ;
end
OPTIONBUTTON_WIDTH = widthMultiplier * OPTIONBUTTON_HEIGHT ;
end
addon.CallbackRegistry : Register ( " FontSizeChanged " , OnFontSizeChanged ) ;
local function PostFontSizeChanged ( )
--We wait after hotkey frame size update
local f = MainFrame ;
if f.Init then return end ;
if f.arrowOptionPool then
local function ModifyArrowOption ( widget )
widget : SetWidgetHeight ( OPTION_WIDGET_SIZE ) ;
widget.numChoices = 0 ;
end
f.arrowOptionPool : ProcessAllObjects ( ModifyArrowOption ) ;
end
if f.hotkeyFramePool then
local method = " UpdateBaseHeight " ;
f.hotkeyFramePool : CallAllObjects ( method ) ;
end
f : Layout ( ) ;
f : UpdateCurrentTab ( ) ;
end
addon.CallbackRegistry : Register ( " PostFontSizeChanged " , PostFontSizeChanged ) ;
local function PostInputDeviceChanged ( dbValue )
INPUT_DEVICE_GAME_PAD = dbValue ~= 1 ;
INPUT_DEVICE_ID = dbValue ;
local f = MainFrame ;
if f.Init then return end ;
f : Layout ( ) ;
f : UpdateCurrentTab ( ) ;
end
addon.CallbackRegistry : Register ( " PostInputDeviceChanged " , PostInputDeviceChanged ) ;
end