Let's start start building the interface, then. Every interface needs menus, so let's create some.
Let's go through this step by step. In line 1 we create a menu inside main (our window) that was created in run above. In line 2 we tell HTKto attach this new menu we call menubar to be the menu of main.
In line 3 (we will not count the empty lines), we create our first pulldown menu -- that is what actually is normaly called a menu. This pulldown menu is created inside menubar, is called fm and has the charming text `File'. To fill this menu empty, we create menu entries, called menu commands inside fm; a menu command is the simplest form of menu item which you can just select (or not). So by now we have restb and quitb inside fm inside menubar inside main.
Besides restarting and quitting, we will need to put some more functionality into our menu. As we read above, the game grid will be resizeable so we will need a `Preferences' menu to have these commands in.
We create a second pulldown menu in menubar called pm. In this menu we nest to submenus (called menu cascades). Each of the cascades has a name, pmc1 and pmc2, and a text configuration set to its title. The next step is a bit tricky. One would now expect to fill the cascades directly with some commands. But the menu cascades are only Containers holding other menus, so we have to create another two menus inside main and assign them to the two cascades. These two menus are called pmc1m and pmc2m which should be an abreviation for preference menu cascade first menu (and second respectively).
By now we have a menu bar which holds two pulldown menus. The first contains two commands, the second contains two cascades which in turn each contain a menu again. To make sense of these two submenus we have to fill them of course. And finally we have to put some functions behind all those commands or this would all be for naught.
Figure 10: The hsMines main window with an open menu
In the code above we do several new things. First we create two Tk variables called varSize and varDiff. These are necessary to hold the state of the GUI, in this case the user's selection. Our next step is to create a menu radio button in each of the two submenus. The first radio button assigns pairs of integers to the TkVariable varSize, the actual values are as indicated in the text configuration and given in a couple of functions above in the code which can be fully seen in the source. Fig. 10 shows the size submenu of the preferences.
As you we can see in the code above (in main and run), currentSize holds the value of normalSize and so by default the radio button is set to normalSize. Nearly the same happens with varDiff and its radio button.
Note that we have to resolve the overloading of the numeric constants by type annotations, because TkVariables can hold all instances of the class GUIValue; when we just write value 3, this might also be e.g. the floating point number 3.
But something should happen we click those menus, so we need to bind them to some events:
This binds the commands and the size radio button(s) to a couple of events, which will occur whenever one of the buttons is selected (i.e. clicked). Note that we do not bind anything to the difficulty submenu. This is because we are actually not interested in the user selecting a new difficulty during the game, we just read out the value set by the user every time we restart a game. (This is not very polite -- it might be better to inform the user of this when he changes the selection, but this is just a small demonstration program.)