Merge pull request #1624 from Sir-Skurpsalot/Skurpz/UI-Module-Fixes
Some checks are pending
Linux Build / ${{matrix.config.name}} (map[build_type:Release cc:gcc cxx:g++ generator:Ninja name:Ubuntu Latest GCC]) (push) Waiting to run
MacOSX Build / ${{matrix.config.name}} (map[build_type:Release cc:clang cxx:clang++ generator:Ninja name:MacOSX Latest Clang]) (push) Waiting to run
Windows Build / ${{matrix.config.name}} (map[build_type:Release cc:cl cxx:cl environment_script:C:/Program Files (x86)/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat generator:Visual Studio 17 2022 name:Windows Latest MSVC]) (push) Waiting to run

Skurpz/UI module fixes
This commit is contained in:
Brian Roberts 2025-12-18 10:25:14 -06:00 committed by GitHub
commit dd72a627a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 677 additions and 752 deletions

View file

@ -13,14 +13,18 @@ function initClient()
exec( "./connectionToServer." @ $TorqueScriptFileExtension ); exec( "./connectionToServer." @ $TorqueScriptFileExtension );
exec( "./levelDownload." @ $TorqueScriptFileExtension ); exec( "./levelDownload." @ $TorqueScriptFileExtension );
exec( "./levelLoad." @ $TorqueScriptFileExtension ); exec( "./levelLoad." @ $TorqueScriptFileExtension );
exec( "data/defaults." @ $TorqueScriptFileExtension );
moduleExec("initClient");
//load prefs //load prefs
exec( "data/defaults." @ $TorqueScriptFileExtension );
%prefPath = getPrefpath(); %prefPath = getPrefpath();
if ( isFile( %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension ) ) if ( isFile( %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension ) )
exec( %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension ); exec( %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension );
moduleExec("initClient"); //keybinds stores user custom keybinds generated by the UI module (if installed), this should be the only place this is executed
if(isScriptFile(%prefPath @ "/keybinds." @ $TorqueScriptFileExtension))
exec(%prefPath @ "/keybinds." @ $TorqueScriptFileExtension);
// Copy saved script prefs into C++ code. // Copy saved script prefs into C++ code.
setDefaultFov( $pref::Player::defaultFov ); setDefaultFov( $pref::Player::defaultFov );

View file

@ -9,22 +9,3 @@ function getMouseAdjustAmount(%val)
// based on a default camera FOV of 90' // based on a default camera FOV of 90'
return(%val * ($cameraFov / 90) * 0.01) * $pref::Input::LinkMouseSensitivity; return(%val * ($cameraFov / 90) * 0.01) * $pref::Input::LinkMouseSensitivity;
} }
function addKeyRemap(%name, %actionMap, %device, %command, %description)
{
if(%name $= "" ||
%actionMap $= "" ||
%device $= "" ||
%command $= "")
{
error("addKeybindRemap() - tried to add a remap entry, but didn't have all the keeded info!");
return;
}
$RemapName[$RemapCount] = %name;
$RemapCmd[$RemapCount] = %command;
$RemapActionMap[$RemapCount] = %actionMap;
$RemapDevice[$RemapCount] = %device;
$RemapDescription[$RemapCount] = %description;
$RemapCount++;
}

View file

@ -30,10 +30,6 @@ function ExampleModule::initClient(%this)
//client scripts //client scripts
exec("./scripts/client/defaultkeybinds"); exec("./scripts/client/defaultkeybinds");
%prefPath = getPrefpath();
if(isScriptFile(%prefPath @ "/keybinds"))
exec(%prefPath @ "/keybinds");
%this.queueExec("./scripts/shared/ExampleGameMode"); %this.queueExec("./scripts/shared/ExampleGameMode");
} }

View file

@ -21,7 +21,8 @@ function UI::onCreate( %this )
// addLanguage("defaultTable","try","tr"); // addLanguage("defaultTable","try","tr");
createLangTable("defaultTable"); createLangTable("defaultTable");
setCoreLangTable("defaultTable"); setCoreLangTable("defaultTable");
exec("./langs/languageMap"); if(isFile("./langs/languageMap"))
exec("./langs/languageMap");
} }
function UI::onDestroy( %this ) function UI::onDestroy( %this )

View file

