# mainWindow Object

mainWindow is a pre-defined PinballY object representing the main user interface window (the "playfield" window). This window is the event target for most UI-related events, and in many ways it serves as the Javascript object that represents the overall PinballY application.

## Event target

mainWindow is an event target object, so you can use the standard event methods (on(), off(), addEventListener(), etc) to add and remove event listeners. See EventTarget.

mainWindow serves as the event target for the following event types:

## Drawing layer ordering

The system displays graphics in several layers in the main window. If you use custom drawing layers, you can interleave your graphics with the system's graphics by using the Z index when creating a layer. Here's the order of the layers, from back to front:

- Main background image or video
- Custom drawing layers with Z index 0 to 999
- Underlay
- Custom drawing layers 1000 to 1999
- Status line text
- Custom drawing layers 2000 to 2999
- Wheel images
- Custom drawing layers 3000 to 3999
- Game info box (the summary of the current game selection that appears when the UI is idle)
- Custom drawing layers 4000 to 4999
- Video overlays and popup boxes
- Custom drawing layers 5000 to 5999
- Menus and credit/coin messages
- Custom drawing layers 6000 and above
- Drag-and-drop feedback graphics

## Methods and properties

The mainWindow object provides the common window methods and properties. It also provides the additional items listed below.

mainWindow.doButtonCommand(command, down, repeatCount): Simulates a key press, or more precisely, simulates a processed key event that corresponds to CommandButtonEvent. This carries out the effect of a named button command, specified by the string command. The valid command names are the values listed for the .command property of the CommandButtonEvent object. down is a boolean indicating if this simulates a key press (true) or a key-up event (false) representing the user releasing the key.

repeatCount is an integer indicating if the simulated event represents an initial key press or an auto-repeated key press (that is, repeated key events generated when the key is being held down). 0 represents an initial key/button press (not yet auto-repeated), 1 represents the first auto-repeat, 2 is the second auto-repeat, and so on. repeatCount is only meaningful when down is true, for obvious reasons.

Because the simulated key press is coming from Javascript already, it doesn't generate any of the usual Javascript events for actual key presses; it just carries out the effect of the key command.

mainWindow.doCommand(id): Executes the command specified by id, which is one of the integer command codes in the Commands set. This function carries out a menu-level command, as opposed to a button-level command; for the latter, use doButtonCommand().

mainWindow.DOFPulse(name): Pulses the named DOF event. This turns the effect "on" (by setting its "brightness" level in DOF to the maximum value of 255), then turns the effect back off (by setting the DOF brightness value to 0) after a brief interval. This is the normal way in DOF to trigger the lighting or tactile effects associated with an "event". In a simulated pinball game, a DOF event would represent a specific, momentary action in the game, such as "the ball hit the Extra Ball target". In a PinballY context you might use this to represent a discrete user action, such as "pressed the left flipper button" or "navigated to a new game".

You can connect events fired with this method to actions in your DOF Config Tool configuration by using the same event name in the Config Tool, adding the $ prefix in the Config Tool rule. For example, if you write `mainWindow.DOFPulse("MyEvent")` in Javascript, the corresponding rule in the DOF Config Tool syntax would refer to the event as `$MyEvent`, because the Config Tool uses the $ prefix to refer to named events. See DOF Events for more.

mainWindow.DOFSet(name, value): Sets the given named DOF event to the given value, from 0 (off) to 255 (full "brightness"). The setting stays in effect until you change it with another call to DOFEffect() using the same name and a different value.

You can connect events fired with this method to actions in your DOF Config Tool configuration by using the same event name in the Config Tool, adding the $ prefix in the Config Tool rule. For example, if you write `mainWindow.DOFSet("MyEvent", 255)` in Javascript, the corresponding rule in the DOF Config Tool syntax would refer to the event as `$MyEvent`, because the Config Tool uses the $ prefix to refer to named events. See DOF Events for more.

Be careful about timing. DOF effects require a little time padding between consecutive changes to a given effect's value, because DOF operates on its own "clock", and only checks for updates periodically. If you update the same named event twice in a row too quickly, DOF might not notice the change and might not trigger the desired hardware effects. For cases where you want to represent a momentary action in the UI, such as "user pressed left flipper button", it's almost always better to use DOFPulse(), since that automatically paces the ON-OFF sequence at a speed that DOF can handle.

This function doesn't coordinate at all with PinballY's own DOF event generation, so it's easiest to use this for your own custom events, using unique names that aren't part of PinballY's own named DOF event set (see DOF Events). You can use any names you want for named DOF events, so you're free to invent as many new events as you like representing whatever actions you like. You can also use this to update PinballY's own named events, but since PinballY updates those events itself, this could cause unpredictable interactions.

mainWindow.endAttractMode(): Exits "Attract Mode" if it's currently active. There's no effect if the program isn't already in attract mode. The attractmodeend event isn't fired when you use this method.

