<p>This contrib allows you to write custom and easy to use building menus. As the name implies, these
menus are most useful for building things, that is, your builders might appreciate them, although
you can use them for your players as well.</p>
<p>Building menus are somewhat similar to <codeclass="docutils literal notranslate"><spanclass="pre">EvMenu</span></code> although they don’t use the same system at all and
are intended to make building easier. They replicate what other engines refer to as “building
editors”, which allow to you to build in a menu instead of having to enter a lot of complex
commands. Builders might appreciate this simplicity, and if the code that was used to create them
is simple as well, coders could find this contrib useful.</p>
<li><p>Building menus work on an object. This object will be edited by manipulations in the menu. So
you can create a menu to add/edit a room, an exit, a character and so on.</p></li>
<li><p>Building menus are arranged in layers of choices. A choice gives access to an option or to a sub-
menu. Choices are linked to commands (usually very short). For instance, in the example shown
below, to edit the room key, after opening the building menu, you can type <codeclass="docutils literal notranslate"><spanclass="pre">k</span></code>. That will lead you
to the key choice where you can enter a new key for the room. Then you can enter <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code> to leave this
choice and go back to the entire menu. (All of this can be changed).</p></li>
<li><p>To open the menu, you will need something like a command. This contrib offers a basic command for
demonstration, but we will override it in this example, using the same code with more flexibility.</p></li>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"|rYou should provide an argument to this function: the object to edit.|n"</span><spanclass="p">)</span>
<li><p>It has a key <codeclass="docutils literal notranslate"><spanclass="pre">@edit</span></code> and a lock to only allow builders to use it.</p></li>
<li><p>In its <codeclass="docutils literal notranslate"><spanclass="pre">func</span></code> method, it begins by checking the arguments, returning an error if no argument is
specified.</p></li>
<li><p>It then searches for the given argument. We search globally. The <codeclass="docutils literal notranslate"><spanclass="pre">search</span></code> method used in this
way will return the found object or <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code>. It will also send the error message to the caller if
necessary.</p></li>
<li><p>Assuming we have found an object, we check the object <codeclass="docutils literal notranslate"><spanclass="pre">typename</span></code>. This will be used later when
we want to display several building menus. For the time being, we only handle <codeclass="docutils literal notranslate"><spanclass="pre">Room</span></code>. If the
caller specified something else, we’ll display an error.</p></li>
<li><p>Assuming this object is a <codeclass="docutils literal notranslate"><spanclass="pre">Room</span></code>, we have defined a <codeclass="docutils literal notranslate"><spanclass="pre">Menu</span></code> object containing the class of our
building menu. We build this class (creating an instance), giving it the caller and the object to
<p>The end might sound a bit surprising at first glance. But the process is still very simple: we
create an instance of our building menu and call its <codeclass="docutils literal notranslate"><spanclass="pre">open</span></code> method. Nothing more.</p>
<p>To add this command, edit <codeclass="docutils literal notranslate"><spanclass="pre">commands/default_cmdsets.py</span></code>. Import our command, adding an import line
<p>And in the class below (<codeclass="docutils literal notranslate"><spanclass="pre">CharacterCmdSet</span></code>), add the last line of this code:</p>
<p>So far, we can’t use our building menu. Our <codeclass="docutils literal notranslate"><spanclass="pre">@edit</span></code> command will throw an error. We have to define
the <codeclass="docutils literal notranslate"><spanclass="pre">RoomBuildingMenu</span></code> class. Open the <codeclass="docutils literal notranslate"><spanclass="pre">commands/building.py</span></code> file and add to the end of the file:</p>
<p>Save these changes, reload your game. You can now use the <codeclass="docutils literal notranslate"><spanclass="pre">@edit</span></code> command. Here’s what we get
(notice that the commands we enter into the game are prefixed with <codeclass="docutils literal notranslate"><spanclass="pre">></span></code>, though this prefix will
help, want to contribute, report issues or just join the community.
As Account #1 you can create a demo/tutorial area with @batchcommand tutorial_world.build.
</pre></div>
</div>
<p>Before diving into the code, let’s examine what we have:</p>
<ulclass="simple">
<li><p>When we use the <codeclass="docutils literal notranslate"><spanclass="pre">@edit</span><spanclass="pre">here</span></code> command, a building menu for this room appears.</p></li>
<li><p>Enter <codeclass="docutils literal notranslate"><spanclass="pre">k</span></code> to edit the room key. You will go into a choice where you can simply type the key
room key (the way we have done here). You can use <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code> to go back to the menu.</p></li>
<p>We then check, with the <codeclass="docutils literal notranslate"><spanclass="pre">look</span></code> command, that the menu has modified this room key. So by adding a
class, with a method and a single line of code within, we’ve added a menu with two choices.</p>
<li><p>We first create a class inheriting from <codeclass="docutils literal notranslate"><spanclass="pre">BuildingMenu</span></code>. This is usually the case when we want to
create a building menu with this contrib.</p></li>
<li><p>In this class, we override the <codeclass="docutils literal notranslate"><spanclass="pre">init</span></code> method, which is called when the menu opens.</p></li>
<li><p>In this <codeclass="docutils literal notranslate"><spanclass="pre">init</span></code> method, we call <codeclass="docutils literal notranslate"><spanclass="pre">add_choice</span></code>. This takes several arguments, but we’ve defined only
<li><p>The choice name. This is mandatory and will be used by the building menu to know how to
display this choice.</p></li>
<li><p>The command key to access this choice. We’ve given a simple <codeclass="docutils literal notranslate"><spanclass="pre">"k"</span></code>. Menu commands usually are
pretty short (that’s part of the reason building menus are appreciated by builders). You can also
specify additional aliases, but we’ll see that later.</p></li>
<li><p>We’ve added a keyword argument, <codeclass="docutils literal notranslate"><spanclass="pre">attr</span></code>. This tells the building menu that when we are in this
choice, the text we enter goes into this attribute name. It’s called <codeclass="docutils literal notranslate"><spanclass="pre">attr</span></code>, but it could be a room
attribute or a typeclass persistent or non-persistent attribute (we’ll see other examples as well).</p></li>
<div><p>We’ve added the menu choice for <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> here, why is another menu choice defined for <codeclass="docutils literal notranslate"><spanclass="pre">quit</span></code>?</p>
<p>In the previous example, we’ve used <codeclass="docutils literal notranslate"><spanclass="pre">add_choice</span></code>. This is one of three methods you can use to add
choices. The other two are to handle more generic actions:</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">add_choice_edit</span></code>: this is called to add a choice which points to the <codeclass="docutils literal notranslate"><spanclass="pre">EvEditor</span></code>. It is used to
edit a description in most cases, although you could edit other things. We’ll see an example
shortly. <codeclass="docutils literal notranslate"><spanclass="pre">add_choice_edit</span></code> uses most of the <codeclass="docutils literal notranslate"><spanclass="pre">add_choice</span></code> keyword arguments we’ll see, but usually
<li><p>Optionally, the attribute of the object to edit, with the <codeclass="docutils literal notranslate"><spanclass="pre">attr</span></code> keyword argument. By
default, <codeclass="docutils literal notranslate"><spanclass="pre">attr</span></code> contains <codeclass="docutils literal notranslate"><spanclass="pre">db.desc</span></code>. It means that this persistent data attribute will be edited by
the <codeclass="docutils literal notranslate"><spanclass="pre">EvEditor</span></code>. You can change that to whatever you want though.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">add_choice_quit</span></code>: this allows to add a choice to quit the editor. Most advisable! If you don’t
do it, the building menu will do it automatically, except if you really tell it not to. Again, you
can specify the title and key of this menu. You can also call a function when this menu closes.</p></li>
<p>So here’s a more complete example (you can replace your <codeclass="docutils literal notranslate"><spanclass="pre">RoomBuildingMenu</span></code> class in
<codeclass="docutils literal notranslate"><spanclass="pre">commands/building.py</span></code> to see it):</p>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">add_choice_quit</span><spanclass="p">(</span><spanclass="s2">"quit this editor"</span><spanclass="p">,</span><spanclass="s2">"q"</span><spanclass="p">)</span>
<p>So far, our building menu class is still thin… and yet we already have some interesting feature.
See for yourself the following MUD client output (again, the commands are prefixed with <codeclass="docutils literal notranslate"><spanclass="pre">></span></code> to
<p>So by using the <codeclass="docutils literal notranslate"><spanclass="pre">d</span></code> shortcut in our building menu, an <codeclass="docutils literal notranslate"><spanclass="pre">EvEditor</span></code> opens. You can use the <codeclass="docutils literal notranslate"><spanclass="pre">EvEditor</span></code>
commands (like we did here, <codeclass="docutils literal notranslate"><spanclass="pre">:DD</span></code> to remove all, <codeclass="docutils literal notranslate"><spanclass="pre">:wq</span></code> to save and quit). When you quit the editor,
the description is saved (here, in <codeclass="docutils literal notranslate"><spanclass="pre">room.db.desc</span></code>) and you go back to the building menu.</p>
<p>Notice that the choice to quit has changed too, which is due to our adding <codeclass="docutils literal notranslate"><spanclass="pre">add_choice_quit</span></code>. In
most cases, you will probably not use this method, since the quit menu is added automatically.</p>
<h3><codeclass="docutils literal notranslate"><spanclass="pre">add_choice</span></code> options<aclass="headerlink"href="#add-choice-options"title="Permalink to this headline">¶</a></h3>
<p><codeclass="docutils literal notranslate"><spanclass="pre">add_choice</span></code> and the two methods <codeclass="docutils literal notranslate"><spanclass="pre">add_choice_edit</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">add_choice_quit</span></code> take a lot of optional
arguments to make customization easier. Some of these options might not apply to <codeclass="docutils literal notranslate"><spanclass="pre">add_choice_edit</span></code>
or <codeclass="docutils literal notranslate"><spanclass="pre">add_choice_quit</span></code> however.</p>
<li><p>The first positional, mandatory argument is the choice title, as we have seen. This will
influence how the choice appears in the menu.</p></li>
<li><p>The second positional, mandatory argument is the command key to access to this menu. It is best
to use keyword arguments for the other arguments.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">aliases</span></code> keyword argument can contain a list of aliases that can be used to access to this
menu. For instance: <codeclass="docutils literal notranslate"><spanclass="pre">add_choice(...,</span><spanclass="pre">aliases=['t'])</span></code></p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">attr</span></code> keyword argument contains the attribute to edit when this choice is selected. It’s a
string, it has to be the name, from the object (specified in the menu constructor) to reach this
attribute. For instance, a <codeclass="docutils literal notranslate"><spanclass="pre">attr</span></code> of <codeclass="docutils literal notranslate"><spanclass="pre">"key"</span></code> will try to find <codeclass="docutils literal notranslate"><spanclass="pre">obj.key</span></code> to read and write the
attribute. You can specify more complex attribute names, for instance, <codeclass="docutils literal notranslate"><spanclass="pre">attr="db.desc"</span></code> to set the
<codeclass="docutils literal notranslate"><spanclass="pre">desc</span></code> persistent attribute, or <codeclass="docutils literal notranslate"><spanclass="pre">attr="ndb.something"</span></code> so use a non-persistent data attribute on the
object.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">text</span></code> keyword argument is used to change the text that will be displayed when the menu choice
is selected. Menu choices provide a default text that you can change. Since this is a long text,
it’s useful to use multi-line strings (see an example below).</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">glance</span></code> keyword argument is used to specify how to display the current information while in
the menu, when the choice hasn’t been opened. If you examine the previous examples, you will see
that the current (<codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">db.desc</span></code>) was shown in the menu, next to the command key. This is
useful for seeing at a glance the current value (hence the name). Again, menu choices will provide
a default glance if you don’t specify one.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">on_enter</span></code> keyword argument allows to add a callback to use when the menu choice is opened.
This is more advanced, but sometimes useful.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">on_nomatch</span></code> keyword argument is called when, once in the menu, the caller enters some text
that doesn’t match any command (including the <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code> command). By default, this will edit the
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">on_leave</span></code> keyword argument allows to specify a callback used when the caller leaves the menu
choice. This can be useful for cleanup as well.</p></li>
<p>These are a lot of possibilities, and most of the time you won’t need them all. Here is a short
example using some of these arguments (again, replace the <codeclass="docutils literal notranslate"><spanclass="pre">RoomBuildingMenu</span></code> class in
<codeclass="docutils literal notranslate"><spanclass="pre">commands/building.py</span></code> with the following code to see it working):</p>
<spanclass="s2"> Current title: |c{{obj.key}}|n</span>
<spanclass="s2">"""</span><spanclass="o">.</span><spanclass="n">format</span><spanclass="p">(</span><spanclass="n">back</span><spanclass="o">=</span><spanclass="s2">"|n or |y"</span><spanclass="o">.</span><spanclass="n">join</span><spanclass="p">(</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">keys_go_back</span><spanclass="p">)))</span>
<p>The most surprising part is no doubt the text. We use the multi-line syntax (with <codeclass="docutils literal notranslate"><spanclass="pre">"""</span></code>).
Excessive spaces will be removed from the left for each line automatically. We specify some
information between braces… sometimes using double braces. What might be a bit odd:</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">{back}</span></code> is a direct format argument we’ll use (see the <codeclass="docutils literal notranslate"><spanclass="pre">.format</span></code> specifiers).</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">{{obj...}}</span></code> refers to the object being edited. We use two braces, because <codeclass="docutils literal notranslate"><spanclass="pre">.format</span></code> will remove them.</p></li>
<p>In <codeclass="docutils literal notranslate"><spanclass="pre">glance</span></code>, we also use <codeclass="docutils literal notranslate"><spanclass="pre">{obj.key}</span></code> to indicate we want to show the room’s key.</p>
<p>The keyword arguments of <codeclass="docutils literal notranslate"><spanclass="pre">add_choice</span></code> are often strings (type <codeclass="docutils literal notranslate"><spanclass="pre">str</span></code>). But each of these arguments
can also be a function. This allows for a lot of customization, since we define the callbacks that
will be executed to achieve such and such an operation.</p>
<p>To demonstrate, we will try to add a new feature. Our building menu for rooms isn’t that bad, but
it would be great to be able to edit exits too. So we can add a new menu choice below
description… but how to actually edit exits? Exits are not just an attribute to set: exits are
objects (of type <codeclass="docutils literal notranslate"><spanclass="pre">Exit</span></code> by default) which stands between two rooms (object of type <codeclass="docutils literal notranslate"><spanclass="pre">Room</span></code>). So how
<p>So what we need is to display this list in our building menu… and to allow to edit it would be
great. Perhaps even add new exits?</p>
<p>First of all, let’s write a function to display the <codeclass="docutils literal notranslate"><spanclass="pre">glance</span></code> on existing exits. Here’s the code,
<spanclass="s2"> Current title: |c{{obj.key}}|n</span>
<spanclass="s2">"""</span><spanclass="o">.</span><spanclass="n">format</span><spanclass="p">(</span><spanclass="n">back</span><spanclass="o">=</span><spanclass="s2">"|n or |y"</span><spanclass="o">.</span><spanclass="n">join</span><spanclass="p">(</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">keys_go_back</span><spanclass="p">)))</span>
<p>When the building menu opens, it displays each choice to the caller. A choice is displayed with its
title (rendered a bit nicely to show the key as well) and the glance. In the case of the <codeclass="docutils literal notranslate"><spanclass="pre">exits</span></code>
choice, the glance is a function, so the building menu calls this function giving it the object
being edited (the room here). The function should return the text to see.</p>
<p>The function you give can accept a lot of different parameters. This allows for a flexible approach
but might seem complicated at first. Basically, your function can accept any parameter, and the
building menu will send only the parameter based on their names. If your function defines an
argument named <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code> for instance (like <codeclass="docutils literal notranslate"><spanclass="pre">def</span><spanclass="pre">func(caller):</span></code> ), then the building menu knows that
the first argument should contain the caller of the building menu. Here are the arguments, you
don’t have to specify them (if you do, they need to have the same name):</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">menu</span></code>: if your function defines an argument named <codeclass="docutils literal notranslate"><spanclass="pre">menu</span></code>, it will contain the building menu
itself.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">choice</span></code>: if your function defines an argument named <codeclass="docutils literal notranslate"><spanclass="pre">choice</span></code>, it will contain the <codeclass="docutils literal notranslate"><spanclass="pre">Choice</span></code> object
representing this menu choice.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">string</span></code>: if your function defines an argument named <codeclass="docutils literal notranslate"><spanclass="pre">string</span></code>, it will contain the user input to
reach this menu choice. This is not very useful, except on <codeclass="docutils literal notranslate"><spanclass="pre">nomatch</span></code> callbacks which we’ll see
later.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">obj</span></code>: if your function defines an argument named <codeclass="docutils literal notranslate"><spanclass="pre">obj</span></code>, it will contain the building menu edited
object.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code>: if your function defines an argument named <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code>, it will contain the caller of the
<p>The only argument we need is <codeclass="docutils literal notranslate"><spanclass="pre">room</span></code>. It’s not present in the list of possible arguments, so the
editing object of the building menu (the room, here) is given.</p>
<p>Most of the time, you will not need these arguments. In very rare cases, you will use them to get
specific data (like the default attribute that was set). This tutorial will not elaborate on these
possibilities. Just know that they exist.</p>
<p>We should also define a text callback, so that we can enter our menu to see the room exits. We’ll
see how to edit them in the next section but this is a good opportunity to show a more complete
callback. To see it in action, as usual, replace the class and functions in <codeclass="docutils literal notranslate"><spanclass="pre">commands/building.py</span></code>:</p>
<spanclass="s2"> Current title: |c{{obj.key}}|n</span>
<spanclass="s2">"""</span><spanclass="o">.</span><spanclass="n">format</span><spanclass="p">(</span><spanclass="n">back</span><spanclass="o">=</span><spanclass="s2">"|n or |y"</span><spanclass="o">.</span><spanclass="n">join</span><spanclass="p">(</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">keys_go_back</span><spanclass="p">)))</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">"</span><spanclass="se">\n</span><spanclass="s2"> Use |y@c|n to create a new exit."</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">"</span><spanclass="se">\n\n</span><spanclass="s2"> |gNo exit has yet been defined.|n"</span>
<p>So far, we’ve only used menu keys with one letter. We can add more, of course, but menu keys in
their simple shape are just command keys. Press “e” to go to the “exits” choice.</p>
<p>But menu keys can be nested. Nested keys allow to add choices with sub-menus. For instance, type
“e” to go to the “exits” choice, and then you can type “c” to open a menu to create a new exit, or
“d” to open a menu to delete an exit. The first menu would have the “e.c” key (first e, then c),
the second menu would have key as “e.d”.</p>
<p>That’s more advanced and, if the following code doesn’t sound very friendly to you, try the next
section which provides a different approach of the same problem.</p>
<p>So we would like to edit exits. That is, you can type “e” to go into the choice of exits, then
enter <codeclass="docutils literal notranslate"><spanclass="pre">@e</span></code> followed by the exit name to edit it… which will open another menu. In this sub-menu
<spanclass="s2"> Current title: |c{{obj.key}}|n</span>
<spanclass="s2">"""</span><spanclass="o">.</span><spanclass="n">format</span><spanclass="p">(</span><spanclass="n">back</span><spanclass="o">=</span><spanclass="s2">"|n or |y"</span><spanclass="o">.</span><spanclass="n">join</span><spanclass="p">(</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">keys_go_back</span><spanclass="p">)))</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">"</span><spanclass="se">\n</span><spanclass="s2"> Use |y@c|n to create a new exit."</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">"</span><spanclass="se">\n\n</span><spanclass="s2"> |gNo exit has yet been defined.|n"</span>
<spanclass="n">caller</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"|rCannot find the exit.|n"</span><spanclass="p">)</span>
<li><p>The first thing new is in our menu class. After creating a <codeclass="docutils literal notranslate"><spanclass="pre">on_nomatch</span></code> callback for the exits
menu (that shouldn’t be a surprised), we need to add a nested key. We give this menu a key of
<codeclass="docutils literal notranslate"><spanclass="pre">"e.*"</span></code>. That’s a bit odd! “e” is our key to the exits menu, . is the separator to indicate a
nested menu, and * means anything. So basically, we create a nested menu that is contains within
the exits menu and anything. We’ll see what this “anything” is in practice.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">glance_exits</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">text_exits</span></code> are basically the same.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">nomatch_exits</span></code> is short but interesting. It’s called when we enter some text in the “exits”
menu (that is, in the list of exits). We have said that the user should enter <codeclass="docutils literal notranslate"><spanclass="pre">@e</span></code> followed by the
exit name to edit it. So in the <codeclass="docutils literal notranslate"><spanclass="pre">nomatch_exits</span></code> callbac, we check for that input. If the entered
text begins by <codeclass="docutils literal notranslate"><spanclass="pre">@e</span></code>, we try to find the exit in the room. If we do…</p></li>
<li><p>We call the <codeclass="docutils literal notranslate"><spanclass="pre">menu.move</span></code> method. That’s where things get a bit complicated with nested menus: we
need to use <codeclass="docutils literal notranslate"><spanclass="pre">menu.move</span></code> to change from layer to layer. Here, we are in the choice of exits (the
exits menu, of key “e”). We need to go down one layer to edit an exit. So we call <codeclass="docutils literal notranslate"><spanclass="pre">menu.move</span></code> and
give it an exit object. The menu system remembers what position the user is based on the keys she
has entered: when the user opens the menu, there is no key. If she selects the exits choice, the
menu key being “e”, the position of the user is <codeclass="docutils literal notranslate"><spanclass="pre">["e"]</span></code> (a list with the menu keys). If we call
<codeclass="docutils literal notranslate"><spanclass="pre">menu.move</span></code>, whatever we give to this method will be appended to the list of keys, so that the user
position becomes <codeclass="docutils literal notranslate"><spanclass="pre">["e",</span><spanclass="pre"><Exit</span><spanclass="pre">object>]</span></code>.</p></li>
<li><p>In the menu class, we have defined the menu “e.*”, meaning “the menu contained in the exits
choice plus anything”. The “anything” here is an exit: we have called <codeclass="docutils literal notranslate"><spanclass="pre">menu.move(exit)</span></code>, so the
<codeclass="docutils literal notranslate"><spanclass="pre">"e.*"</span></code> menu choice is chosen.</p></li>
<li><p>In this menu, the text is set to a callback. There is also a <codeclass="docutils literal notranslate"><spanclass="pre">on_nomatch</span></code> callback that is
called whenever the user enters some text. If so, we change the exit name.</p></li>
<p>Using <codeclass="docutils literal notranslate"><spanclass="pre">menu.move</span></code> like this is a bit confusing at first. Sometimes it’s useful. In this case, if
we want a more complex menu for exits, it makes sense to use a real sub-menu, not nested keys like
this. But sometimes, you will find yourself in a situation where you don’t need a full menu to
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># Still in commands/building.py, replace the menu class and functions by...</span>
<spanclass="s2"> Current title: |c{{obj.key}}|n</span>
<spanclass="s2">"""</span><spanclass="o">.</span><spanclass="n">format</span><spanclass="p">(</span><spanclass="n">back</span><spanclass="o">=</span><spanclass="s2">"|n or |y"</span><spanclass="o">.</span><spanclass="n">join</span><spanclass="p">(</span><spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">keys_go_back</span><spanclass="p">)))</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">"</span><spanclass="se">\n</span><spanclass="s2"> Use |y@c|n to create a new exit."</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">"</span><spanclass="se">\n\n</span><spanclass="s2"> |gNo exit has yet been defined.|n"</span>
<p>We have to call <codeclass="docutils literal notranslate"><spanclass="pre">open_submenu</span></code> on the menu object (which opens, as its name implies, a sub menu)
<li><p>The keys of the parent to open when the sub-menu closes. Basically, when we’re in the root of the
sub-menu and press <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code>, we’ll open the parent menu, with the parent keys. So we specify <codeclass="docutils literal notranslate"><spanclass="pre">["e"]</span></code>,
since the parent menus is the “exits” choice.</p></li>
<p>And that’s it. The new class will be automatically created. As you can see, we have to create a
<codeclass="docutils literal notranslate"><spanclass="pre">on_nomatch</span></code> callback to open the sub-menu, but once opened, it automatically close whenever needed.</p>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">keys_go_back</span></code> (default to <codeclass="docutils literal notranslate"><spanclass="pre">["@"]</span></code>): the keys to use to go back in the menu hierarchy, from choice
to root menu, from sub-menu to parent-menu. By default, only a <codeclass="docutils literal notranslate"><spanclass="pre">@</span></code> is used. You can change this
key for one menu or all of them. You can define multiple return commands if you want.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">sep_keys</span></code> (default <codeclass="docutils literal notranslate"><spanclass="pre">"."</span></code>): this is the separator for nested keys. There is no real need to
redefine it except if you really need the dot as a key, and need nested keys in your menu.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">joker_key</span></code> (default to <codeclass="docutils literal notranslate"><spanclass="pre">"*"</span></code>): used for nested keys to indicate “any key”. Again, you shouldn’t
need to change it unless you want to be able to use the @*@ in a command key, and also need nested
keys in your menu.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">min_shortcut</span></code> (default to <codeclass="docutils literal notranslate"><spanclass="pre">1</span></code>): although we didn’t see it here, one can create a menu choice
without giving it a key. If so, the menu system will try to “guess” the key. This option allows to
change the minimum length of any key for security reasons.</p></li>