-
Notifications
You must be signed in to change notification settings - Fork 19
Menus
This a future enhancement to Shoes if all the wrinkles can be smoothed.
This was never part of the original philosophy of Shoes or the design goals. However, it appears possible to get some minimal menus implemented. As anyone who has used osx and linux (or windows) knows, OSX is different. It has one menubar for all the windows in your application. If you think about it harder it becomes even more difficult to figure out how Shoes could emulate one model on the other system because there's more got-cha tricks in those competing models that you first appreciate.
Menus are totally optional - you have to ask for them.
If you need menus for your application and you want to be cross platform then you won't spawn new Shoes.apps or Windows and put menus on those sub windows/app. In other words you'll use the one menubar model. It's not that much of design constraint.
Shoes doesn't allow submenus (yet). We don't have icons in the menus (yet) or mnemonics (yet). We do have accelerators and separators.
Not everything that could be done has to be done.
Shoes defines things this way. These definitions(widgets) will differ from what you know in OSX and Gtk3 even though some names are shared.
The menubar is a horizontal strip of graphic real estate. In OSX it's on the top of the screen. In Linux and Windows it is a strip across the Window(s) The menubar has menus. In Shoes there will be a default menu already setup up. You should think three times before changing it and one of those rethinks will be done with OSX.
A menu is a vertical stripe of dropdown space. A menu contains menuitems. A menu has a title like "Help". The title is shown in the menubar. A menu also has a position in the menubar (0 that "Shoes" menu)
A menu contains menuitems.
A menuitem has a title, shown in the menu, an optional accelerator key like ^h and a Shoes block that will be called when the menuitem is selected.
Let add a Help menu to the menubar with an About menuitem and and a Cobbler menuitem
Shoes.app menus: true, width: 300, height: 200 do
mb = menubar
helpmenu = menu "Help"
@aboutitem = menuitem "About", key: "control_h" do
alert "This is a menu test", title: "About"
end
helpmenu << @aboutitem
cobbleritem = menuitem "Cobbler" do Shoes.cobbler end
helpmenu << cobbleritem
mb << helpmenu
end
We get the current menubar, there will be one. We don't know if were are running osx or linux or windows so this script doesn't know what's in the Shoes menu so we'll append the help menu to the menubar. But first we have to build the helpmenu object and then build all the menuitem objects and attach them to the menu. Then we can update the menubar.
That's it. In real life, that do..end block could to be tricky to write for your application. It's a lot like a Shoes button.
This should be in the manual but I'll rough it out here.
This gets the global menubar (OSX) or current menubar object for the Shoes 'app' window. Design your application so they are the same.
Returns a ruby array of menu objects.
Shoes does something fun here. [x] could be an integer like [1] or it could be a string like ["Help"]. If the string does exist in the menubar's menus titles or the integer is out of range then nil is returned. You might get an exception on the log window too.
Same as append.
Append the new menu object to the end of the menubar and two the menus array in the menubar object.
Returns nothing useful
Insert the menu object at pos position. If pos is a string, it will used to search thru the menus for a matching title. menus start at 0. Inserting at 1 will push 1...n-1 down (visually to the right). Only dare-devils would insert at 0.
Returns nothing useful.
Delete the menu at pos from the menubar. Pos maybe a integer or a String that matches a menu title.
A few more methods than menubar but there is pattern.
Creates a new menu object with the given title string. A new menu object has no menuitems attached. Returns the new menuitem object
Returns the string of the menu's title. Not particularly useful.
Returns the list (array) of menuitems contained in this menu object.
Returns the menuitem at position [x]. X maybe an integer [3] or a string ["About"] matching the title of the first menuitem contained in the menu.
Returns the index of the menuitem title that matches the string Like all ruby array indices, it start with 0.
see append
Adds the menuitem to the end of the list (array) of menuitems contained in the menu. Visually, this the bottom of drop down column.
Inserts the new menuitem at pos, pushing anything at or beyond pos down. pos may be an integer or a String that matches a menuitem title. If pos is less that 0 (or nonexistent) it behaves as append.
Delete the menuitem at pos from the menu's list. pos may be an integer or a string. If a string it will delete the first matching menuitem with a matching title.
Creates a new menuitem with the given title string (shown in the containing menu drop down list); A hash of {:key "string"} is optional. The block argument is also optional. Like Button widgets, the syntax for a menuitem block is a bit odd. The block will be called it the menuitem is selected by the user.
NOTE: If the title starts with 3 hyphens "---" the menuitem will display as a separator and can not be selected or trigger a call to a block.
The optional :key => string hash (or key: string) requires the string to be in a certain form: For example "control_h" will be converted to ^H on Linux/Windows and that apple-fan-h on OSX. 'shift_control_x' would be shift control X (shift_apple_X).
Caution: alt_, and alt_shift_control_ and variants like control_alt_ may work for some people, sometimes. Rule of thumb: Don't use alt if you care about other people.
Returns the title string of the menuitem
Changes the menuitem title to string
By default all menuitems except the "---" separators are enabled: They can be selected and the associated block will trigger. You can disable with a menuitem.enable = false
and re-enable with menuitem.enable = true
You can replace (or set) a block on a menu item. This example might help.
Shoes.app menus: true, width: 300, height: 200 do
mb = menubar
helpmenu = menu "Help"
@aboutitem = menuitem "About", key: "control_h" do
alert "This is a menu test", title: "About"
end
helpmenu << @aboutitem
cobbleritem = menuitem "Cobbler" do Shoes.cobbler end
helpmenu << cobbleritem
mb << helpmenu
button "change About" do
@aboutitem.title = "Info"
@aboutitem.block = proc {
if confirm "The block is changed, disable menuitem?"
@aboutitem.enable = false
end
}
end
end
Note that it demonstrates setting title and enable.