I was asked recently if there was a way to get rid of all of the filter options on the main menu, so that the system was locked in "All Games" mode. The person asking was getting ready to take his pin cab to a pinball expo to put on the show floor, so he wanted to lock things down a bit so that random users at the show wouldn't mess things up or confuse themselves by hiding a bunch of the games behind a filter.
PinballY doesn't have a specific option setting for this kind of "kiosk mode" restriction, but it's the sort of thing that's easy to implement in Javascript, since Javascript lets you modify any of the system menus to your exact liking. In this case, you can use this capability to remove a bunch of the standard menu options to restrict the functions that users can access.
Removing menu items is pretty simple by itself, so for the sake of a more complete example, let's throw in one more feature: let's add a menu item that lets you switch in and out of Kiosk mode through the UI.
Obviously, we can't let ordinary users access this special new Kiosk Mode command, as that would defeat the whole purpose. Fortunately, there's an obvious place to put any menu commands that we want to restrict to the pin cab priesthood, namely the Operator Menu. In a real pin cab setup, the Operator Menu is normally accessed from the service panel buttons inside the coin door. That was intentionally designed for exactly this situation, since it naturally restricts access to the Operator Menu to those who have the key to the coin door. Perfect for an expo setup.
If you've looked at the other worked examples, you know the process for adding a new command to a menu by now:
Here's the code to do all of that.
That should mostly look familiar if you've gone over the other examples that set up custom menu commands. There are a couple of special extra things we're doing in this example, though:
Now we come to the original question, which is how to get rid of the filter menu command in the main menu.
In most cases, removing a command from a menu works like this:
This case is a little different, in that the filters don't have pre-determined IDs. The system assigns command IDs to the filters at the start of each session instead.
All of that makes it seem a little trickier to find the filter commands. But the system helps us out here by grouping the filter commands into a range of commands, command.FilterFirst to command.FilterLast. For the sake of completeness, we should also remove any custom user filters you've added through other Javascript modules; those will be in the range command.UserFilterFirst to command.UserFilterLast.
There's also the matter of "filter groups", where the command in the main menu takes you to a sub-menu with the individual filters. For example, "Filter by Manufacturer" takes you to a separate menu showing the manufacturer filters. For these, the system does give us a set of fixed constants: command.FilterByAdded, command.FilterByCategory, and so on. It's a little brittle to rely on a fixed set like that, though, since we'd have to remember to change our Javascript code every time PinballY gets a new built-in filter group. So the better way to do this is to take advantage of the ability to get a list of all of the filters via gameList.getAllFilters(), and use that to come up with a set of all of the group IDs.
We can actually simplify things a bit by using the group command approach for the filter commands as well, so that we just have to look in one place to see if a given command is any sort of filter command.
Note that it's just a happy (or perhaps confusing) coincidence that we're using the Javascript array method named "filter()" to remove the filter menu items! That's a standard Javascript method that takes a subset of an array according to a test condition - in this case, keeping only commands that aren't in the list of filter commands.
The call to tidyMenu() is there to handle the likely situation that we'll remove all of the items between a pair of separator bars that the system used to group the filter commands visually in the menu. The tidyMenu() method looks for adjacent separator bars, which we can identify by their empty title string, and removes the first one when it finds a pair of them packed together with nothing in between. This gets rid of any unsightly empty groups that are left over after we edit the menu, making it look presentable again.
There's one more little detail we'll want to take care of. When in Kiosk Mode, we'll also want to disable the Exit menu, so that users won't be able to quit out of PinballY and mess around with your Windows desktop. To do that, we can intercept the menu event that occurs when the Exit menu is about to be opened, and cancel the whole thing.
Note that you can also disable the Exit menu manually from the Menu Options page of the Settings dialog. But I think it's a little tidier to include it in the Kiosk Mode option like this, since this way, you won't have to remember to change that separate setting each time you switch modes. The custom Kiosk Mode command we placed on the operator menu takes care of it automatically.
And one more thing! Now that we've disabled the normal Exit menu, it would be nice to have a way for the operator to exit the program, by adding a command to the Operator Menu. We just need to add an item that activates the built-in Quit command. Let's add it to the end of the menu, just before the standard "Cancel" item at the bottom.