Difference between revisions of "XML: Key Traps"

From FSDeveloper Wiki
Jump to: navigation, search
Line 155: Line 155:
 
  6        (L:Num392,enum) (>L:Num393,enum)
 
  6        (L:Num392,enum) (>L:Num393,enum)
 
  7        (L:Num391,enum) (>L:Num392,enum)
 
  7        (L:Num391,enum) (>L:Num392,enum)
  8         (M:Key) (>L:Num391,enum)
+
  8           (M:Key) (>L:Num391,enum)
 
  9        (L:Num395,enum) chr  
 
  9        (L:Num395,enum) chr  
 
  10        (L:Num394,enum) chr scat
 
  10        (L:Num394,enum) chr scat

Revision as of 12:55, 5 July 2014

KEY TRAP

A Key Trap is gauge code that ‘listens’ for a specific keyboard entry to be made. Its purpose is to allow customized script to be executed when the user types that specific key. By nature, it’s conditional: “if the keystroke (for example, “A”) is made, then momentarily disregard whatever A was previously assigned to do and then process the key trap script.”

In XML, the trap is defined using an <On Key> block placed within a <Keys> section:

<Keys>
  <On Key="AlphaNumeric">
    <Visible>(L:KeyTrapEnabled, bool) 1 ==</Visible>
      (M:Key) chr (>C:fs9gps:NameSearchEnterChar)
  </On>
</Keys>

Here, the specified keystroke is any alphanumeric character and the key trap script passes the character that was typed to a gps variable provided, however, that L:KeyTrapEnabled = 1.

<Visible> expressions are frequently added to key traps so the user can control when the trap is functional, especially important when the broad key definitions “ascii” and “alphanumeric” are used. In this example, whenever the user has not set L:KeyTrapEnabled to 1, the key trap is not functional. Then, the typical (i.e., default) key assignment of “G” will still toggle landing gear rather than being trapped and the character “G” sent to the gps variable.

<On Key> blocks are nested within <Keys> sections and therefore should be placed at the bottom of the gauge script in order to catch all keystrokes and events triggered during each gauge update cycle.


DEFINING THE TRAP KEY

Format of the trap key definition is flexible. It can be broadly specified using “ascii” or “alphanumeric” expressions, or individually specified using the alphanumeric character itself, or the decimal or hex ascii code equivalent of it.

Examples:

<On Key=”ascii”> traps any of the following characters: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 and space, minus, plus, comma, period.

<On Key=”alphanumeric”> traps any of the following characters: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 and space

<On Key=”W”> traps the letter “W”
<On Key=”87”> traps the letter “W”.  87 is the decimal value of the ascii code for character “W”
<On Key=”0x57”> traps the letter “W”.  0x57 is the hex value of the ascii code for character “W”

Ctrl and Shift Combination: Ctrl and/or Shift plus an alphanumeric character can also be trapped in an <On Key> block.

The table below shows binary representation of the ascii code for letter W. The ascii decimal value of W is 87, hex equivalent is 0x57, and binary is 1 0 1 0 1 1 1.

To add Shift, place 1 in Bit 8. 1 in bit 9 for Ctrl. Ctrl+Shift is 1 in both bit 8 and bit 9:

CtrlShift.png

Several formats are acceptable for definition of the key combination.

<On Key=”855”> traps the key combination Ctrl + Shift + W
<On Key=”0x357”> traps the key combination Ctrl + Shift + W, and
<On Key=”Ctrl+Shift+W”> also traps the key combination Ctrl + Shift + W and may be the easiest format to remember.

When the <On Key> definition includes Shift and/or Ctrl, (M:Key) will return only the root character code. As an example, a key trap for Ctrl+W:

<Keys>
  <On Key="599">
    <Visible>(L:KeyTrapEnabled, bool) 1 ==</Visible>
      (M:Key) (>L:CtrlW_Value, enum)
  </On>
</Keys>

(L:CtrlW_Value, enum) will return 87, the decimal value of the ascii code for W, not 599 which is the decimal value for Ctrl + W used in the trap definition.


TRAPPABLE KEYSTROKES

The tables at the bottom of the wiki summarize keystroke trap capability. Blue font with no shading reflects keys and combinations that are trappable. Pink shading indicates that the key, or key combination, is not trappable, and grey represents uncertainty as my keyboards do not have these keys.


Ascii and Alphanumeric: indicate keys that are trappable using <On Key=”Ascii”> or <On Key=”Alphanumeric”> definitions.


Trap using Name: indicates keys that can be trapped using the character name in the definition, for example <On Key=”Backspace”> or <On Key=”A”>. Ctrl and Shift can be used in combination with these, for example <On Key=”Ctrl+Shift+Enter”>.


Trap using Ascii Decimal, Trap using Ascii Hex: indicates keystrokes that are trappable using decimal or hex values in the definition. For example, the Home key can be trapped using <On Key=”36”> or <On Key=”0x24”> definition.


Trap using Ctrl, Shift and Ctrl+Shift: Ctrl and Shift can be used in combination with some other keys. For example, a Ctrl+Capslock trap is defined as <On Key=”532”> or <On Key=”0x214”> (0X214 is the hex equivalent of decimal 532).