mainWindow.getActiveWindow(): Returns the window object (mainWindow, backglassWindow, etc) corresponding to the current active window in the application. This is the active window at the operating system level, which means that it's in the foreground and has keyboard focus. If the application is currently in the background, none of the windows are active, so this returns null.

mainWindow.getKeyCommand(descriptor): Returns an array of the button commands assigned to the given key or joystick button. descriptor is an object describing the key or button to look up. This can be in one of the following formats:

{ type: "key", vkey: integer }; // look up by virtual key (vkey) from key event { type: "key", code: string }; // look up by key code from key event { type: "joystick", unit: integer, button: integer }; // joystick button

This is the same information provided to your event listener in a KeyEvent or JoystickButtonEvent object, so it's easy to look up the command information in one of those handlers.

The command names in the returned array are the same names used in the .command property of the CommandButtonEvent object. An array is returned because it's possible for a user to assign multiple commands to the same keyboard key or joystick button. Pressing a key with multiple commands assigned carries out each of the commands in sequence.

mainWindow.getUIMode(): Returns an object describing the current UI state. Here's a quick summary of the object's contents:

{ mode: "wheel", // see list game: (object), // GameInfo object for currently selected game in wheel menuID: "main", // see list; present only in "menu" mode popupID: "about box", // see list; present only in "popup" mode runMode: "running", // or "starting", "exiting"; present only when a game is running capture: "single" // or "batch"; present only when running a game in media capture mode }

The main state is given by the property .mode, which has one of the values listed below. Depending on the mode, other properties of the object might be present to provide additional information.

- "wheel": in the normal game wheel UI, awaiting a command
- "menu": a menu is being displayed (this refers to the graphical menu that PinballY displays as an overlay in the playfield window, not a standard Windows menu). In this case, the .menuID property of the mode object will contain a string identifying which particular menu is being displayed. See system menus for a list of the built-in menus and their identifiers.
- "popup": a popup box is being displayed. The .popupID property of the mode object is a string specifying the type of popup. See system popups for a list of the system popup types.
- "running": a running game is in progress. Note that "menu" mode can supersede this, since the user can still bring up menus while a game is running. You can determine for sure whether or not a game is running by checking for the presence of another property, .runMode, which will be present if and only if a game is running. If present, .runMode will be set to the string "starting" (the game has been launched but hasn't opened its UI window yet), "running" (the game is in progress), or "exiting" (PinballY has closed the game and is waiting for the process to exit). In addition, if the game is running for the purposes of media capture, the property .capture will be present, and will be set to the string "single" for a single-game capture or "batch" for a batch capture.
- "attract": attract mode/screen saver mode (meaning that there hasn't been any user input for the period of time configured in the settings to activate attract mode)

The .game property identifies the game that's currently selected in the wheel, if any. This is present regardless of which UI mode is in effect. This is a GameInfo object, which has properties that access the game's details. The .game property will be omitted (so it'll read as undefined) if no game is selected, which can only happen when the wheel is completely empty. The wheel can be empty when the program can't find any installed games, or when a filter is selected that doesn't match any games.

mainWindow.launchOverlay: This read-only property contains an object representing the launch overlay, which displays graphics showing the status during game launches. This lets you customize the graphics shown during the launch process. launchOverlay has two properties, giving you access to the two drawing layers of the launch overlay:

- fg: an object representing the foreground layer
- bg: an object representing the background layer

Each of those objects in turn has methods that let you show graphics in its layer. The foreground layer (mainWindow.launchOverlay.fg) is, as the name suggests, the front layer; the background layer (bg) is immediately behind it in the drawing order. These are the topmost layers overall, so they're draw in front of the wheel UI and the playfield background. If you draw an opaque background into either window, it'll cover up everything else in the UI.

The reason we have two layers for this one overlay is that it lets the system (or your Javascript code) draw some fixed graphics in the background layer, and then update the message in the foreground layer at each stage of the process, without having to redraw the background. This is more efficient than redrawing the whole background on every update, and it's also nice if you want to show a video, since videos can't be directly combined in one layer with other graphics. You can use the background layer for a video that plays throughout the loading process, for example, while status messages are drawn on top of the video via the foreground layer.

The launch overlay is only displayed during game launches. Accessing it at other times will have no effect. In most cases, you'd use this object in listeners for the LaunchOverlayEvent group of events.

The fg and bg objects are DrawingLayer objects. You can draw graphics into them the same way you would with a drawing layer that you created explicitly in your scripting code via createDrawingLayer(). However, since PinballY itself creates and manages the fg and bg objects, there are a few differences to be aware of:

- These layers only exist during the launch process, so you can't draw into them at other times
- PinballY itself draws graphics in these layers during the launch process, which might replace any graphics you draw if you don't intervene via the LaunchOverlay events
- Because these are system-created layers, you can't remove them with removeDrawingLayer()
- You also can't move or resize the layers - they're always stretched to exactly fill the window's height and width

mainWindow.message(message, style): Shows a message using a graphical popup box in the main window. Unlike the global alert() function, this doesn't pause the script until the user acknowledges the message; it simply shows or queues the message and returns immediately. This is a good option for showing error messages or status updates, since it doesn't interrupt the flow of the user interface with a modal dialog. If style is provided, it's a string value specifying the visual style of the popup message. This can be "info", "warning", or "error", to show the message with green, orange, or red trim (respectively), to visually signal the nature of the message. The regular "info" style is used if style is omitted.

mainWindow.playGame(game, options): Launches a game. game is a GameInfo object for the game to be launched. options is an object with properties specifying option settings; this whole argument can be omitted, in which case defaults are used for all options. If you do include the object argument, you only have to specify the properties for options you want to override; any missing properties will use the corresponding defaults. Here are the possible options properties:

- command: An integer giving the command code that the game is nominally launched under. The default is command.PlayGame, which is also the command that the system itself uses to launch games for normal play (as opposed to media capture). The command you specify here has no effect on how PinballY itself handles the launch process, but it's reported to your event handlers as the command code in all of the LaunchEvent events reported that fire during the launch, so you can use it as the basis of any custom handling you want to perform during the launch.
- system: A GameSysInfo object specifying which system to use to launch the game. The default is the system associated with the game in the game database, or the system associated with the table directory where the game file is located. If it's not possible for PinballY to uniquely determine the system from one of those sources, you must specify this option to tell the program which system to use. Note that PinballY doesn't try to second-guess your choice of system here; it'll let you run any game file with any system. But for obvious reasons, the launched program will probably show an error, crash, or otherwise fail to work properly if you try to launch it with a game file designed for a different system.
- overrides: An optional object value specifying overrides for the normal launch parameters. The parameters are specified via the object's properties. These are the same properties that can be set in the override property of a prelaunch event; see override properties for the list of properties and their meanings.

  You can specify any subset of the override properties. The normal system launch parameters are used for any properties you omit from the override set. For example, if you want to change the "show window" mode but use the rest of the normal the launch parameters unchanged, you could do something like this:

  mainWindow.playGame(game, undefined, { swShow: SW_HIDE });

mainWindow.setUnderlay(filename, options): Display a new underlay in the main window's wheel UI. This loads the image file specified by filename and displays it as the new underlay. Use an empty string ("") to remove the underlay image.

options, if present, is an object specifying additional layout details for the underlay. This lets you override the normal layout parameters for an individual underlay file, in case you want to customize the size or position of each underlay file separately. If the options object is omitted entirely, all of the layout parameters use the settings from the configuration. If you do provide an options object, you don't have to include all of the properties listed below - just the ones you want to override. Any properties not included in your options object use the defaults, taken from the configuration. Any values you specify in the options object override the settings for duration of this underlay display (so the overrides remain in effect even if the user edits the option settings or resizes the window). The options only last for the duration of this single underlay display; they aren't persistently attached to the file or anything crazy like that. The following properties can be specified:

- height: The display height of the underlay in the window, as a percentage of the total window height. E.g., the value 20.5 specifies 20.5% of the window height.
- maxWidth: The maximum display width of the underlay, as a percentage of the window height. The underlay is normally stretched to the full width of the window, but maxWidth can be used to limit the stretch, to set a limit on how far the aspect ratio is distorted. This can be useful to prevent excessive distortion when the window is much wider than it is tall (as in typical landscape mode displays).
- yOffset: The distance from the bottom of the window to use to position the underlay vertically, as a percentage of the window height.

See also UnderlayEvent, which describes the event fired when the system is about to initiate its own change to the underlay because of a new game selection in the wheel UI.

mainWindow.showMenu(id, items, options): Displays a custom menu in the main window, in the same style as the main menu, exit menu, etc. See Menus for more details. The menuopen event isn't fired when you use this method.

mainWindow.showPopup(desc): Displays a custom popup dialog in the main window, in the style of the standard system popups (e.g., game information, high scores, ratings entry). See Custom Popups for more details.

mainWindow.showWheel(show): Shows or hides the game wheel display. If show is true, the function shows the wheel; if show is false, the wheel is hidden. The system hides the wheel itself at certain times, such as when "attract mode" is active and the options are set to hide the wheel in attract mode; in these cases, showing the wheel through this function will have no immediate effect.

mainWindow.startAttractMode(): Enters "Attract Mode", the screen saver mode that normally kicks in automatically when there hasn't been any keyboard or mouse input for some amount of time (the exact amount of time is configurable in the settings). This function lets you explicitly enter Attract Mode from Javascript code, so that you can create your own custom conditions for triggering the mode, separately from the system's normal handling. For example, you could use this to enter attract mode when a certain key is pressed, or from a custom menu selection. The attractmodestart event isn't fired when you use this method.

mainWindow.statusLines: An object containing references to the StatusLine objects representing the on-screen status line displays. The object has the following properties:

- upper: The upper line of the main two-line status area
- lower: The lower line of the main two-line status area
- attract: The single-line status area that replaces the main status area when attract mode is active