all: I found the content of menu can be changed by pressing Shift key before clicking it. For example, if I don't press Shift key, the content of menu is for 2D imaging processing. But if I press Shift key, the content of menu is for 3D imaging processing. Does anyone know how to achieve this feature? Thanks in advance.
The basic idea is that one needs a periodically executed function that rebuilds a custom menu according to the current state of the shift key. In order not to block user interaction with the menu, it is important to make sure that this function runs on a background thread. The example script below provides a very simple illustration of how one might do this.
// $BACKGROUND$
class TwoStateMenu
{
Number savedShiftState;
Number menuChangeCount;
Object currentMenu;
void Action1(object self)
{
OKDialog("Action1 triggered");
}
void Action2(object self)
{
OKDialog("Action2 triggered");
}
void Action3(object self)
{
OKDialog("Action3 triggered");
}
void Action4(object self)
{
OKDialog("Action4 triggered");
}
void ConfigureMenu(Object self)
{
// Only update if shift state has changed
Number isShiftDown = ShiftDown();
if (savedShiftState != isShiftDown)
{
Object menuBar = GetMenuBar();
// Remove the previous menu, if any
if (currentMenu.ScriptObjectIsValid())
menuBar.RemoveMenuItem(currentMenu);
// Create the new menu, populate according to shift state
String menuName = "TwoState";
currentMenu = NewMenu(menuName);
currentMenu.SetIsEnabled(1);
if (isShiftDown)
{
Object shiftMenuItem1 = NewMenuItem("Shift Item 1");
shiftMenuItem1.SetAction(self, "Action3");
shiftMenuItem1.SetIsEnabled(1);
currentMenu.AddMenuItem(shiftMenuItem1);
Object shiftMenuItem2 = NewMenuItem("Shift Item 2");
shiftMenuItem2.SetAction(self, "Action4");
shiftMenuItem2.SetIsEnabled(1);
currentMenu.AddMenuItem(shiftMenuItem2);
}
else
{
Object defaultMenuItem1 = NewMenuItem("Item 1");
defaultMenuItem1.SetAction(self, "Action1");
defaultMenuItem1.SetIsEnabled(1);
currentMenu.AddMenuItem(defaultMenuItem1);
Object defaultMenuItem2 = NewMenuItem("Item 2");
defaultMenuItem2.SetAction(self, "Action2");
defaultMenuItem2.SetIsEnabled(1);
currentMenu.AddMenuItem(defaultMenuItem2);
}
// Update the menu bar
menuBar.AddMenu(currentMenu);
menuBar.RebuildMenuBar();
savedShiftState = isShiftDown;
menuChangeCount++;
}
}
Object Init(Object self)
{
savedShiftState = -1;
self.ConfigureMenu();
return self;
}
Number GetMenuChangeCount(Object self)
{
return menuChangeCount;
}
void ShutDownMenu(Object self)
{
Object menuBar = GetMenuBar();
menuBar.RemoveMenuItem(currentMenu);
menuBar.RebuildMenuBar();
}
}
void DoTwoStateMenu()
{
Object twoStateMenu = Alloc(TwoStateMenu).Init();
while (twoStateMenu.GetMenuChangeCount() < 10)
{
Sleep(0.5);
twoStateMenu.ConfigureMenu();
}
twoStateMenu.ShutDownMenu();
}
DoTwoStateMenu();
Note that in order to avoid permanently adding this TwoState menu to your current DM session, this example only tracks 10 changes in the menu content and then removes the menu. You will want to change this in a way that best suits your needs. Note also that this example tries not to be a CPU hog by putting itself to sleep for 0.5 seconds during each polling loop. This sleep time determines how quickly the menu will typically update in response to a change in the shift key state.