The Cafe ain't no Diner.... We need a simple menu
ChrisLaffra 060000KCEQ Comment (1) Visits (3290)
Many EGL Rich UI applications are migration targets from a legacy desktop application developed in VisualAge Generator, PowerBuilder, VisualBasic, or similar technologies. Personally, I think menus have no place in web2.0 applications. Just go find the menubar in gmail, or in Google Finance. They're not there. However, if you have to maintain superficial compatibility between the old application and the new one, and you really need a menu, EGL Rich UI comes with a powerful menu solution that lets you completely customize and style your menu.
Those of you who are already dabbling with menus will discover they are hard to use in the RBD. What is happening here is that our Text UI and Rich UI technologies are fighting over the same types being available for lookup. Namely, we automatically include the Text UI's Menu and MenuItem on the search path. This is for historical reasons. We are looking at IDE solutions to better separate the search paths, without ruining the lives of existing CUI programmers. For now, if you use menus in EGL Rich UI, simply write the import statements by hand. Ctrl-Shift-O, nor Ctrl-Space, will introduce the import statements automatically.
Anyway, back to the power of menus. With all the flexibility that comes with the menus, allowing you to attach behaviors, etc, a price is paid for ease of use. When Jon Sayles and I talked about his upcoming Rich UI training materials he is working on, he mentioned the need for a simpler menu. One with just text, and one event handler. One that is not so flexible perhaps, but one that works quickly.
What you will see below is a Menu implemented using our general solution, including defining a behavior to set styles and handle events. Rather than setting up the menu with MenuItems, and gobble together the entire menu, I tried to make the declaration as simple as possible, using just an array of String. It limits what the menu can do. It has no sub-menus, and no icons in the menu, and all menu item elements look the same. Imagine a virtual slider with on the left side ease of use and abstration, and on the right side full detail with maximum power. SimpleMenu sits way on the left. Our Rich UI menu solution sits way on the right. You may come up with a menu solution called IconNestedMenu that sits somewhere in the middle. I find that aspect of software design the most intriguing: where to put your solution on that imaginary slider.
To create a SimpleMenu, you say the following:
You specify one or more listeners, and introduce each menu (we add three menu in this sample). Each menu has a number of options that will be shown when the menu is activated. This is what the menu will look like:
The menubar is grey, and the menus are white. When the mouse is hovered over a menu title or menu item, the background turns to a shade of blue. We handle a few extra events to hide the menu automatically, and close existing menus when hovering to another one on the menubar.
When a menu item is selected, the SimpleMenu will trigger the listeners that have registered:
All styling for the menubar and the menu items is done in CSS, so you can control the look and feel easily. This is what the CSS looks like originally:
Changing the look and feel is easy. For instance, if you change the background color to the menu title and item to this:
you will get this result:
The implementation of SimpleMenu uses the existing Rich UI menu, adds a behavior to it, and converts our simplified list of menu item strings into instances of MenuItem and set up the menu.
When a SimpleMenu is created, we use the exsiting menu and set up a behavior:
The hightlightMenu behavior function is called by the Rich UI menu each time a menu is created and allows us to customize the menu as we see fit. In our case, we set up event handlers and styles on the menu as follows:
When we move the mouse around and enter a menu item, we want to show it and also close any menu item that is already open. The enterTitle function takes care of that:
The enterTitle function is called whenever the mouse enters a menu item. We now want to inform all the other menus to close themselves. To avoid us having to go back to the menubar and ask it to close the other menus for us, we use the InfoBus to generate an application level event that is broadcasted to all the other menus.
As a result, each menu will be informed when it should close itself. This is how numerous menus can talk to each other without needing a third party to help out in the communication.