I want to add a menu item into the application's main menu that will be used quite rare. I want it to be hidden by default and show it only when user hold down Option key. How do i do this?
It seems that I should handle flagsChanged:
, but it is NSResponder
's method and NSMenu
does not inherits from NSResponder
? I tried it inside main window controller, and it works when I press Option key before I click on menu. The following use case doe not work: click on menu item (there is no item), press option key — my item should appear, release option key — item should disappear.
I've also tried NSEvent's addLocalMonitorForEventsMatchingMask:handler:
and addGlobalMonitorForEventsMatchingMask:handler:
for NSFlagsChangedMask
but when option key pressed while main menu is open neither local or global handlers are not fired.
How can I do this?
It's not possible to hide a menu in Win32, MFC is just a wrapper over this framework. You've got to remove this menu item when not needed and then insert it back at the same location using InsertMenu, have a look at MF_BYPOSITION and MF_BYCOMMAND.
The best way to hide all items in a menu with just one command is to use "group" on your menu xml. Just add all menu items that will be in your overflow menu inside the same group. Then, on your activity (preferable at onCreateOptionsMenu), use command setGroupVisible to set all menu items visibility to false or true.
The menu item that is not typically found in File menu is 'Copy'.
This example demonstrates how do I hide and show a menu item in the Android ActionBar. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main.xml. Step 3 − Add the following code to src/MainActivity.java
Choose Show or hide from the first drop-down box. It instructs the plugin to show/hide the chosen menu item if the following conditions are matched. Set your condition in the next box.
This tutorial will show you how to hide or show the app list in the Start menu for your account in Windows 10. This doesn't apply to full screen Start. 1 Open Settings, and click/tap on the Personalization icon. 3 When finished, you can close Settings if you like. They're still not getting it!
Hide WordPress Menu by User-Roles. Nav Menu Roles is another popular plugin to hide menu items based on user roles. So you can show some items to certain users only and hide the same from others as well. After installing, go to Menus to manage item visibility. Set Display mode for each item regardless of the reader’s role on the site.
There's some complex answers here but it's actually very simple:
Create 2 menuitems. The first is the default with whatever keyEquivalent and title you want. The second is what will be shown when the modifier key is down - again with separate keyEquivalent and title. On the second menuitem, enable 'Alternate' and everything else will happen automatically.
The required modifier is detected by comparing the 2 keyEquivalent values.
Add the following to applicationDidFinishLaunching.
// Dynamically update QCServer menu when option key is pressed
NSMenu *submenu = [[[NSApp mainMenu] itemWithTitle:@"QCServer"] submenu];
NSTimer *t = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(updateMenu:) userInfo:submenu repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:t forMode:NSEventTrackingRunLoopMode];
then add
- (void)updateMenu:(NSTimer *)t {
static NSMenuItem *menuItem = nil;
static BOOL isShowing = YES;
// Get global modifier key flag, [[NSApp currentEvent] modifierFlags] doesn't update while menus are down
CGEventRef event = CGEventCreate (NULL);
CGEventFlags flags = CGEventGetFlags (event);
BOOL optionKeyIsPressed = (flags & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate;
CFRelease(event);
NSMenu *menu = [t userInfo];
if (!menuItem) {
// View Batch Jobs...
menuItem = [menu itemAtIndex:6];
[menuItem retain];
}
if (!isShowing && optionKeyIsPressed) {
[menu insertItem:menuItem atIndex:6];
[menuItem setEnabled:YES];
isShowing = YES;
} else if (isShowing && !optionKeyIsPressed) {
[menu removeItem:menuItem];
isShowing = NO;
}
NSLog(@"optionKeyIsPressed %d", optionKeyIsPressed);
}
The timer only fires while controls are being tracked so it's not too much of a performance hit.
When constructing the menu include the optional item and mark it as hidden. Then set your class instance as the menu's delegate and add a run loop observer while the menu is open to control the optional item's hidden state.
@implementation AppController {
CFRunLoopObserverRef _menuObserver;
}
- (void)updateMenu {
BOOL hideOptionalMenuItems = ([NSEvent modifierFlags] & NSAlternateKeyMask) != NSAlternateKeyMask;
[self.optionalMenuItem setHidden:hideOptionalMenuItems];
}
- (void)menuWillOpen:(NSMenu *)menu {
[self updateMenu];
if (_menuObserver == NULL) {
_menuObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
[self updateMenu];
});
CFRunLoopAddObserver(CFRunLoopGetCurrent(), _menuObserver, kCFRunLoopCommonModes);
}
}
- (void)menuDidClose:(NSMenu *)menu {
if (_menuObserver != NULL) {
CFRunLoopObserverInvalidate(_menuObserver);
CFRelease(_menuObserver);
_menuObserver = NULL;
}
}
The best way you can achieve this is by using two menu items, the first menu item uses a custom view of height 0, and is disabled, then right under it is an "alternate" item. (You will have to set this item's keyEquivalentModifierMask
to NSAlternateKeyMask
) With this arrangement, when you press the option key, NSMenu will automatically replace the zero-height menu item with the alternate item which will have the effect of making a menu item magically appear.
No need for timers, updates or flag change notifications.
This functionality is described in the documentation here: Managing Alternates
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With