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,6 +21,7 @@ function UI::onCreate( %this )
// addLanguage("defaultTable","try","tr"); // addLanguage("defaultTable","try","tr");
createLangTable("defaultTable"); createLangTable("defaultTable");
setCoreLangTable("defaultTable"); setCoreLangTable("defaultTable");
if(isFile("./langs/languageMap"))
exec("./langs/languageMap"); exec("./langs/languageMap");
} }

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)
@ -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,7 +1245,6 @@ 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)
{ {
@ -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")
Canvas.popDialog( RemapDlg );
if(%action $= "escape" || %action $= "btn_start")
return; 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 );
%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++;
}