lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Interesting discussion.

I have just a few comments.

First of all, Lua does not preserve order when inserting keys into a 
table. So:

  Menu =
  {
        ["New"] = SubMenu1,
        ["Load Game"] = ID_LOADGAME,
        ["Exit"] = ID_EXIT
  }

is probably not going to do what you want. You are very likely to find 
that it is displayed in some other order:

  +------------+
  |  Exit      |
  |  Load Game |
  |  New...    |
  +------------+

when you really wanted:

  +============+
  |Main:       |
  +============+
  |  New...    |
  |  Load Game |
  +------------+
  |  Exit      |
  +------------+

So I think you probably want to use a more complicated object than a 
simple table. It could, for example, be a pair of tables, one of which is 
as you have described, and the second of which is an ordered list of menu 
keys. (Of course, if you are planning on internationalizing, you might not 
want to use the menu text as a key, either. Or you might.)

This would motivate the creation of a Menu object, which implements the 
:add() method. You might then be able to write, for example:
  mainMenu = Menu.new "Main"
               :add("New", subMenu1)
               :add("Load Game", ID_LOADGAME,
               :add_separator
               :add("Exit", ID_EXIT)

Now, you actually could just include the sub-menu without giving it a 
name, using an interface like this:

  mainMenu = Menu.new "Main"
               :sub "New"
                    :add("New Campaign", ID_CAMPAIGN)
                    :add("New Random Map", ID_RANDOMMAP)
               .super
               :add("Load Game", ID_LOADGAME,
               .separator
               :add("Exit", ID_EXIT)


The call to :sub() automatically adds a Back link to the newly created 
submenu, which is then used by .super
to get back to the previous menu. This solves the problem expressed by 
Alex:

  > Well, the only thing I dislike about the solution below is that 
SubMenu1
  > is effectively split in two parts. If the Menu table is a page long it
  > would be easy to miss that <SubMenu1["Back"] = Menu> while browsing
  > through the file. What if there were 50 sub menus? All of them would
  > be split in at least (but not limited to) two parts and the file
  > can become a real mess with time.

But it doesn't address the question of what happens if a menu is a submenu 
of more than one parent menu, which is certainly a possibility in the 
general case.

eg:

    +==============+
    |Maze:         |
    +==============+
    |  Simplify    |
    |  Complicate  |
    |  New...      |\
    +--------------+ \
<---|  Back        +  \
    +--------------+   \
                        \
    +==============+     \   +============+
    |Character:    |      -> |From:       +
    +==============+     /   +============+
    |  Empower     |    /    |  CD        |
    |  Kill        |   /     |  Website   |
    |  New...      |>-/      |  File...   |
    +--------------+         +------------+
<---|  Back        +   ? <---|  Back      |
    +--------------+         +------------+

That is, the same "From" menu is used in both the Maze and Character 
menus.

This would suggest that Back entries should be added automatically when 
the submenu is presented, rather than when it is first created. A similar 
mechanism would allow addition of contextual information (Recent, for 
example).

------------------------------------

Since I've got a dental appointment in 15 minutes, I'll leave 
implementation of the
above interface as an exercise. Hints: 1) every method returns its self 
object,
except for :sub() which returns the new submenu. 2) .super and .separator 
are
implemented by the __index metamethod; the first one simply returns the 
back
link, and the second one modifies the object by adding the separator and 
then
returns the original object. You could avoid the mix of : and . by using .
throughout, and faking the method call by returning a closed function.

Rici


Anyway, rough outline code for the first implementation, where "Back" is 
added automatically.