controlsMenu.tscript 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // =============================================================================
  2. // KEYBINDS MENU
  3. // =============================================================================
  4. function ControlsMenuDefaultsButton::onClick(%this)
  5. {
  6. //For this to work with module-style, we have to figure that somewhere, we'll set where our default keybind script is at.
  7. //This can be hardcoded in your actual project.
  8. //exec($KeybindPath);
  9. //ControlsMenu.reload();
  10. }
  11. function getMapDisplayName( %device, %action )
  12. {
  13. if ( %device $= "keyboard" )
  14. return( %action );
  15. else if ( strstr( %device, "mouse" ) != -1 )
  16. {
  17. // Substitute "mouse" for "button" in the action string:
  18. %pos = strstr( %action, "button" );
  19. if ( %pos != -1 )
  20. {
  21. %mods = getSubStr( %action, 0, %pos );
  22. %object = getSubStr( %action, %pos, 1000 );
  23. %instance = getSubStr( %object, strlen( "button" ), 1000 );
  24. return( %mods @ "mouse" @ ( %instance + 1 ) );
  25. }
  26. else
  27. error( "Mouse input object other than button passed to getDisplayMapName!" );
  28. }
  29. else if ( strstr( %device, "joystick" ) != -1 )
  30. {
  31. // Substitute "joystick" for "button" in the action string:
  32. %pos = strstr( %action, "button" );
  33. if ( %pos != -1 )
  34. {
  35. %mods = getSubStr( %action, 0, %pos );
  36. %object = getSubStr( %action, %pos, 1000 );
  37. %instance = getSubStr( %object, strlen( "button" ), 1000 );
  38. return( %mods @ "joystick" @ ( %instance + 1 ) );
  39. }
  40. else
  41. {
  42. %pos = strstr( %action, "pov" );
  43. if ( %pos != -1 )
  44. {
  45. %wordCount = getWordCount( %action );
  46. %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : "";
  47. %object = getWord( %action, %wordCount - 1 );
  48. switch$ ( %object )
  49. {
  50. case "upov": %object = "POV1 up";
  51. case "dpov": %object = "POV1 down";
  52. case "lpov": %object = "POV1 left";
  53. case "rpov": %object = "POV1 right";
  54. case "upov2": %object = "POV2 up";
  55. case "dpov2": %object = "POV2 down";
  56. case "lpov2": %object = "POV2 left";
  57. case "rpov2": %object = "POV2 right";
  58. default: %object = "";
  59. }
  60. return( %mods @ %object );
  61. }
  62. else
  63. error( "Unsupported Joystick input object passed to getDisplayMapName!" );
  64. }
  65. }
  66. else if ( strstr( %device, "gamepad" ) != -1 )
  67. {
  68. return %action;
  69. %pos = strstr( %action, "button" );
  70. if ( %pos != -1 )
  71. {
  72. %mods = getSubStr( %action, 0, %pos );
  73. %object = getSubStr( %action, %pos, 1000 );
  74. %instance = getSubStr( %object, strlen( "button" ), 1000 );
  75. return( %mods @ "joystick" @ ( %instance + 1 ) );
  76. }
  77. else
  78. {
  79. %pos = strstr( %action, "thumb" );
  80. if ( %pos != -1 )
  81. {
  82. //%instance = getSubStr( %action, strlen( "thumb" ), 1000 );
  83. //return( "thumb" @ ( %instance + 1 ) );
  84. return %action;
  85. }
  86. else
  87. error( "Unsupported gamepad input object passed to getDisplayMapName!" );
  88. }
  89. }
  90. return( "" );
  91. }
  92. function buildFullMapString( %index, %actionMap, %deviceType )
  93. {
  94. %name = $RemapName[%index];
  95. %cmd = $RemapCmd[%index];
  96. %temp = %actionMap.getBinding( %cmd );
  97. if ( %temp $= "" )
  98. return %name TAB "";
  99. %mapString = "";
  100. %count = getFieldCount( %temp );
  101. for ( %i = 0; %i < %count; %i += 2 )
  102. {
  103. if ( %mapString !$= "" )
  104. continue;
  105. //%mapString = %mapString @ ", ";
  106. %device = getField( %temp, %i + 0 );
  107. %object = getField( %temp, %i + 1 );
  108. if (startsWith(%device,"mouse"))
  109. %deviceType = "mouse";
  110. if(%deviceType !$= "" && !startsWith(%device, %deviceType))
  111. continue;
  112. %mapString = %mapString @ getMapDisplayName( %device, %object );
  113. }
  114. return %name TAB %mapString;
  115. }
  116. function fillRemapList()
  117. {
  118. %device = $remapListDevice;
  119. OptionsMenuSettingsList.clear();
  120. //build out our list of action maps
  121. %actionMapCount = ActionMapGroup.getCount();
  122. %actionMapList = "";
  123. for(%i=0; %i < %actionMapCount; %i++)
  124. {
  125. %actionMap = ActionMapGroup.getObject(%i);
  126. if(%actionMap == GlobalActionMap.getId())
  127. continue;
  128. %actionMapName = %actionMap.humanReadableName $= "" ? %actionMap.getName() : %actionMap.humanReadableName;
  129. //see if we have any actual listed remappable keys for this movemap. if so, drop it from the listing
  130. %hasRemaps = false;
  131. for ( %r = 0; %r < $RemapCount; %r++ )
  132. {
  133. %testMapName = $RemapActionMap[%r].humanReadableName $= "" ? $RemapActionMap[%r].getName() : $RemapActionMap[%r].humanReadableName;
  134. if(%actionMapName $= %testMapName)
  135. {
  136. //got a match to at least one, so we're ok to continue
  137. %hasRemaps = true;
  138. break;
  139. }
  140. }
  141. if(!%hasRemaps)
  142. continue;
  143. if(%actionMapList $= "")
  144. %actionMapList = %actionMapName;
  145. else
  146. %actionMapList = %actionMapList TAB %actionMapName;
  147. }
  148. //If we didn't find any valid actionMaps, then just exit out
  149. if(%actionMapList $= "")
  150. return;
  151. if($activeRemapControlSet $= "")
  152. $activeRemapControlSet = getField(%actionMapList, 0);
  153. OptionsMenuSettingsList.addOptionRow("Control Set", "$activeRemapControlSet", %actionMapList, false, "controlSetChanged", true, "Which keybind control set to edit", $activeRemapControlSet);
  154. for ( %i = 0; %i < $RemapCount; %i++ )
  155. {
  156. if(%device !$= "" && %device !$= $RemapDevice[%i])
  157. continue;
  158. %actionMapName = $RemapActionMap[%i].humanReadableName $= "" ? $RemapActionMap[%i].getName() : $RemapActionMap[%i].humanReadableName;
  159. if($activeRemapControlSet !$= %actionMapName)
  160. continue;
  161. %keyMap = buildFullMapString( %i, $RemapActionMap[%i], %device );
  162. %description = $RemapDescription[%i];
  163. %buttonImageAsset = getButtonBitmap(%device, getField(%keyMap, 1));
  164. OptionsMenuSettingsList.addKeybindRow(getField(%keyMap, 0), %buttonImageAsset, "doKeyRemap", true, %description);
  165. }
  166. //OptionsMenuSettingsList.refresh();
  167. //OptionsMenu.addRow( %i, %this.buildFullMapString( %i ) );
  168. }
  169. function controlSetChanged()
  170. {
  171. $activeRemapControlSet = OptionsMenuSettingsList.getObject(0).getCurrentOption();
  172. fillRemapList();
  173. }
  174. function doKeyRemap( %row )
  175. {
  176. %rowIndex = %row.getParent().getObjectIndex(%row);
  177. %rowIndex--; //Offset the rowIndex to account for controlset option
  178. %name = $RemapName[%rowIndex];
  179. RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
  180. OptRemapInputCtrl.index = %rowIndex;
  181. Canvas.pushDialog( RemapDlg );
  182. //Let the options menu know
  183. %actionMap = $RemapActionMap[%rowIndex];
  184. OptionsMenu.onKeybindChanged(%actionMap, %name);
  185. }
  186. function ControlsMenuRebindButton::onClick(%this)
  187. {
  188. %name = $RemapName[%this.keybindIndex];
  189. RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
  190. OptRemapInputCtrl.index = %this.keybindIndex;
  191. OptRemapInputCtrl.optionIndex = %this.optionIndex;
  192. Canvas.pushDialog( RemapDlg );
  193. }
  194. function OptRemapInputCtrl::onInputEvent( %this, %device, %action )
  195. {
  196. //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" );
  197. Canvas.popDialog( RemapDlg );
  198. // Test for the reserved keystrokes:
  199. if ( %device $= "keyboard" )
  200. {
  201. // Cancel...
  202. if ( %action $= "escape" )
  203. {
  204. // Do nothing...
  205. return;
  206. }
  207. }
  208. %cmd = $RemapCmd[%this.index];
  209. %name = $RemapName[%this.index];
  210. %actionMap = $RemapActionMap[%this.index];
  211. // Grab the friendly display name for this action
  212. // which we'll use when prompting the user below.
  213. %mapName = getMapDisplayName( %device, %action );
  214. // Get the current command this action is mapped to.
  215. %prevMap = %actionMap.getCommand( %device, %action );
  216. //TODO: clear all existant keybinds to a command and then bind it so we only have a single one at all times
  217. unbindExtraActions( %cmd, %actionMap, 0 );
  218. unbindExtraActions( %cmd, %actionMap, 1 );
  219. // If nothing was mapped to the previous command
  220. // mapping then it's easy... just bind it.
  221. if ( %prevMap $= "" )
  222. {
  223. //unbindExtraActions( %cmd, %actionMap, 1 );
  224. %actionMap.bind( %device, %action, %cmd );
  225. fillRemapList();
  226. return;
  227. }
  228. // If the previous command is the same as the
  229. // current then they hit the same input as what
  230. // was already assigned.
  231. if ( %prevMap $= %cmd )
  232. {
  233. //unbindExtraActions( %cmd, %actionMap, 0 );
  234. %actionMap.bind( %device, %action, %cmd );
  235. fillRemapList();
  236. return;
  237. }
  238. // Look for the index of the previous mapping.
  239. %prevMapIndex = findRemapCmdIndex( %prevMap );
  240. // If we get a negative index then the previous
  241. // mapping was to an item that isn't included in
  242. // the mapping list... so we cannot unmap it.
  243. if ( %prevMapIndex == -1 )
  244. {
  245. MessageBoxOK( "Remap Failed", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" );
  246. return;
  247. }
  248. // Setup the forced remapping callback command.
  249. %callback = "redoMapping(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @
  250. %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");";
  251. // Warn that we're about to remove the old mapping and
  252. // replace it with another.
  253. %prevCmdName = $RemapName[%prevMapIndex];
  254. Canvas.pushDialog( RemapConfirmDlg );
  255. %remapWarnText = "\"" @ %mapName @ "\" is already bound to \"" @ %prevCmdName @ "\"! Do you wish to replace this mapping?";
  256. %doRemapCommand = "redoMapping(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @
  257. %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ "); Canvas.popDialog();";
  258. %cancelCommand = "Canvas.popDialog();";
  259. MessageBoxYesNo( "Key already in use", %remapWarnText, %doRemapCommand, %cancelCommand );
  260. }
  261. function findRemapCmdIndex( %command )
  262. {
  263. for ( %i = 0; %i < $RemapCount; %i++ )
  264. {
  265. if ( %command $= $RemapCmd[%i] )
  266. return( %i );
  267. }
  268. return( -1 );
  269. }
  270. /// This unbinds actions beyond %count associated to the
  271. /// particular actionMap %commmand.
  272. function unbindExtraActions( %command, %actionMap, %count )
  273. {
  274. %temp = %actionMap.getBinding( %command );
  275. if ( %temp $= "" )
  276. return;
  277. %count = getFieldCount( %temp ) - ( %count * 2 );
  278. for ( %i = 0; %i < %count; %i += 2 )
  279. {
  280. %device = getField( %temp, %i + 0 );
  281. %action = getField( %temp, %i + 1 );
  282. %actionMap.unbind( %device, %action );
  283. }
  284. }
  285. function redoMapping( %device, %actionMap, %action, %cmd, %oldIndex, %newIndex )
  286. {
  287. //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] );
  288. %actionMap.bind( %device, %action, %cmd );
  289. fillRemapList();
  290. }