@ -388,7 +388,7 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
horizSizing = "left"; horizSizing = "left";
vertSizing = "center"; vertSizing = "center";
profile = "GuiMenuButtonProfile"; profile = "GuiMenuButtonProfile";
command = "ChooseLevelBegin(1);"; command = "ChooseLevelMenuOption(1);";
tooltipProfile = "GuiToolTipProfile"; tooltipProfile = "GuiToolTipProfile";
}; };
new GuiIconButtonCtrl(ChooseLevelBackBtn) { new GuiIconButtonCtrl(ChooseLevelBackBtn) {

View file

@ -433,9 +433,9 @@ function ChooseLevelMenuOption(%val)
if(%val) if(%val)
{ {
if(ChooseLevelMenu.currentMenuIdx == 0) if(ChooseLevelMenu.currentMenuIdx == 0)
ToggleGameMode(ChooseLevelMenu.listPosition); ToggleGameMode($MenuList.listPosition);
else if(ChooseLevelMenu.currentMenuIdx == 1) else if(ChooseLevelMenu.currentMenuIdx == 1)
ChooseLevelBegin(ChooseLevelMenu.listPosition); ChooseLevelBegin($MenuList.listPosition);
} }
} }

View file

@ -1,4 +1,3 @@
$reportKeymapping = false;
$optionsEntryPad = 10; $optionsEntryPad = 10;
$OptionsMenuCategories[0] = "Video"; $OptionsMenuCategories[0] = "Video";
@ -6,6 +5,11 @@ $OptionsMenuCategories[1] = "Audio";
$OptionsMenuCategories[2] = "KBM"; $OptionsMenuCategories[2] = "KBM";
$OptionsMenuCategories[3] = "Controller"; $OptionsMenuCategories[3] = "Controller";
//==============================================================================
//
// OptionsMenu General Functions
//
//==============================================================================
function OptionsMenu::onAdd(%this) function OptionsMenu::onAdd(%this)
{ {
if(!isObject(%this.optionsCategories)) if(!isObject(%this.optionsCategories))
@ -465,240 +469,6 @@ function OptionsMenuActivateOption(%val)
} }
} }
//==============================================================================
// 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) function tryCloseOptionsMenu(%val)
{ {
if(!%val) if(!%val)
@ -723,8 +493,8 @@ function tryCloseOptionsMenu(%val)
if(%unappliedVideoChanges || %unappliedAudioChanges) if(%unappliedVideoChanges || %unappliedAudioChanges)
{ {
MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?", MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?",
"OptionsMenu.applyChangedOptions(); BaseUIBackOut(1);", "BaseUIBackOut(1);", "OptionsMenu.applyChangedOptions(); BaseUIBackOut(1);", "BaseUIBackOut(1);",
"Apply", "Discard"); "Apply", "Discard");
} }
else else
{ {
@ -750,6 +520,7 @@ function OptionsMenu::applyChangedOptions(%this)
{ {
VideoSettingsList.applyChanges(); VideoSettingsList.applyChanges();
AudioSettingsList.applyChanges(); AudioSettingsList.applyChanges();
KBMControlsList.applyChanges(); //Saves settings and binds from GamepadControlsList as well
//Process the audio channel tempvars to get their values //Process the audio channel tempvars to get their values
//and then apply them to the actual pref variable, as well as the SFXChannelVolume //and then apply them to the actual pref variable, as well as the SFXChannelVolume
@ -772,23 +543,6 @@ function OptionsMenu::applyChangedOptions(%this)
MessageBoxOK("Restart Required", "Some of your changes require the game to be restarted."); 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 // Option types
function addOptionGroup(%displayName) function addOptionGroup(%displayName)
@ -1028,12 +782,419 @@ function OptionsSliderEntrySlider::updateSliderValue(%this)
//update settings value here //update settings value here
} }
function OptionsMenuActionMapButton::onHighlighted(%this, %highlighted) //==============================================================================
//
// Video List Functions
//
//==============================================================================
//==============================================================================
// 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)
{ {
%container = %this.getParent(); VideoSettingsList.clear();
%container-->actionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
OptionsMenuSettingsScroll.scrollToObject(%container); 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
}
}
function OptionsMenu::resetSettings(%this)
{
MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", "");
}
//==============================================================================
//
// Audio List Functions
//
//==============================================================================
//==============================================================================
// 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
}
}
//==============================================================================
//
// Keyboard & Mouse, Controller List Functions
//
//==============================================================================
function KBMControlsList::applyChanges(%this){
//Save mouse sensitivity
$pref::Input::LinkMouseSensitivity = $pref::Input::LinkMouseSensitivity_tempVar;
if(!$RemapDirty)
return;
%prefPath = getPrefpath();
%filePath = (%prefPath @ "/keybinds." @ $TorqueScriptFileExtension);
%fileWrite = new fileObject(){};
// Delete the file first if it exists
if (isFile(%filePath))
fileDelete( %filepath );
// Open / create the custom binds file
%fileWrite.openForWrite(%filePath);
// Iterate through the remapabble bindings and write them to the keyBinds file
for(%i = 0; %i < $RemapCount; %i++){
%actionMap = $RemapActionMap[%i];
%cmd = $RemapCmd[%i];
%binding = %actionMap.getBinding(%cmd);
%device = getField(%binding, 0);
%action = getField(%binding, 1);
// saves a restoreRemap call to each line of keyBinds file instead of the bind command in order to leverage functions for
// removing conflicts and duplicates
if (%device !$= "" && %action !$= ""){
%line = "restoreRemap(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @ %cmd @ "\");";
%fileWrite.writeLine(%line);
}
else
continue;
}
%fileWrite.close();
%fileWrite.delete();
$RemapDirty = false;
}
// restoreRemap() is called from user custom keybinds file which is generated by KBMControlsList::applyChanges()
function restoreRemap(%device, %actionMap, %action, %cmd){
// Make sure no other "action" (key / button press) is bound to this command on this actionMap (from remapDlg.tscript)
unbindExtraActions( %cmd, %actionMap, %device, 0 );
unbindExtraActions( %cmd, %actionMap, %device, 1 );
%actionMap.bind( %device, %action, %cmd );
}
function OptionsMenu::populateKBMControls(%this){
%this.populateKeybinds("keyboard", KBMControlsList); // includes remappable actions declared with "mouse" as the device as well
%this.syncGui();
KBMControlsList.syncGui();
}
function OptionsMenu::populateGamepadControls(%this){
%this.populateKeybinds("gamepad", GamepadControlsList);
%this.syncGui();
GamepadControlsList.syncGui();
}
function OptionsMenu::populateKeybinds(%this,%device, %controlsList) {
%controlsList.clear();
if (%device $= "keyboard") {
%controlsList.add(addOptionGroup("Mouse Options"));
%controlsList.add(addOptionSlider("Mouse Sensitivity", "", "$pref::Input::LinkMouseSensitivity", 0, 1, 10));
}
//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++ )
{
//If there was no match go to the next remappable action
if(%device $= "" || %device !$= $RemapDevice[%i])
continue;
%actionMapName = $RemapActionMap[%i].humanReadableName $= "" ? $RemapActionMap[%i].getName() : $RemapActionMap[%i].humanReadableName;
if(%currentActionMap !$= %actionMapName)
continue;
%keyMap = buildFullMapString( %i, $RemapActionMap[%i], %device );
%description = $RemapDescription[%i];
echo("Added ActionMap Entry: " @ %actionMapName @ " | " @ %device @ " | " @ %keymap @ " | " @ %description);
%remapEntry = addActionMapEntry(%actionMapName, %device, %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 buildFullMapString( %index, %actionMap, %deviceType )
{
%name = $RemapName[%index];
%cmd = $RemapCmd[%index];
%temp = %actionMap.getBinding( %cmd );
if ( %temp $= "" )
return %name TAB "";
%mapString = "";
%count = getFieldCount( %temp );
for ( %i = 0; %i < %count; %i += 2 )
{
if ( %mapString !$= "" )
continue;
//%mapString = %mapString @ ", ";
%device = getField( %temp, %i + 0 );
%object = getField( %temp, %i + 1 );
if (startsWith(%device,"mouse"))
%deviceType = "mouse";
if(%deviceType !$= "" && !startsWith(%device, %deviceType))
continue;
%mapString = %mapString @ getMapDisplayName( %device, %object );
}
return %name TAB %mapString;
}
// Also used by remapDlg.tscript
function getMapDisplayName( %device, %action )
{
if ( %device $= "keyboard" )
return( %action );
else if ( strstr( %device, "mouse" ) != -1 )
{
// Substitute "mouse" for "button" in the action string:
%pos = strstr( %action, "button" );
if ( %pos != -1 )
{
%mods = getSubStr( %action, 0, %pos );
%object = getSubStr( %action, %pos, 1000 );
%instance = getSubStr( %object, strlen( "button" ), 1000 );
return( %mods @ "mouse" @ ( %instance + 1 ) );
}
else
error( "Mouse input object other than button passed to getDisplayMapName!" );
}
else if ( strstr( %device, "joystick" ) != -1 )
{
// Substitute "joystick" for "button" in the action string:
%pos = strstr( %action, "button" );
if ( %pos != -1 )
{
%mods = getSubStr( %action, 0, %pos );
%object = getSubStr( %action, %pos, 1000 );
%instance = getSubStr( %object, strlen( "button" ), 1000 );
return( %mods @ "joystick" @ ( %instance + 1 ) );
}
else
{
%pos = strstr( %action, "pov" );
if ( %pos != -1 )
{
%wordCount = getWordCount( %action );
%mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : "";
%object = getWord( %action, %wordCount - 1 );
switch$ ( %object )
{
case "upov": %object = "POV1 up";
case "dpov": %object = "POV1 down";
case "lpov": %object = "POV1 left";
case "rpov": %object = "POV1 right";
case "upov2": %object = "POV2 up";
case "dpov2": %object = "POV2 down";
case "lpov2": %object = "POV2 left";
case "rpov2": %object = "POV2 right";
default: %object = "";
}
return( %mods @ %object );
}
else
error( "Unsupported Joystick input object passed to getDisplayMapName!" );
}
}
else if ( strstr( %device, "gamepad" ) != -1 )
{
return %action;
%pos = strstr( %action, "button" );
if ( %pos != -1 )
{
%mods = getSubStr( %action, 0, %pos );
%object = getSubStr( %action, %pos, 1000 );
%instance = getSubStr( %object, strlen( "button" ), 1000 );
return( %mods @ "joystick" @ ( %instance + 1 ) );
}
else
{
%pos = strstr( %action, "thumb" );
if ( %pos != -1 )
{
//%instance = getSubStr( %action, strlen( "thumb" ), 1000 );
//return( "thumb" @ ( %instance + 1 ) );
return %action;
}
else
error( "Unsupported gamepad input object passed to getDisplayMapName!" );
}
}
return( "" );
} }
function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description) function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
@ -1084,8 +1245,7 @@ function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
}; };
%buttonContainer = %entry.findObjectByInternalName("valuesContainer"); %buttonContainer = %entry.findObjectByInternalName("valuesContainer");
if ($reportKeymapping) echo("Keymap: " @ %keymap @ " | Keymap word count: " @ getWordCount(getField(%keyMap, 1)));
echo("Keymap: " @ %keymap @ " | Keymap word count: " @ getWordCount(getField(%keyMap, 1)));
if(getWordCount(getField(%keyMap, 1)) == 2) if(getWordCount(getField(%keyMap, 1)) == 2)
{ {
%modifierBtn = new GuiIconButtonCtrl() { %modifierBtn = new GuiIconButtonCtrl() {
@ -1142,3 +1302,23 @@ function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
return %entry; return %entry;
} }
function OptionsMenuActionMapButton::onHighlighted(%this, %highlighted)
{
%container = %this.getParent();
%container-->actionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
OptionsMenuSettingsScroll.scrollToObject(%container);
}
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 );
}