NEUTRALIZING AN EXISTING KEY ASSIGNMENT

A key trap without a trap script neutralizes an existing key assignment because the trap momentarily disregards the existing assignment and instead, processes the trap script. As an example,

<Keys>
  <On Key=”Q">
  </On>
</Keys>

disables the default sound toggle.


KEY TRAP PROCESSING

Keystrokes trapped in the current update cycle are queued and then their trap routines are sequentially processed at the end of the cycle. All simulation variables (A:Vars) affected by the trap routines return updated values on the subsequent cycle.

Key Traps across the Gauge Set: FS processes <On Key> trap routines found in all gauges of the aircraft’s panel (the ‘gauge set’).

So, if Gauge00 contains the following:

<Keys>
  <On Key=”Ctrl+W">
    <Visible>(L:KeyTrapEnabled, bool) 1 ==</Visible>
      (L:MyVarA,enum) 10 + (>L:MyVarA,enum)
    </On>
</Keys>

and Gauge01 contains:

<Keys>
  <On Key=”Ctrl+W">
    <Visible>(L:KeyTrapEnabled, bool) 1 ==</Visible>
      (L:MyVarA,enum) 20 + (>L:MyVarA,enum)
  </On>
</Keys>

Then, on the update cycle following entry of Ctrl+W, (L:MyVarA, enum) will return 30.


VISIBLE WINDOW REQUIREMENT

Key traps have the same visibility requirements as Event traps. One condition is that gauges must be in a visible window for their trap routines to be processed. If a gauge is part of a window whose visibility is set to visibility=0, then no <On Key> routines in that gauge will be run until visibility of the window is set to 1, or if the window is visible on the screen.

Another important condition is that key trap routines in XML gauges are disabled when the user is in External view. This is a problem for those who like to manage systems (i.e. the autopilot) via keystrokes while flying in External view.

Note: A recently released FSX module (XMLTools v.1.0, June 2014, from Tom Aguilo) will handle FSX event traps in any view mode, thus overcoming the visible and external window limitations of stock FSX. XMLTools can be freely downloaded from the FSDeveloper Resources site. Check that site or FSDeveloper Gauges Forum for XMLTools update notices.


M:KEY

M:Key is a parameter that returns the decimal ascii code value of an ascii or alphanumeric keyboard entry.

In the following key trap,

<Keys>
  <On Key="Alphanumeric">
    <Visible>(L:KeyTrapEnabled, bool) 1 ==</Visible>
      (M:Key) (>L:MKeyValue, enum)
  </On>
</Keys>

If the letter “X” is typed, (L:MKeyValue, enum) is 88.


SHIFT REGISTER

In certain situations, the user may want to concatenate and store multi-character alphanumeric keystroke entries. Without use of an external module such as XMLVars, FS cannot store string values. FS is limited to storing the decimal ascii code equivalent of individual letters into individual L:Vars. This can be accomplished through the use of a shift register.

The example below accommodates repetitive typing of up to 5 keystrokes, storing the ascii code value of each typed character into a separate L:Var, subsequently retrieving the L:Vars, converting the ascii code back to characters, concatenating the characters, then ultimately storing the string into FlightPlanNewWaypointIdent.

1   <Keys>		
2     <On Key="Alphanumeric">
3       <Visible>(L:KeyEntry, enum) 39 ==</Visible>
4         (L:Num394,enum) (>L:Num395,enum)
5         (L:Num393,enum) (>L:Num394,enum)
6         (L:Num392,enum) (>L:Num393,enum)
7         (L:Num391,enum) (>L:Num392,enum)
8           (M:Key) (>L:Num391,enum)
9         (L:Num395,enum) chr 
10        (L:Num394,enum) chr scat	
11        (L:Num393,enum) chr scat	
12        (L:Num392,enum) chr scat	
13        (L:Num391,enum) chr scat
14        (>@c:FlightPlanNewWaypointIdent, string)	
15    </On>		
16  </Keys>

Lines 4-7: The “shift register”. Before converting the current key entry to ascii and storing that number into L:Num391 (Line 8), the ascii value of the previous keystroke entry, which was initially stored in L:Num391, is stored into L:Num392 (Line 7). Preceding that (Line 6), the value in L:Num392 is shifted up to (stored into) L:Num393, and so forth. After 5 keystrokes, the ascii value of first keystroke entered will end up being stored in L:Num395.

Line 8: The ascii decimal value of the current keystroke, (M:Key), is stored into L:Num391.

Lines 9–13: The L:Var ascii values are recalled in a last-in, first-out order, converted back to symbols using the ‘chr’ operator, and concatenated using the ‘scat’ operator to form a string.

Line 14: The concatenated string is entered into FlightPlanNewWaypointIdent.

External dll modules such as Tom Aguilo’s XMLVars (included in his XMLTools module) or Doug Dawson’s String_Storage allow the user to store and retrieve string values and are highly recommended. For a more complete discussion of string storage options in Flight Simulator, refer to the Storing Strings wiki.


Acknowledgements: Pete Dowson (author of FSUIPC), Rob Barenregt, Tom Aguilo

Bob McElrath (July 2014)


KT1.png KT2.png KT3.png