Referencing an old post by Andrew Beckett, (Andrew if you could please clarify how to do this)
I am trying to build a menu which includes a menu item to re-load the menu.
The purpose is for adding new items and for testing and debugging code, without having to close Cadence and re-start.
Per Andrew's post, the Banner Menu should not be added in a Post Install Trigger (which appears to be the standard method), so I am loading it as (one of) a list of menus to add as a userMenuTrigger passed to RegUserTriggers.
I have not found a way to successfully do this. Cadence will not reload UserTriggers without deleting them first, and cannot delete selectively, so all get deleted and all have to be re-registered. What this means is that my "list" of menus has been expanded from the one custom menu, to include others not defined in the Menu.il file.
Another problem is that in order to re-load the modified menu in-session, I have to first delete it.
hiDeleteMenu() requires an argument of "r" type template, a defstruct which I can't locate. Defining the Menu does not return any value to the CIW, so I do not know what the argument is that needs to be passed to hiDeleteMenu().
I have tried modifying this code many times. Even when I do not get an Error message, the Menu does not get updated with the current code instructions.
Here is some sample code:
; define menu item(s)
Update = hiCreateMenuItem(
; define call procedure
) ; proc
; create pulldown menu
) ; fi
) ; list
) ; let
; trigger menu
if ( ( deGetAppInfo( "maskLayout" )->userMenuTrigger ) then
; this always returns true because MyMenu is not the only user Trigger Menu!!
; can the test case be more specific for MyMenu??
; this removes ALL user Trigger Menus
deRegUserTriggers("maskLayout" nil 'MyMenu)
deRegUserTriggers("maskLayout" nil 'MyMenu)
- James C.
Unregistering and re-registering the trigger won't help you here, because the issue is that you need to have something to re-trigger the event - otherwise it won't call your userMenuTrigger.
If you want to update the menus, I'd suggest having your callback redefine the menus, and then do:
deInstallApp(hiGetCurrentWindow() "Pcell") deInstallApp(hiGetCurrentWindow() "Layout")
This is like switching to the "Pcell" tool then back to Layout - and that will cause it to re-install the menu, using whatever is the latest definition of that menu.
I have tested the callback as the following: (I am no longer un-registering and re-registering, only registering User Triggers)
I get the same ERROR msgs about the Layout Menu trigger already being defined -
*ERROR* User menu trigger already registered for viewType maskLayout.
*ERROR* load: error while loading file - "MyMenu.il"
Thank you Andrew,
I got it to work in 2 different ways:
procedure( call_Update() isReg_MyMenu = t ; Menu is already registered if calling Update load("MyMenu.il") deInstallApp(hiGetCurrentWindow() "Pcell") deInstallApp(hiGetCurrentWindow() "Layout") ) ; proc
) ) ; end let, end proc
if( boundp('isReg_MyMenu) then printf( "Skill Script Menu previously defined and Menu Trigger registered.\n" ) printf( "Skill Script Menu Trigger does not need to be re-registered.\n" ) else deRegUserTriggers("maskLayout" nil 'MyMenu_Prog) ) ; fi
procedure( call_Update() isReg_MyMenu = t ; Menu is already registered if calling Update load("MyMenu.il") ) ; proc
if( !boundp( 'isReg_SkillScriptMenu ) then deRegUserTriggers("maskLayout" nil 'skill_PulldownMenu_Prog) else if( isReg_SkillScriptMenu == t then println("**** WARNING: ") println("**** Multiple loading may result in errors that require the user") println("**** to exit the application and re-invoke "); procedure( SetupSkillScriptMenuTrigger() prog( (prevAppTrigger prevMenuTrigger prevPostInstallTrigger viewtype appinfo ) if( !boundp('SkillScriptMenuViewType) then SkillScriptMenuViewType = list("maskLayout" "maskLayoutXL" "maskLayoutGXL") ) ; fi ; Get any existing trigger(s) foreach( viewtype SkillScriptMenuViewType when(appinfo=deGetAppInfo(viewtype) prevAppTrigger = get( appinfo 'userAppTrigger ) prevMenuTrigger = get( appinfo 'userMenuTrigger ) prevPostInstallTrigger = get( appinfo 'userPostInstallTrigger ) ; If there are previously defined menu triggers then unregister them. if( (prevAppTrigger!=nil) || (prevMenuTrigger!=nil) || (prevPostInstallTrigger!=nil) then deUnRegUserTriggers( viewtype ) ) ; fi ; Register the new trigger which will contain the old trigger, if any. deRegUserTriggers( viewtype prevAppTrigger prevMenuTrigger prevPostInstallTrigger ) ) ; when ) ; foreach ) ; prog ) ; proc ) ; fi) ; fi
Clearly, your suggestion is much simpler than saving the current Triggers, unregistering them, and re-registering them.
For anyone else who looks at this code and is confused about the variable names, I attempted to simplify my code as I typed or copied it in, replacing the program and menu names to read "...MyMenu..." - unfortunately I did not catch all of the needed replacements!
ie isReg_SkillScriptMenu ~= isReg_MyMenu
ie skill_PulldownMenu_Prog ~= MyMenu_Prog