Dear all, I want to ask the community before I approach this task. I’ve read a lot and I’m still unsure how to approach this, so I want to lay down the task as clearly as I can.
Below is a screenshot of our App. It’s a set of tools for doctor’s and students alike.
THE TASK
We want to implement a top-level menu for each panel. As is, you access functions either directly from the interface (clicking icons / dragging dropping etc.) or by right-clicking, as seen below:
We want to make these menus accessible from the standard Windows / Mac menu., loading / showing the panels menu only when the panel is visible and hiding / removing it when panel is destroyed / not visible.
The panel itself is a container which is hosted by a custom TabBar control, and loaded dynamically in code.
The question: 1. How can I enable / disable / add / remove options from the menu from within the container.
*2. How can I catch the selected menu (created by the panel) and from WITHIN the panel.
I am unable to get menuhandlers working from within the container. Also, the app has a built-in notification system where any element can subscribe to various notifications, for example, a panel opening / closing, so it’s easy to create communications back and forth between the Main window and the container control, but… I am open to suggestions and guidance from the pros in this lovely forum.
Look into MenuItem.Tag. It’s a Variant object that can store an object reference, such as a reference to the container that it refers to. When the MenuItem is chosen, it can consult its Tag and send the container a message.
Eric’s idea is a good one. I would be slightly careful about circular references though. If the container contains a reference to the menu and the menu tags contain a reference to the container you could be setting yourself up for a memory leak.
There are two ways to deal with that. One is a weekRef, which will automatically go to Nil when the object it points to dies. The other way is to be very careful about filling the tags and clearing them after they are done with.
Here’s a basic implementation. I’ve made superclasses for your menus and your containers that coordinate the messaging necessary for the enabling/disabling of menu items.
Interestingly enough, it doesn’t use my original Tag suggestion. The new DesktopMenuItem class handles this a little differently and a customm class/property seemed a better approach.
And by adding menu handlers within the container, i am catching the events from the clicked menuitem (Would be nice if Xojo would show the list of available menuitems to the right when adding handlers, like it does when adding menuhandlers to windows).
Works like a charm, I’m off to implementation… Eric… you are the man of the day! Thank you!
Actually, this is totally related to my own project file
So,
I updated the demo to API 2 and it crashed. (got same error as in the screnshot).
However, I fixed the demo project by setting the MenuPanel1 and MenuPanel2 super to PanelMenu … even though it still said PanelMenu for both elements in the IDE…That made it work (Weird Xojo behaviour).
However, when copying the project to my project (see screenshot) I get the same error again.
And the error in question : I can refer to MenuPanel1 and MenuPanel2 in the Containers opening event, but when I run the project Xojo says they don’t exist. (I have set the parent of the containers to configPanel and super of menus to PanelMenu)…Copying the folder out of my project and into a new one → works.
This is driving me mad. I updated to Xojo 2004R2 but nothing changes, and during this process I noticed weird behaviour of the IDE.
For example : Right click on a menu item and you get the option “Update to API 2”, if you do that then the title of the menu “updated” is identcal (DesktopMenuItem) but the sidebar now doesn’t show the name of the element, instead everything is renamed to DesktopMenuItem
Weird behaviour : Xojo offers to change the item to DesktopMenuItem, but it already is:
All menu items have to be DesktopMenuItems, you cannot mix Menus and DesktopMenuItems, It has to be DesktopMenu and DesktopMenuItems. You cannot mix Window and DesktopMenus etc. For API2 keep everything Desktop (API2) style. Don’t try and mix and match them. For example: Don’t try and convert one MenuItem, do the whole menu.
I didn’t, try downloading the tiny demo above… simply copy it to a another instance of Xojo and run it again…and enjoy how Xojo messes it up, from A-Z.
Here is the tiny demo (which was working fine), copied to a new project and now it gives an error… can’t figure this out
Well no you didn’t. You may have tried to, but the best advice on this topic is to recreate the demo from scratch (DON’T try to modify it) using only API2 components.
You can use API1 and API2 together. However, in my experience, you cannot mix API1 menus with API2 menus. You cannot use API1 menus on an API2 window or vice versa.
Duplicate the API1 menu (completely) and then convert it to API2.
Convert an API1 window to API2 and then attach to the new API2 menu.
Other windows can remain API1 and use the existing API1 menu.