View file

@ -1,125 +0,0 @@
//--- OBJECT WRITE BEGIN ---
$guiContent = new GuiControl(RemapConfirmDlg) {
position = "0 0";
extent = "1024 768";
minExtent = "8 8";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "1";
helpTag = "0";
new GuiContainer(RemapConfirmationPanel) {
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "168 352";
extent = "700 64";
minExtent = "8 2";
horizSizing = "center";
vertSizing = "center";
profile = "GuiDefaultProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
new GuiChunkedBitmapCtrl() {
bitmapAsset = "UI:hudfill_image";
useVariable = "0";
tile = "0";
position = "0 0";
extent = "700 64";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(RemapConfirmationText) {
text = "\"m\" is already bound to \"Forward\"!\nDo you wish to replace this mapping?";
maxLength = "255";
margin = "0 0 0 0";
padding = "0 0 0 0";
anchorTop = "1";
anchorBottom = "0";
anchorLeft = "1";
anchorRight = "0";
position = "0 8";
extent = "700 20";
minExtent = "8 8";
horizSizing = "width";
vertSizing = "height";
profile = "GuiMenuButtonProfile";
visible = "1";
active = "1";
accelerator = "return";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiButtonCtrl(RemapConfirmationYesButton) {
text = "Yes";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
position = "270 36";
extent = "80 22";
minExtent = "8 8";
horizSizing = "right";
vertSizing = "top";
profile = "GuiMenuButtonProfile";
visible = "1";
active = "1";
command = "ControlsMenu.redoMapping(keyboard, \"m\", \"jump\", 0, 4); Canvas.popDialog();";
accelerator = "return";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiButtonCtrl(RemapConfirmationNoButton) {
text = "No";
groupNum = "-1";
buttonType = "PushButton";
useMouseEvents = "0";
position = "367 36";
extent = "80 22";
minExtent = "8 8";
horizSizing = "right";
vertSizing = "top";
profile = "GuiMenuButtonProfile";
visible = "1";
active = "1";
command = "Canvas.popDialog();";
accelerator = "escape";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
};
};
//--- OBJECT WRITE END ---

View file

@ -14,18 +14,21 @@ function OptRemapInputCtrl::onAxisEvent( %this, %device, %action, %axisVal)
function OptRemapInputCtrl::onInputEvent( %this, %device, %action ) function OptRemapInputCtrl::onInputEvent( %this, %device, %action )
{ {
if(!startsWith(%device,$remapListDevice) && %action !$= "escape" && %action !$= "btn_start") if(%action $= "escape" || %action $= "btn_start"){
{ Canvas.popDialog( RemapDlg );
return; return;
} }
else // do nothing if gamepad is attempted to be used on the keyboard & mouse binds menu...
{ else if(%device $= "gamepad" && $remapListDevice $= "keyboard")
return;
// do nothing if keyboard or mouse is attempted to be used on the gamepad binds menu...
else if ((%device $= "mouse" || %device $= "keyboard") && $remapListDevice $= "gamePad")
return;
// procceed with remap if appropriate device used on binds menu...
else{
Canvas.popDialog( RemapDlg ); Canvas.popDialog( RemapDlg );
if(%action $= "escape" || %action $= "btn_start")
return;
%this.doRemap(%device, %action, 0); %this.doRemap(%device, %action, 0);
$RemapDirty = true;
} }
} }
@ -44,7 +47,7 @@ function OptRemapInputCtrl::doRemap(%this, %device, %action, %axisVal)
// Get the current command this action is mapped to. // Get the current command this action is mapped to.
%prevMap = %actionMap.getCommand( %device, %action ); %prevMap = %actionMap.getCommand( %device, %action );
//TODO: clear all existant keybinds to a command and then bind it so we only have a single one at all times // Make sure no other "action" (key / button press) is bound to this command
unbindExtraActions( %cmd, %actionMap, %device, 0 ); unbindExtraActions( %cmd, %actionMap, %device, 0 );
unbindExtraActions( %cmd, %actionMap, %device, 1 ); unbindExtraActions( %cmd, %actionMap, %device, 1 );
@ -55,14 +58,15 @@ function OptRemapInputCtrl::doRemap(%this, %device, %action, %axisVal)
// was already assigned. // was already assigned.
if ( %prevMap $= "" || %prevMap $= %cmd ) if ( %prevMap $= "" || %prevMap $= %cmd )
{ {
//unbindExtraActions( %cmd, %actionMap, 1 );
%actionMap.bind( %device, %action, %cmd ); %actionMap.bind( %device, %action, %cmd );
OptionsMenu.populateKBMControls(); OptionsMenu.populateKBMControls();
OptionsMenu.populateGamepadControls(); OptionsMenu.populateGamepadControls();
return; return;
} }
//------------------------------------------------------------------------------------------------------------------
// If this action (key / button press) was already bound to another command, undoing that is handled in this section
//------------------------------------------------------------------------------------------------------------------
// Look for the index of the previous mapping. // Look for the index of the previous mapping.
%prevMapIndex = findRemapCmdIndex( %prevMap ); %prevMapIndex = findRemapCmdIndex( %prevMap );
@ -77,22 +81,23 @@ function OptRemapInputCtrl::doRemap(%this, %device, %action, %axisVal)
// Setup the forced remapping callback command. // Setup the forced remapping callback command.
%callback = "redoMapping(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @ %callback = "redoMapping(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @
%cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");"; %cmd @ "\");";
// Warn that we're about to remove the old mapping and // Warn that we're about to remove the old mapping and
// replace it with another. // replace it with another.
%prevCmdName = $RemapName[%prevMapIndex]; %prevCmdName = $RemapName[%prevMapIndex];
//Canvas.pushDialog( RemapConfirmDlg );
%remapWarnText = "\"" @ %mapName @ "\" is already bound to \"" @ %prevCmdName @ "\"! Do you wish to replace this mapping?"; %remapWarnText = "\"" @ %mapName @ "\" is already bound to \"" @ %prevCmdName @ "\"! Do you wish to replace this mapping?";
%doRemapCommand = "redoMapping(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @ %doRemapCommand = "redoMapping(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @
%cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");"; %cmd @ "\");";
%cancelCommand = ""; %cancelCommand = "";
MessageBoxYesNo( "Key already in use", %remapWarnText, %doRemapCommand, %cancelCommand ); MessageBoxYesNo( "Key already in use", %remapWarnText, %doRemapCommand, %cancelCommand );
} }
/// This unbinds actions beyond %count associated to the /// This unbinds actions (buttons / key presses) beyond %count associated to the
/// particular actionMap %commmand. /// particular actionMap %commmand.
function unbindExtraActions( %command, %actionMap, %device, %count ) function unbindExtraActions( %command, %actionMap, %device, %count )
{ {
@ -106,7 +111,24 @@ function unbindExtraActions( %command, %actionMap, %device, %count )
%amDevice = getField( %temp, %i + 0 ); %amDevice = getField( %temp, %i + 0 );
%action = getField( %temp, %i + 1 ); %action = getField( %temp, %i + 1 );
if(%device !$= "" || %device $= %amDevice) if(amDevice !$= "") {
%actionMap.unbind( %device, %action ); %actionMap.unbind( %amDevice, %action ); //need to use %amDevice because could be changing from keyboard to mouse or vice versa
}
} }
} }
function findRemapCmdIndex( %command ){
for ( %i = 0; %i < $RemapCount; %i++ )
{
if ( %command $= $RemapCmd[%i] )
return( %i );
}
return( -1 );
}
function redoMapping( %device, %actionMap, %action, %cmd)
{
%actionMap.bind( %device, %action, %cmd );
OptionsMenu.populateKBMControls();
OptionsMenu.populateGamepadControls();
}

View file

@ -1,157 +0,0 @@
// =============================================================================
// KEYBINDS MENU
// =============================================================================
function ControlsMenuDefaultsButton::onClick(%this)
{
//For this to work with module-style, we have to figure that somewhere, we'll set where our default keybind script is at.
//This can be hardcoded in your actual project.
//exec($KeybindPath);
//ControlsMenu.reload();
}
function getMapDisplayName( %device, %action )
{
if ( %device $= "keyboard" )
return( %action );
else if ( strstr( %device, "mouse" ) != -1 )
{
// Substitute "mouse" for "button" in the action string:
%pos = strstr( %action, "button" );
if ( %pos != -1 )
{
%mods = getSubStr( %action, 0, %pos );
%object = getSubStr( %action, %pos, 1000 );
%instance = getSubStr( %object, strlen( "button" ), 1000 );
return( %mods @ "mouse" @ ( %instance + 1 ) );
}
else
error( "Mouse input object other than button passed to getDisplayMapName!" );
}
else if ( strstr( %device, "joystick" ) != -1 )
{
// Substitute "joystick" for "button" in the action string:
%pos = strstr( %action, "button" );
if ( %pos != -1 )
{
%mods = getSubStr( %action, 0, %pos );
%object = getSubStr( %action, %pos, 1000 );
%instance = getSubStr( %object, strlen( "button" ), 1000 );
return( %mods @ "joystick" @ ( %instance + 1 ) );
}
else
{
%pos = strstr( %action, "pov" );
if ( %pos != -1 )
{
%wordCount = getWordCount( %action );
%mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : "";
%object = getWord( %action, %wordCount - 1 );
switch$ ( %object )
{
case "upov": %object = "POV1 up";
case "dpov": %object = "POV1 down";
case "lpov": %object = "POV1 left";
case "rpov": %object = "POV1 right";
case "upov2": %object = "POV2 up";
case "dpov2": %object = "POV2 down";
case "lpov2": %object = "POV2 left";
case "rpov2": %object = "POV2 right";
default: %object = "";
}
return( %mods @ %object );
}
else
error( "Unsupported Joystick input object passed to getDisplayMapName!" );
}
}
else if ( strstr( %device, "gamepad" ) != -1 )
{
return %action;
%pos = strstr( %action, "button" );
if ( %pos != -1 )
{
%mods = getSubStr( %action, 0, %pos );
%object = getSubStr( %action, %pos, 1000 );
%instance = getSubStr( %object, strlen( "button" ), 1000 );
return( %mods @ "joystick" @ ( %instance + 1 ) );
}
else
{
%pos = strstr( %action, "thumb" );
if ( %pos != -1 )
{
//%instance = getSubStr( %action, strlen( "thumb" ), 1000 );
//return( "thumb" @ ( %instance + 1 ) );
return %action;
}
else
error( "Unsupported gamepad input object passed to getDisplayMapName!" );
}
}
return( "" );
}
function buildFullMapString( %index, %actionMap, %deviceType )
{
%name = $RemapName[%index];
%cmd = $RemapCmd[%index];
%temp = %actionMap.getBinding( %cmd );
if ( %temp $= "" )
return %name TAB "";
%mapString = "";
%count = getFieldCount( %temp );
for ( %i = 0; %i < %count; %i += 2 )
{
if ( %mapString !$= "" )
continue;
//%mapString = %mapString @ ", ";
%device = getField( %temp, %i + 0 );
%object = getField( %temp, %i + 1 );
if (startsWith(%device,"mouse"))
%deviceType = "mouse";
if(%deviceType !$= "" && !startsWith(%device, %deviceType))
continue;
%mapString = %mapString @ getMapDisplayName( %device, %object );
}
return %name TAB %mapString;
}
function ControlsMenuRebindButton::onClick(%this)
{
%name = $RemapName[%this.keybindIndex];
RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
OptRemapInputCtrl.index = %this.keybindIndex;
OptRemapInputCtrl.optionIndex = %this.optionIndex;
Canvas.pushDialog( RemapDlg );
}
function findRemapCmdIndex( %command )
{
for ( %i = 0; %i < $RemapCount; %i++ )
{
if ( %command $= $RemapCmd[%i] )
return( %i );
}
return( -1 );
}
function redoMapping( %device, %actionMap, %action, %cmd, %oldIndex, %newIndex )
{
//%actionMap.bind( %device, %action, $RemapCmd[%newIndex] );
%actionMap.bind( %device, %action, %cmd );
OptionsMenu.populateKBMControls();
OptionsMenu.populateGamepadControls();
}

View file

@ -182,11 +182,11 @@ function addLanguage(%langTable, %filename, %alias)
{ {
// generate an .lso file and if a languageMap file does not exist, it as well // generate an .lso file and if a languageMap file does not exist, it as well
%needLangMap = true; %needLangMap = true;
if(isFile("data/UI/langs/languageMap")) if(isFile("./langs/languageMap"))
%needLangMap = false; %needLangMap = false;
CompileLanguage("data/UI/langs/"@ %filename @".txt", %needLangMap); CompileLanguage("./langs/"@ %filename @".txt", %needLangMap);
%langTable.addLanguage("data/UI/langs/"@ %filename @".lso", %alias); %langTable.addLanguage("./langs/"@ %filename @".lso", %alias);
} }
function switchLanguage(%language) //use here the #n as it's the order of inclusion function switchLanguage(%language) //use here the #n as it's the order of inclusion
@ -195,3 +195,26 @@ function switchLanguage(%language) //use here the #n as it's the order of inclus
getCoreLangTable().setCurrentLanguage(%language); getCoreLangTable().setCurrentLanguage(%language);
Canvas.setContent(Canvas.getContent()); Canvas.setContent(Canvas.getContent());
} }
function addKeyRemap(%name, %actionMap, %device, %command, %description)
{
if(%name $= "" ||
%actionMap $= "" ||
%device $= "" ||
%command $= "")
{
error("addKeybindRemap() - tried to add a remap entry, but didn't have all the keeded info!");
return;
}
// "mouse" is accepted as a convenience, but the remappable actions related functions treat it same as "keyboard".
if(%device $= "mouse")
%device = "keyboard";
$RemapName[$RemapCount] = %name;
$RemapCmd[$RemapCount] = %command;
$RemapActionMap[$RemapCount] = %actionMap;
$RemapDevice[$RemapCount] = %device;
$RemapDescription[$RemapCount] = %description;
$RemapCount++;
}