Torque3D/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript
Sir-Skurpsalot 6526e87724
Update optionsMenu.tscript
Fixed re-mappable binds with "mouse" as the device not showing up in the menu.
2025-12-09 18:35:43 -07:00

1145 lines
36 KiB
Plaintext

$reportKeymapping = false;
$optionsEntryPad = 10;
$OptionsMenuCategories[0] = "Video";
$OptionsMenuCategories[1] = "Audio";
$OptionsMenuCategories[2] = "KBM";
$OptionsMenuCategories[3] = "Controller";
function OptionsMenu::onAdd(%this)
{
if(!isObject(%this.optionsCategories))
{
%this.optionsCategories = new ArrayObject();
}
%this.currentCategory = "";
callOnModules("populateOptionsMenuCategories", "Game");
}
function OptionsMenu::onWake(%this)
{
%this.optsListCount = -1;
$optionsChangeRequiresRestart = false;
%this.populateVideoSettings();
%this.populateAudioSettings();
%this.populateKBMControls();
%this.populateGamepadControls();
//establish the cached prefs values here
%this.openOptionsCategory("Video");
}
if(!isObject( OptionsMenuActionMap ) )
{
new ActionMap(OptionsMenuActionMap){};
OptionsMenuActionMap.bind( keyboard, Escape, tryCloseOptionsMenu);
OptionsMenuActionMap.bind( gamepad, btn_b, tryCloseOptionsMenu);
OptionsMenuActionMap.bind( keyboard, w, OptionMenuNavigatePrev );
OptionsMenuActionMap.bind( keyboard, s, OptionMenuNavigateNext );
OptionsMenuActionMap.bind( gamepad, yaxis, "D", "-0.23 0.23", OptionMenuStickNavigate );
OptionsMenuActionMap.bind( gamepad, upov, OptionMenuNavigatePrev );
OptionsMenuActionMap.bind( gamepad, dpov, OptionMenuNavigateNext );
OptionsMenuActionMap.bind( keyboard, a, OptionMenuPrevSetting );
OptionsMenuActionMap.bind( keyboard, d, OptionMenuNextSetting );
OptionsMenuActionMap.bind( gamepad, xaxis, "D", "-0.23 0.23", OptionMenuStickChangeSetting );
OptionsMenuActionMap.bind( gamepad, lpov, OptionMenuPrevSetting );
OptionsMenuActionMap.bind( gamepad, rpov, OptionMenuNextSetting );
OptionsMenuActionMap.bind( keyboard, q, OptionsMenuPrevCategory );
OptionsMenuActionMap.bind( gamepad, btn_l, OptionsMenuPrevCategory );
OptionsMenuActionMap.bind( keyboard, e, OptionsMenuNextCategory );
OptionsMenuActionMap.bind( gamepad, btn_r, OptionsMenuNextCategory );
OptionsMenuActionMap.bind( keyboard, R, OptionsMenuReset );
OptionsMenuActionMap.bind( gamepad, btn_x, OptionsMenuReset );
OptionsMenuActionMap.bind( keyboard, Space, OptionsMenuActivateOption );
OptionsMenuActionMap.bind( gamepad, btn_a, OptionsMenuActivateOption );
OptionsMenuActionMap.bind( keyboard, Enter, tryApplyOptions);
OptionsMenuActionMap.bind( gamepad, btn_start, tryApplyOptions);
}
//==============================================================================
// This function updates all the elements in the actual lists to ensure they're
// sized, stylized and formatted correctly, as well as up to date values
function OptionsMenuList::syncGui(%this)
{
%this.callOnChildren("setHighlighted", false);
%btn = %this.getObject(%this.listPosition);
if(%btn.class $= "OptionsListEntry" ||
%btn.class $= "OptionsListSliderEntry" ||
%btn.class $= "OptionsKeybindEntry")
%btn-->button.setHighlighted(true);
//iterate over the items and ensure that they are formatted well based on the settings selected
foreach(%option in %this)
{
%container = %option-->valuesContainer;
if(%option.class $= "OptionsListEntry")
{
%hasLevels = %option.optionsObject.getCount() <= 1;
%optionObject = %option.optionsObject;
//If it's out of range of the options, it's probably a custom value
if(%option.currentOptionIndex < %optionObject.getCount() && %option.currentOptionIndex >= 0)
{
%currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
%currentOptionLevelTxt = %currentOptionLevel.displayName;
}
else
{
%currentOptionLevelTxt = "Custom";
}
%optionValTextWidth = %option-->optionValue.profile.getStringWidth(%currentOptionLevelTxt);
%option-->optionValue.resize(%container.extent.x - %container-->prevValButton.extent.x - %optionValTextWidth - 20, 0,
%optionValTextWidth + 20, %container.extent.y);
%option-->optionValue.text = %currentOptionLevelTxt;
%container-->prevValButton.position.x = %option-->optionValue.position.x - 20;
%container-->nextValButton.position.x = %container.extent.x - %container-->prevValButton.extent.x;
//if there's no alternatives, disable the left/right buttons
%container-->prevValButton.setHidden(%hasLevels);
%container-->nextValButton.setHidden(%hasLevels);
}
else if(%option.class $= "OptionsListSliderEntry")
{
}
else if(%option.class $= "OptionsKeybindEntry")
{
if(getWordCount(getField(%option.keymap, 1)) == 2)
{
%keymap = getField(%option.keymap, 1);
%modifierImgAsset = getButtonBitmap(%option.device, getWord(%keymap, 0));
if(%modifierImgAsset $= "UI:Keyboard_Black_Blank_image")
%modifierImgAsset = "";
%container-->modifierButton.setBitmap(%modifierImgAsset);
//
%bindImgAsset = getButtonBitmap(%option.device, getWord(%keymap, 1));
if(%bindImgAsset $= "UI:Keyboard_Black_Blank_image")
%bindImgAsset = "";
%container-->bindButton.setBitmap(%bindImgAsset);
}
else
{
%bindImgAsset = getButtonBitmap(%option.device, getField(%option.keymap, 1));
if(%bindImgAsset $= "UI:Keyboard_Black_Blank_image")
%bindImgAsset = "";
%container-->bindButton.setBitmap(%bindImgAsset);
}
}
}
}
function OptionsMenuList::checkForUnappliedChanges(%this)
{
%unappliedChanges = false;
foreach(%option in %this)
{
if(%option.class $= "OptionsListEntry")
{
if(%option.currentOptionIndex >= 0 && %option.currentOptionIndex < %option.optionsObject.getCount())
{
%targetOptionLevel = %option.optionsObject.getObject(%option.currentOptionIndex);
if(!%targetOptionLevel.isCurrent())
%unappliedChanges = true;
if(%unappliedChanges && %option.optionsObject.requiresRestart)
$optionsChangeRequiresRestart = true;
}
}
}
return %unappliedChanges;
}
function OptionsMenuList::applyChanges(%this)
{
foreach(%option in %this)
{
if(%option.class $= "OptionsListEntry")
{
//If it's custom or nonsensical index, there's some kind of external factor going on, so we're
//just going to skip applying it because we don't know what we'd be applying
if(%option.currentOptionIndex >= 0 && %option.currentOptionIndex < %option.optionsObject.getCount())
{
%targetOptionLevel = %option.optionsObject.getObject(%option.currentOptionIndex);
if(!%targetOptionLevel.isCurrent())
%targetOptionLevel.apply();
}
}
}
}
function OptionsMenu::openOptionsCategory(%this, %categoryName)
{
VideoSettingsList.setVisible(%categoryName $= "Video");
AudioSettingsList.setVisible(%categoryName $= "Audio");
KBMControlsList.setVisible(%categoryName $= "KBM");
GamepadControlsList.setVisible(%categoryName $= "Controller");
if(%categoryName $= "Video")
{
$MenuList = VideoSettingsList;
//Find our first non-group entry
while($MenuList.getObject($MenuList.listPosition).class !$= OptionsListEntry && $MenuList.listPosition < $MenuList.getCount())
{
$MenuList.listPosition += 1;
}
%this.currentCatgeoryIdx = 0;
}
else if(%categoryName $= "Audio")
{
$MenuList = AudioSettingsList;
%this.currentCatgeoryIdx = 1;
}
else if(%categoryName $= "KBM")
{
$MenuList = KBMControlsList;
%this.currentCatgeoryIdx = 2;
}
else if(%categoryName $= "Controller")
{
$MenuList = GamepadControlsList;
%this.currentCatgeoryIdx = 3;
}
$MenuList.syncGui();
%this.syncGui();
}
//==============================================================================
// This function updates the non-list items of the menu to be up to date and stylistically
// complaint. This ensures keybind hint buttons are presented correctly based on the current input
// device
function OptionsMenu::syncGui(%this)
{
OptionsMenuCategoryList.callOnChildren("setHighlighted", false);
%btn = OptionsMenuCategoryList.getObject(%this.currentCatgeoryIdx);
%btn.setHighlighted(true);
%buttonPosX = %btn.position.x + OptionsMenuCategoryList.position.x;
OptionsMenuPrevNavIcon.position.x = %buttonPosX - 5;
OptionsMenuNextNavIcon.position.x = %buttonPosX + %btn.extent.x - 35;
//Update the button imagery to comply to the last input device we'd used
%device = Canvas.getLastInputDevice();
if(%device $= "mouse")
%device = "keyboard";
OptionsMenuBackBtn.setBitmap(BaseUIActionMap.getCommandButtonBitmap(%device, "BaseUIBackOut"));
OptionsMenuResetBtn.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuReset"));
OptionsMenuPrevNavIcon.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuPrevCategory"));
OptionsMenuNextNavIcon.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuNextCategory"));
OptionsMenuApplyBtn.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "tryApplyOptions"));
OptionsMenuRemapBtn.visible = KBMControlsList.visible || GamepadControlsList.visible;
OptionsMenuRemapBtn.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuActivateOption"));
}
//==============================================================================
// Menu navigation functions
// Primarily used by keybinds
function OptionsMenuPrevCategory(%val)
{
if(%val)
{
%currentIdx = OptionsMenu.currentMenuIdx;
OptionsMenu.currentMenuIdx -= 1;
OptionsMenu.currentMenuIdx = mClamp(OptionsMenu.currentMenuIdx, 0, 3);
if(%currentIdx == OptionsMenu.currentMenuIdx)
return;
%newCategory = $OptionsMenuCategories[OptionsMenu.currentMenuIdx];
OptionsMenu.openOptionsCategory(%newCategory);
}
}
function OptionsMenuNextCategory(%val)
{
if(%val)
{
%currentIdx = OptionsMenu.currentMenuIdx;
OptionsMenu.currentMenuIdx += 1;
OptionsMenu.currentMenuIdx = mClamp(OptionsMenu.currentMenuIdx, 0, 3);
if(%currentIdx == OptionsMenu.currentMenuIdx)
return;
%newCategory = $OptionsMenuCategories[OptionsMenu.currentMenuIdx];
OptionsMenu.openOptionsCategory(%newCategory);
}
}
function OptionMenuNavigatePrev(%val)
{
if(%val)
{
$MenuList.listPosition -= 1;
while( $MenuList.listPosition >= 0 && ($MenuList.getObject($MenuList.listPosition).class !$= "OptionsListEntry" &&
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsListSliderEntry" &&
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsKeybindEntry"))
{
$MenuList.listPosition -= 1;
}
if($MenuList.listPosition < 0)
$MenuList.listPosition = 0;
$MenuList.syncGUI();
$BaseUI::scrollSchedule = schedule($BaseUI::scrollSpeedTimeMs, 0, "OptionMenuNavigatePrev", 1);
}
else
{
cancel($BaseUI::scrollSchedule);
}
}
function OptionMenuNavigateNext(%val)
{
if(%val)
{
$MenuList.listPosition += 1;
while($MenuList.listPosition < $MenuList.getCount() && ($MenuList.getObject($MenuList.listPosition).class !$= "OptionsListEntry" &&
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsListSliderEntry" &&
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsKeybindEntry"))
{
$MenuList.listPosition += 1;
}
if($MenuList.listPosition >= $MenuList.getCount())
$MenuList.listPosition = $MenuList.getCount()-1;
$MenuList.syncGUI();
$BaseUI::scrollSchedule = schedule($BaseUI::scrollSpeedTimeMs, 0, "OptionMenuNavigateNext", 1);
}
else
{
cancel($BaseUI::scrollSchedule);
}
}
function OptionMenuStickNavigate(%val)
{
if(%val == 1)
OptionMenuNavigateNext(1);
else if(%val == -1)
OptionMenuNavigatePrev(1);
else
cancel($BaseUI::scrollSchedule);
}
function OptionMenuPrevSetting(%val)
{
if(!%val)
return;
%option = $MenuList.getObject($MenuList.listPosition);
if(!isObject(%option))
return;
if(%option.class $= "OptionsListEntry")
{
%optionObject = %option.optionsObject;
%currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
%option.currentOptionIndex = mClamp(%option.currentOptionIndex-1, 0, %optionObject.getCount()-1);
%newOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
//echo("Changed option: " @ %optionObject.optionName @ " from level: " @ %currentOptionLevel.displayName @ " to level: " @ %newOptionLevel.displayName);
}
else if(%option.class $= "OptionsListSliderEntry")
{
%sliderCtrl = %option-->valuesContainer-->slider;
%minValue = %sliderCtrl.range.x;
%maxValue = %sliderCtrl.range.y;
%ticks = %sliderCtrl.ticks;
%tickIncrementVal = (%maxValue - %minValue) / %ticks;
%sliderCtrl.value -= %tickIncrementVal;
}
$MenuList.syncGUI();
}
function OptionMenuNextSetting(%val)
{
if(!%val)
return;
%option = $MenuList.getObject($MenuList.listPosition);
if(!isObject(%option) )
return;
if(%option.class $= "OptionsListEntry")
{
%optionObject = %option.optionsObject;
%currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
%option.currentOptionIndex = mClamp(%option.currentOptionIndex+1, 0, %optionObject.getCount()-1);
%newOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
//echo("Changed option: " @ %optionObject.optionName @ " from level: " @ %currentOptionLevel.displayName @ " to level: " @ %newOptionLevel.displayName);
}
else if(%option.class $= "OptionsListSliderEntry")
{
%sliderCtrl = %option-->valuesContainer-->slider;
%minValue = %sliderCtrl.range.x;
%maxValue = %sliderCtrl.range.y;
%ticks = %sliderCtrl.ticks;
%tickIncrementVal = (%maxValue - %minValue) / %ticks;
%sliderCtrl.value += %tickIncrementVal;
}
$MenuList.syncGUI();
}
function OptionMenuStickChangeSetting(%val)
{
if(%val == 1)
OptionMenuNextSetting(1);
else if(%val == -1)
OptionMenuPrevSetting(1);
}
function OptionsMenuActivateOption(%val)
{
if(!%val)
return;
%option = $MenuList.getObject($MenuList.listPosition);
if(!isObject(%option))
return;
if(%option.class $= "OptionsKeybindEntry")
{
%option-->button.execAltCommand();
}
}
//==============================================================================
// This function utilizes the VideoSettingsGroup SimGroup to populate options.
// The object is defined in core/rendering/scripts/graphicsOptions.tscript
// A majority of the options are statically defined, but some are dynamically populated
// on refresh, like the display device or available resolution options.
// Once populated, we loop over the simgroup structure to populate our option entry
// rows in the options menu itself.
function OptionsMenu::populateVideoSettings(%this)
{
VideoSettingsList.clear();
VideoSettingsGroup::populateDisplaySettings();
for(%i=0; %i < VideoSettingsGroup.getCount(); %i++)
{
%setting = VideoSettingsGroup.getObject(%i);
if(%setting.class $= "SubOptionsGroup")
{
%entry = addOptionGroup(%setting.displayName);
if(isObject(%entry))
VideoSettingsList.add(%entry);
for(%s=0; %s < %setting.getCount(); %s++)
{
%option = %setting.getObject(%s);
%optionsEntry = addOptionEntry(%option);
if(isObject(%optionsEntry))
VideoSettingsList.add(%optionsEntry);
}
}
else if(%setting.class $= "OptionsSettings")
{
%optionsEntry = addOptionEntry(%setting);
if(isObject(%optionsEntry))
VideoSettingsList.add(%optionsEntry);
}
}
//Ensure our newly templated options listings are sized right
for(%i=0; %i < VideoSettingsList.getCount(); %i++)
{
%entry = VideoSettingsList.getObject(%i);
%entry.resize(0, 0, VideoSettingsList.extent.x - 15, %entry.extent.y); //-10 for the scroll wheel pad
}
}
//==============================================================================
// This function utilizes the AudioSettingsGroup SimGroup to populate options.
// The object is defined in core/sfx/scripts/audioOptions.tscript
// Similar to the video options, it can be a mix of static and dynamically populated
// option entries, which we then iterate over and populate the entry rows for the menu
function OptionsMenu::populateAudioSettings(%this)
{
AudioSettingsList.clear();
AudioSettingsGroup.populateSettings();
//Process the lists
for(%i=0; %i < AudioSettingsGroup.getCount(); %i++)
{
%setting = AudioSettingsGroup.getObject(%i);
if(%setting.class $= "SubOptionsGroup")
{
%entry = addOptionGroup(%setting.displayName);
if(isObject(%entry))
AudioSettingsList.add(%entry);
for(%s=0; %s < %setting.getCount(); %s++)
{
%option = %setting.getObject(%s);
%optionsEntry = addOptionEntry(%option);
if(isObject(%optionsEntry))
AudioSettingsList.add(%optionsEntry);
}
}
else if(%setting.class $= "AudioOptionsSettings")
{
%optionsEntry = addOptionEntry(%setting);
if(isObject(%optionsEntry))
AudioSettingsList.add(%optionsEntry);
}
}
AudioSettingsList.add(addOptionGroup("Channel Volume"));
//Now we'll populate the sliders for the audio channels.
//The defaults of these are defined in core/sfx/scripts/audio.tscript
//These define the MasterVolume channel, as well as several other common defualt ones
//Because it's a variable list, this can be expanded by modules by just upping $AudioChannelCount
//and then defining the $AudioChannelName[x] with the displayed name and
//and the $AudioChannels[x] variable with the SFXSource object defined to it for the given channel
AudioSettingsList.add(addOptionSlider("Master Volume", "", "$pref::SFX::masterVolume", 0, 1, 10));
//We init to 1, because 0 is the reserved for the masterVolume in practice
for(%i=1; %i < $AudioChannelCount; %i++)
{
AudioSettingsList.add(addOptionSlider($AudioChannelsName[%i] @ " Volume", "", "$pref::SFX::channelVolume" @ %i, 0, 1, 10));
}
//Ensure our newly templated options listings are sized right
for(%i=0; %i < AudioSettingsList.getCount(); %i++)
{
%entry = AudioSettingsList.getObject(%i);
%entry.resize(0, 0, AudioSettingsList.extent.x - 15, %entry.extent.y); //-10 for the scroll wheel pad
}
}
function OptionsMenu::populateKBMControls(%this)
{
%this.populateKeybinds("keyboard" TAB "mouse", KBMControlsList);
%this.syncGui();
KBMControlsList.syncGui();
}
function OptionsMenu::populateGamepadControls(%this)
{
%this.populateKeybinds("gamepad", GamepadControlsList);
%this.syncGui();
GamepadControlsList.syncGui();
}
function OptionsMenu::populateKeybinds(%this, %devices, %controlsList)
{
%controlsList.clear();
//build out our list of action maps
%actionMapCount = ActionMapGroup.getCount();
%actionMapList = "";
for(%i=0; %i < %actionMapCount; %i++)
{
%actionMap = ActionMapGroup.getObject(%i);
if(%actionMap == GlobalActionMap.getId())
continue;
%actionMapName = %actionMap.humanReadableName $= "" ? %actionMap.getName() : %actionMap.humanReadableName;
//see if we have any actual listed remappable keys for this movemap. if so, drop it from the listing
%hasRemaps = false;
for ( %r = 0; %r < $RemapCount; %r++ )
{
%testMapName = $RemapActionMap[%r].humanReadableName $= "" ? $RemapActionMap[%r].getName() : $RemapActionMap[%r].humanReadableName;
if(%actionMapName $= %testMapName)
{
//got a match to at least one, so we're ok to continue
%hasRemaps = true;
break;
}
}
if(!%hasRemaps)
continue;
if(%actionMapList $= "")
%actionMapList = %actionMapName;
else
%actionMapList = %actionMapList TAB %actionMapName;
}
//If we didn't find any valid actionMaps, then just exit out
if(%actionMapList $= "")
return;
if($activeRemapControlSet $= "")
$activeRemapControlSet = getField(%actionMapList, 0);
echo("============================================");
for(%am = 0; %am < getFieldCount(%actionMapList); %am++)
{
%currentActionMap = getField(%actionMapList, %am);
//only add the group if we've got more than one group, otherwise it's obviously
//part of the single grouping
if(getFieldCount(%actionMapList) > 1)
{
%actionMapGroupEntry = addOptionGroup(%currentActionMap);
%controlsList.add(%actionMapGroupEntry);
}
for ( %i = 0; %i < $RemapCount; %i++ )
{
%entryDevice = "";
//Check each field of %devices for device matching the remappable action
foreach$(%d in %devices){
if(%d $= $RemapDevice[%i]) {
%entryDevice = %d;
break;
}
}
//If there was no match go to the next remappable action
if(%entryDevice $= "")
continue;
%actionMapName = $RemapActionMap[%i].humanReadableName $= "" ? $RemapActionMap[%i].getName() : $RemapActionMap[%i].humanReadableName;
if(%currentActionMap !$= %actionMapName)
continue;
%keyMap = buildFullMapString( %i, $RemapActionMap[%i], %entryDevice );
%description = $RemapDescription[%i];
echo("Added ActionMap Entry: " @ %actionMapName @ " | " @ %entryDevice @ " | " @ %keymap @ " | " @ %description);
%remapEntry = addActionMapEntry(%actionMapName, %entryDevice, %keyMap, %i, %description);
%controlsList.add(%remapEntry);
}
}
//Ensure our newly templated options listings are sized right
for(%i=0; %i < %controlsList.getCount(); %i++)
{
%entry = %controlsList.getObject(%i);
%entry.resize(0, 0, %controlsList.extent.x - 15, %entry.extent.y); //-10 for the scroll wheel pad
}
}
//==============================================================================
function tryCloseOptionsMenu(%val)
{
if(!%val)
return;
$optionsChangeRequiresRestart = false;
%unappliedVideoChanges = VideoSettingsList.checkForUnappliedChanges();
%unappliedAudioChanges = AudioSettingsList.checkForUnappliedChanges();
//validate audio prefs
if($pref::SFX::masterVolume_tempVar !$= "" && $pref::SFX::masterVolume_tempVar != $pref::SFX::masterVolume)
%unappliedAudioChanges = true;
for(%i=1; %i < $AudioChannelCount; %i++)
{
%tempVolume = getVariable("$pref::SFX::channelVolume" @ %i @ "_tempVar");
if(%tempVolume !$= "" && $pref::SFX::channelVolume[ %i ] != %tempVolume)
%unappliedAudioChanges = true;
}
if(%unappliedVideoChanges || %unappliedAudioChanges)
{
MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?",
"OptionsMenu.applyChangedOptions(); BaseUIBackOut(1);", "BaseUIBackOut(1);",
"Apply", "Discard");
}
else
{
BaseUIBackOut(1);
}
}
function tryApplyOptions(%val)
{
if(!%val)
return;
$optionsChangeRequiresRestart = false;
%unappliedVideoChanges = VideoSettingsList.checkForUnappliedChanges();
%unappliedAudioChanges = AudioSettingsList.checkForUnappliedChanges();
if(%unappliedVideoChanges || %unappliedAudioChanges)
OptionsMenu.applyChangedOptions();
}
function OptionsMenu::applyChangedOptions(%this)
{
VideoSettingsList.applyChanges();
AudioSettingsList.applyChanges();
//Process the audio channel tempvars to get their values
//and then apply them to the actual pref variable, as well as the SFXChannelVolume
$pref::SFX::masterVolume = $pref::SFX::masterVolume_tempVar;
sfxSetMasterVolume( $pref::SFX::masterVolume );
//0 is always master anyways
for(%i=1; %i < $AudioChannelCount; %i++)
{
%volume = getVariable("$pref::SFX::channelVolume" @ %i @ "_tempVar");
sfxSetChannelVolume( %i, %volume );
$pref::SFX::channelVolume[ %i ] = %volume;
}
//Finally, write our prefs to file
%prefPath = getPrefpath();
export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false);
if($optionsChangeRequiresRestart)
MessageBoxOK("Restart Required", "Some of your changes require the game to be restarted.");
}
function doKeyRemap( %optionEntry )
{
%name = getField(%optionEntry.keymap,0);
RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
OptRemapInputCtrl.index = %optionEntry.remapIndex;
$remapListDevice = %optionEntry.device;
Canvas.pushDialog( RemapDlg );
}
function OptionsMenu::resetSettings(%this)
{
MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", "");
}
//==============================================================================
// Option types
function addOptionGroup(%displayName)
{
OptionsMenu.optsListCount++;
%group = new GuiTextCtrl() {
text = %displayName;
position = "0 0";
extent = "500 45";
profile = "MenuHeaderText";
tooltipProfile = "GuiToolTipProfile";
canSave = false;
};
return %group;
}
function optionsMenuButton::onHighlighted(%this, %highlighted)
{
%container = %this.getParent();
%container-->optionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
%container-->optionDescription.profile = %highlighted ? GuiMLTextProfileHighlighted : GuiMLTextProfile;
%valuesContainer = %container-->valuesContainer;
%valuesContainer-->optionValue.profile = %highlighted ? GuiMenuTextProfileHL : GuiMenuTextProfile;
OptionsMenuSettingsScroll.scrollToObject(%container);
}
function addOptionEntry(%optionObj)
{
OptionsMenu.optsListCount++;
if(!isObject(%optionObj) || (%optionObj.class !$= "OptionsSettings" && %optionObj.class !$= "AudioOptionsSettings"))
{
error("addOptionsEntry() - attempting to create a new options entry, but was provided an invalid options object");
return 0;
}
%qualityLevel = getCurrentQualityLevel(%optionObj);
if(isObject(%qualityLevel))
{
%qualityLevelText = %qualityLevel.displayName;
%qualityLevelIndex = %optionObj.getObjectIndex(%qualityLevel);
}
else
{
%qualityLevelText = %qualityLevel;
%qualityLevelIndex = %optionObj.getCount();
}
%optionNameHeight = 20;
if(%optionObj.Description $= "")
%optionNameHeight = 40;
%entry = new GuiContainer() {
position = "0 0";
extent = "800 40";
profile = GuiMenuDefaultProfile;
tooltipProfile = "GuiToolTipProfile";
horizSizing = "width";
vertSizing = "bottom";
class = "OptionsListEntry";
optionsObject = %optionObj;
currentOptionIndex = %qualityLevelIndex;
selectionID = OptionsMenu.optsListCount;
canSave = false;
new GuiButtonCtrl() {
profile = GuiMenuButtonProfile;
position = "0 0";
extent = "800 40";
horizSizing = "width";
vertSizing = "height";
internalName = "button";
class = "optionsMenuButton";
};
new GuiTextCtrl() {
text = %optionObj.OptionName;
position = $optionsEntryPad SPC -1;
extent = 400 SPC %optionNameHeight;
profile = "MenuSubHeaderText";
tooltipProfile = "GuiToolTipProfile";
internalName = "optionName";
};
new GuiTextCtrl() {
text = %optionObj.Description;
position = $optionsEntryPad SPC 17;
extent = "400 18";
profile = "GuiMLTextProfile";
tooltipProfile = "GuiToolTipProfile";
internalName = "optionDescription";
};
new GuiContainer() {
position = "400 0";
extent = "400 40";
profile = GuiModelessDialogProfile;
tooltipProfile = "GuiToolTipProfile";
horizSizing = "left";
vertSizing = "height";
internalName = "valuesContainer";
new GuiButtonCtrl() {
position = "310 0";
extent = "20 40";
text = "<";
profile = GuiMenuButtonProfile;
internalName = "prevValButton";
command = "$MenuList.listPosition = $thisControl.getParent().getParent().selectionID; OptionMenuPrevSetting(1);";
};
new GuiTextCtrl() {
text = %qualityLevelText;
position = "330 0";
extent = "50 40";
profile = "GuiMenuTextProfile";
tooltipProfile = "GuiToolTipProfile";
horizSizing = "right";
vertSizing = "center";
internalName = "optionValue";
};
new GuiButtonCtrl() {
position = "380 0";
extent = "20 40";
text = ">";
profile = GuiMenuButtonProfile;
internalName = "nextValButton";
command = "$MenuList.listPosition = $thisControl.getParent().getParent().selectionID; OptionMenuNextSetting(1);";
};
};
};
return %entry;
}
function addOptionSlider(%optionName, %optionDesc, %prefName, %sliderMin, %sliderMax, %sliderTicks)
{
OptionsMenu.optsListCount++;
%currentVal = getVariable(%prefName);
%tempVarName = %prefName @ "_tempVar";
if(%currentVal $= "")
%currentVal = %sliderMin;
setVariable(%tempVarName, %currentVal);
%optionNameHeight = 20;
if(%optionDesc $= "")
%optionNameHeight = 40;
%entry = new GuiContainer() {
position = "0 0";
extent = "800 40";
profile = GuiMenuDefaultProfile;
tooltipProfile = "GuiToolTipProfile";
horizSizing = "width";
vertSizing = "bottom";
class = "OptionsListSliderEntry";
canSave = false;
new GuiButtonCtrl() {
profile = GuiMenuButtonProfile;
position = "0 0";
extent = "800 40";
horizSizing = "width";
vertSizing = "height";
internalName = "button";
class = "optionsMenuButton";
};
new GuiTextCtrl() {
text = %optionName;
position = $optionsEntryPad SPC -1;
extent = 400 SPC %optionNameHeight;
profile = "MenuSubHeaderText";
tooltipProfile = "GuiToolTipProfile";
internalName = "optionName";
};
new GuiTextCtrl() {
text = %optionDesc;
position = $optionsEntryPad SPC 17;
extent = "400 18";
profile = "GuiMLTextProfile";
tooltipProfile = "GuiToolTipProfile";
internalName = "optionDescription";
};
new GuiContainer() {
position = "400 0";
extent = "400 40";
profile = GuiModelessDialogProfile;
tooltipProfile = "GuiToolTipProfile";
horizSizing = "left";
vertSizing = "height";
internalName = "valuesContainer";
new GuiSliderCtrl() {
range = %sliderMin SPC %sliderMax;
ticks = %sliderTicks;
snap = "1";
value = %currentVal;
variable = %tempVarName;
useFillBar = "1";
fillBarColor = $TextMediumEmphasisColor;
renderTicks = "0";
position = "0 10";
extent = "400 20";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "center";
profile = GuiMenuButtonProfile;
visible = "1";
active = "1";
command = "$thisControl.updateSliderValue();";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
class = "OptionsSliderEntrySlider";
internalName = "slider";
};
};
};
return %entry;
}
function OptionsSliderEntrySlider::updateSliderValue(%this)
{
//update settings value here
}
function OptionsMenuActionMapButton::onHighlighted(%this, %highlighted)
{
%container = %this.getParent();
%container-->actionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
OptionsMenuSettingsScroll.scrollToObject(%container);
}
function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
{
%entry = new GuiContainer() {
position = "0 0";
extent = "800 40";
profile = GuiMenuDefaultProfile;
tooltipProfile = "GuiToolTipProfile";
horizSizing = "width";
vertSizing = "bottom";
class = "OptionsKeybindEntry";
actionMap = %actionMap;
device = %device;
keymap = %keyMap;
remapIndex = %index;
canSave = false;
new GuiButtonCtrl() {
profile = GuiMenuButtonProfile;
position = "0 0";
extent = "800 40";
horizSizing = "width";
vertSizing = "height";
internalName = "button";
class = "OptionsMenuActionMapButton";
altCommand = "doKeyRemap($thisControl.getParent());";
};
new GuiTextCtrl() {
text = getField(%keyMap, 0);
position = $optionsEntryPad SPC -1;
extent = "400 40";
profile = "MenuSubHeaderText";
tooltipProfile = "GuiToolTipProfile";
internalName = "actionName";
};
new GuiContainer() {
position = "400 3";
extent = "400 34";
profile = GuiModelessDialogProfile;
tooltipProfile = "GuiToolTipProfile";
horizSizing = "left";
vertSizing = "height";
internalName = "valuesContainer";
};
};
%buttonContainer = %entry.findObjectByInternalName("valuesContainer");
if ($reportKeymapping)
echo("Keymap: " @ %keymap @ " | Keymap word count: " @ getWordCount(getField(%keyMap, 1)));
if(getWordCount(getField(%keyMap, 1)) == 2)
{
%modifierBtn = new GuiIconButtonCtrl() {
position = 156 SPC -10;
extent = "98 45";
BitmapAsset = "";
profile = GuiRemapActionMapButtonProfile;
sizeIconToButton = true;
makeIconSquare = true;
iconLocation = "center";
internalName = "modifierButton";
active = false;
};
%combinerText = new GuiTextCtrl(){
position = 264 SPC -5;
extent = "20 45";
profile = MenuSubHeaderText;
text = " + ";
};
%bindButton = new GuiIconButtonCtrl() {
position = "300 -10";
extent = "98 45";
BitmapAsset = "";
profile = GuiRemapActionMapButtonProfile;
sizeIconToButton = true;
makeIconSquare = true;
iconLocation = "center";
internalName = "bindButton";
active = false;
};
%buttonContainer.add(%modifierBtn);
%buttonContainer.add(%combinerText);
%buttonContainer.add(%bindButton);
}
else
{
%bindButton = new GuiIconButtonCtrl() {
position = "300 -10";
extent = "98 45";
BitmapAsset = "";
profile = GuiRemapActionMapButtonProfile;
sizeIconToButton = true;
makeIconSquare = true;
iconLocation = "center";
internalName = "bindButton";
active = false;
};
%buttonContainer.add(%bindButton);
}
return %entry;
}