At last. Usuing gadtools for menus while everything else is reaction is kind of strange. True menu class without restirictions of the sublevels, and co will be very welcome. And trixie is for sure right person to do this.
Does this project allow to RECORD menu activity and 'playback' ?
No it could not do that, and should not if it were possib;e, it simply a BOOPSI class to wrap menu creation. A nice idea assuming the end result is easier to use that the current system (which is not particularly difficult TBH).
Quote:
or is it a step towards dynamic menu creation and execution at runtime ?
Menus are always created at runtime, and you can easily create dynamically AWeb did it since the dawn of time, (and many other programs), hope fully this will make the process simpler.
At last. Usuing gadtools for menus while everything else is reaction is kind of strange.
yes, will be interested to see the resultant design.
Quote:
True menu class without restirictions of the sublevels, and co will be very welcome.
None of the 'restrictions' come from the gadtools interface they are the way intuition menus work, so trixe will have no influence over that and extending the actual menus is a job for the os devs.
Yes, five years after suggesting this project, I decided to develop it myself, how cool is that? But please hold your horses and do not set your expectations sky-high! I'd like to explain a few things before you all get too happy:
First, I won't be able to really start coding before late September. I'm still polishing the ADRipper update (due in a week or so), and then I'll work on my dissertation throughout the summer. I'll nevertheless think about various implementation ideas and solutions, also discussing them with people responsible for the Intuition/BOOPSI part of the OS.
This needs to be made clear right from the beginning: the project DOES NOT involve writing a replacement for the Intuition menu system! I am not capable of doing anything like this, really. The project is about writing a BOOPSI-encapsulating class for the existing menu system. (Yes, disappointing - we'll still only have one submenu level!) In other words: the project merely aims at putting menu programming on par with the other GUI tasks. Windows, requesters, gadgets and images have been programmed as objects for some time; menus now will be too. You'll never have to say "Gadtools" again.
I'm taking MUI as inspiration here (MUI does not implement its own menu system, either). For each type of menu element - the menustrip, the menu, the menu item - there will be a class. Creating a menu will, therefore, entail instantiating several hierarchically-arranged objects, like in this simple "Project" menu:
- Menustrip (an instance of menustrip.class) -- Menu ("Project": an instance of menu.class) --- Item ("New": an instance of menuitem.class) --- Item ("Open": an instance of menuitem.class) --- Item ("Save": an instance of menuitem.class) --- Item ("Quit": an instance of menuitem.class)
There will only be one physical disk-based class, the "menustrip.class". The other two subclasses will be part of the menustrip.class binary and will be opened automatically by their masterclass. The programmer will then instantiate from them via their public class name (just like you do it with page.gadget, which is part of the layout.gadget binary).
Changing menu/item properties, enabling/disabling and adding/removing items or entire menus will be a matter of course. All manipulation will be done via BOOPSI attributes and methods. I expect that Rigo will implement particular support in window.class so that the two classes are always in line and aware of their state, to avoid possible problems.
As the menu will in fact be a standard Intuition menu, input events from it will of course be sent to the window (class). So for the programmer, there will be no change in menu input handling. (There's really no point in menustrip.class implementing its own input handling method.) You'll be using WM_HANDLEINPUT as you did before.
Last but not least: BOOPSI encapsulation means abstraction. If one fine day the Intuition menu system does get rewritten, things will simply change in the class and programs will use the new system without the need for a rewrite.
I'm taking MUI as inspiration here (MUI does not implement its own menu system, either).
Actually it does but I think it's not on by default. But still, stick to your idea and don't try and code your own
I hope that you will be able to extract the pointer to the true menustrip in the same way as the window from the window.class, this will enable adding BOOPSI menus to plain intuition windows when required. (Though clearly manipulating the menustrip should be done by the owning class).
I hope that you will be able to extract the pointer to the true menustrip in the same way as the window from the window.class, this will enable adding BOOPSI menus to plain intuition windows when required.
Intuition menus will not be used in new applications, if there are better MUI and Reaction menus.
It's irrelevant. The menus are Intuition menus, they will not be getting replaced any time soon. Even GadTools menus are Intuition menus, just with an additional layer of abstraction that handles all the layouting, putting submenu arrows in the right places etc, and ensures a uniform look.
I imagine the menu class will be implemented using GadTools, rather than re-writing all the layouting directly on top of Intuiton, as that'll be a lot of work to replace (and it's something that GadTools does a fantastic job of).
Having played around with manual layouting using image classes fed into GadTools menus, I can appreciate the amount of fiddliness required to get it right (and I've not figured out yet how to emulate the usual menu highlighting).
I imagine the menu class will be implemented using GadTools, rather than re-writing all the layouting directly on top of Intuiton
Yes, that is exactly what I want to do. The Gadtools menu system works sufficiently well for Amiga software, and to be honest, I've never found the one-submenu-level limit too limiting. Especially with today's GUI design trends where complex and deep menus are on their way out.
@LiveForIt
Quote:
Intuition menus will not be used in new applications, if there are better MUI and Reaction menus.
Strictly speaking, there is no ReAction any more. What was historically known as the ReAction toolkit is now part of the Intuition/BOOPSI framework. I have changed the project name to reflect this (and updated the project description as well).
OK, but MUI, Gadtools and most other GUI systems is based on BOOPSI, so this can get a bit confusing. BOOPSI being the Struct Gadget, and low level stuff like that.
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
OK, but MUI, Gadtools and most other GUI systems is based on BOOPSI, so this can get a bit confusing. BOOPSI being the Struct Gadget, and low level stuff like that.
I'm not to sure about gadtools being BOOPIS, you don't use the intuition NewObject() and related family of fuctiond with it, I think it's a lower level wrapper to the base gadgets.
struct Gadget is certainly *not* BOOPSI, it far predates it and it's quite possible to write completely non boopsi based GUI based on struct Gadget and freinds. (though only if you like pain and torment!)
You're right, the AmigaOS GUI programming environment is a rather confusing mess :)
As broadblues says: Gadtools is not based on BOOPSI (it's not an object-oriented API). That's one of the main reasons why I took up this project - we use menus in object-oriented GUIs without the former being actually programmed as objects. It's not good to mix APIs like this, it only increases the learning curve and puts off new programmers.
(Speaking of BOOPSI: it's a rather common misconception that BOOPSI is only good for GUI programming. The scope of its possibilities is much broader. You can use it to design all sorts of object-oriented stuff for your software, to develop your own plugin system, etc.)
OK, after first experiments with the implementation one thing has become rather clear. Going the MUI way, i.e. having separate classes for each menu type (the strip, the menu, the item), is quite an overkill. The menustrip.class and the menu.class are virtually empty - they are there only to provide object-oriented access to them.
I guess this can be done in a more straightforward way. As the menu represents a hierarchy, I have taken inspiration from the Layout Gadget. Now, in my still-tentative design, there is only one class - the menu.class. Each object of this class can take children to form a hierarchy. The actual meaning of the object (i.e. whether it is a menu, a submenu, an item, an item in a submenu etc.) is decided by the class based on the position of the object in the hierarchy. So the very first menu object is interpreted as the menu strip, its first child is the first menu, etc. It's all rather easy and there is really no need for several class types.
The following code snippet will give you an idea. In order not to scare you off I've added some handy macros that make the example easier to follow:
/* ReAction-style macros to make this example more readable. */
#define MenuObject IIntuition->NewObject(MenuClass, NULL
#define End TAG_END)
menu[MID_STRIP] = MenuObject,
/* Project menu */
MENU_AddChild, menu[MID_PROJECT] = MenuObject,
MENU_Label, "Project",
/* "New" menu item */
MENU_AddChild, menu[MID_NEW] = MenuObject,
MENU_Label, "New",
MENU_CommKey, "n",
End,
/* "Open" menu item */
MENU_AddChild, menu[MID_OPEN] = MenuObject,
MENU_Label, "Open",
MENU_CommKey, "o",
End,
/* "Open Recent" submenu */
MENU_AddChild, menu[MID_RECENT] = MenuObject,
MENU_Label, "Open Recent",
MENU_AddChild, menu[MID_FIRST] = MenuObject,
MENU_Label, "First in the list of recent files",
End,
MENU_AddChild, menu[MID_SECOND] = MenuObject,
MENU_Label, "Second in the list of recent files",
/* Invalid submenu level. This item will be ignored by the class
until Intuition supports deeper menu hierarchies.*/
MENU_AddChild, menu[MID_INVALID] = MenuObject,
MENU_Label, "Why is everybody ignoring me, Doc?",
End,
End,
End,
/* "Quit" menu item */
MENU_AddChild, menu[MID_QUIT] = MenuObject,
MENU_Label, "Quit",
MENU_CommKey, "q",
End,
End,
End;
So each item in the menu is an object and can be accessed via BOOPSI methods. For example, it you wanted to remove the entire Project menu, you'd invoke a remove method over the menu[MID_PROJECT] object. If you wanted to disable the Open Recent submenu, you'd SetAttrs() the disable attribute for menu[MID_RECENT], etc.
Looking at that I can't see the menu structure as easily as looking at the equivalent Gadtools code.
Though that might be solved as simple as creating aliases for MENU_AddChild as in MENU_AddMenu MENU_AddSubMenu MENU_AddItem etc etc
Is an object deciding it's nature by it position in the heriachy not going to be bit of a headache coding wise?
What if someone detaches a menu object and tries to add it at a different point in the heirarchy ? Or has sets of menus ready to swap in and out depending on context (add a paint tool menu when the paint tool is active remove it and add a erase tools meneu etc etc) with your concept as I read it while detached the top of the heirarchy would be a strip then when attached to the strip it would suddenly become a Menu. Possible I'm sure but a lot interobject communication required.
What about specifying the type (default might be MENU_ITEM or what ever turns out to be most sensible)
Random feature thought, a menu object of type strip (however that is determined) could take an object od Window as an attribte then could handle attachment and removal transparently when methods modifying the menu are invoked.
Looking at that I can't see the menu structure as easily as looking at the equivalent Gadtools code. Though that might be solved as simple as creating aliases for MENU_AddChild as in MENU_AddMenu MENU_AddSubMenu MENU_AddItem etc etc
That certainly is a possibility, and the alias macros a likely solution.
Quote:
Is an object deciding it's nature by it position in the heriachy not going to be bit of a headache coding wise?
Frankly, I don't know yet. Dynamic layouts can easily prove me wrong once I start the actual implementation You can be sure that something like the MENU_Type attribute is on my backburner, if it proves that my idea isn't going to work and that the objects need specific identification.
Still it's good to have realized that we can do all of this inside one class and not three.
Quote:
a menu object of type strip (however that is determined) could take an object od Window as an attribte then could handle attachment and removal transparently when methods modifying the menu are invoked.
Window interaction will be crucial. I'll give it a very good thought.