Выбор первого элемента в popUpContextMenu - PullRequest
2 голосов
/ 07 июля 2010

Я работаю над клавиатурным приложением.Обе руки на клавиатуре.Нет рук на мышь.

Пользователь может через клавиатуру открыть контекстное меню, выбрать элемент и, наконец, нажать Enter.

[NSMenu popUpContextMenu] отображает меню без выделения какого-либо элемента.Пользователь должен будет нажать arrow_down один раз, чтобы выделить первый элемент.

Мой друг заметил, что вам нужно нажимать arrow_down каждый раз, когда вы используете это меню, и предложил удалить этот шаг, чтобыпервый пункт всегда подсвечивается при всплывающем меню.

Я подозреваю, что для этого требуется углеродный взлом?

Как программно выделить первый элемент?


Я использую этот код для всплывающего меню.

NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined
    location:location 
    modifierFlags:0 
    timestamp:0
    windowNumber:[[self window] windowNumber]
    context:[[self window] graphicsContext]
    subtype:100
    data1:0
    data2:0
];
[NSMenu popUpContextMenu:menu withEvent:event forView:self];

обновление: я пытался отправить моему приложению событие arrow_down сразу после popUpContextMenu, однако событие не выполняетсякогда меню видно.(Событие выполняется после ухода из меню).

unichar code = NSDownArrowFunctionKey;
NSString* chars = [NSString stringWithFormat: @"%C", code];
NSEvent* event = [NSEvent keyEventWithType:NSKeyDown location:location modifierFlags:0 timestamp:0 windowNumber:[[self window] windowNumber] context:[[self window] graphicsContext] characters:chars charactersIgnoringModifiers:chars isARepeat:NO keyCode:code];
[NSApp sendEvent:event];

Ответы [ 2 ]

0 голосов
/ 07 ноября 2015

Для записи, если вы нацелены на 10.6 и более поздние версии, не используйте метод класса popUpContextMenu, используйте экземпляр popUpMenuPositioningItem:atLocation:inView:. Если вы укажете positioningItem, он будет выбран автоматически. Конечно, вам нужно будет пересчитать местоположение относительно выбранного элемента.

0 голосов
/ 08 июля 2010

Я нашел ответ на свой оригинальный вопрос.Однако у него есть проблемы, и я думаю _NSGetCarbonMenu() необходимо исправить их.

  1. ПРОБЛЕМА: как нарисовать элемент меню, чтобы он выглядел как собственный элемент меню?
  2. ПРОБЛЕМА: как заставить пользовательский вид вести себя как обычный пункт меню ... сейчас вам нужно нажать arrow_down два раза, чтобы выбрать следующий выбранный элемент.эти проблемы?
    @interface MyMenuItem : NSView {
        BOOL m_active;
    }
    @end
    
    @implementation MyMenuItem
    - (BOOL)acceptsFirstResponder { return YES; }
    - (BOOL)becomeFirstResponder { m_active = YES; return YES; }
    - (BOOL)resignFirstResponder { m_active = NO; return YES; }
    
    - (void)viewDidMoveToWindow { [[self window] makeFirstResponder:self]; }
    
    - (void)drawRect:(NSRect)rect {
        if(m_active) {
            [[NSColor blueColor] set];
        } else {
            [[NSColor blackColor] set];
        }
        NSRectFill(rect);
    }
    @end
    
    
    // this makes sure the first item gets selected when the menu popups
    MyMenuItem* view = [[[MyMenuItem alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)] autorelease];
    [view setAutoresizingMask:NSViewWidthSizable];
    NSMenuItem* item = [menu itemAtIndex:0];
    [item setView:view];
    [NSMenu popUpContextMenu:menu withEvent:event forView:self];
    

    РЕШЕНО ЭТО !!!Забудьте все вещи выше.Я только что нашел элегантное решение, которое совсем не требует углерода.

    // simulate a key press of the arrow-down key
    CGKeyCode key_code = 125;  // kVK_DownArrow = 125
    CGEventRef event1, event2;
    event1 = CGEventCreateKeyboardEvent(NULL, key_code, YES);
    event2 = CGEventCreateKeyboardEvent(NULL, key_code, NO);
    CGEventPost(kCGSessionEventTap, event1);
    CGEventPost(kCGSessionEventTap, event2);
    CFRelease(event1);
    CFRelease(event2);
    
    [NSMenu popUpContextMenu:menu withEvent:event forView:self];
    
...