В основном я хочу создать эффект того, что есть в строке меню системы. Пользователь нажимает на один из заголовков меню, и при перемещении по разным заголовкам меню открываются автоматически.
Загвоздка в том, что если я открываю всплывающее меню для кнопки, пользователь должен щелкнуть еще раз, чтобы закрыть ее. Весь цикл выполнения приостановлен, поскольку я считаю, что всплывающее меню является модальным. Как мне получить возможность отправить [somePopUpMenu cancelTracking], когда пользователь переходит к следующей кнопке?
Вот код, который я сейчас пробую в своем подклассе NSWindow. Дело в том, что как только мышь выходит из кнопки, она автоматически щелкает (влево / вправо) на следующей кнопке, таймер становится недействительным и всплывающее меню закрывается.
Предполагая, что всплывающее меню открыто и мышь существует, запускаются события leftdown / leftup (я знаю, что это работает, поскольку я регистрирую их в NSLog для mouseDown и mouseUp), таймер недействителен, но всплывающее меню все еще отображается, и другая кнопка, на которую «нажали» фальшивые события, ничего не показывает. Кроме того, все это зацикливается, и по какой-то причине отправляются безумные mouseDown / mouseUp.
Стоит отметить, что всплывающее меню создается в другом объекте, хотя hookToMenu имеет правильную ссылку на него (я подтвердил через отладку / пошаговое выполнение).
Не знаю, работаю ли я с таймером отслеживания событий или делаю это неправильно. Я тоже пробовал это через оконный контроллер, но получил те же результаты.
Любая помощь по этому поводу будет оценена.
-(void)stopTimer
{
[timer invalidate];
[hookToMenu cancelTracking]; //hookToMenu is NSMenu*
}
-startFireDateTimer
{
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
timer = [[NSTimer alloc] initWithFireDate:nil interval:0 target:self selector:@selector(targetMethod) userInfo:nil repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSEventTrackingRunLoopMode];
[timer release];
}
-(void)targetMethod
{
NSEvent *newEvent;
newEvent=[NSApp nextEventMatchingMask:NSMouseExitedMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:NO];
if ([newEvent type]==NSMouseExited)
{
NSPoint mouseLoc;
mouseLoc=[newEvent locationInWindow];
int type=NSLeftMouseDown;
int type2=NSLeftMouseUp;
int windowNumber=[self windowNumber];
id fakeMouseUpEvent=[NSEvent mouseEventWithType:type
location:mouseLoc
modifierFlags:nil
timestamp:[NSDate timeIntervalSinceReferenceDate]
windowNumber:windowNumber
context:nil
eventNumber:nil
clickCount:1
pressure:1];
id fakeMouseUpEvent2=[NSEvent mouseEventWithType:type2
location:mouseLoc
modifierFlags:nil
timestamp:[NSDate timeIntervalSinceReferenceDate]
windowNumber:windowNumber
context:nil
eventNumber:nil
clickCount:1
pressure:1];
[NSApp sendEvent:fakeMouseUpEvent];
[NSApp sendEvent:fakeMouseUpEvent2];
[self stopTimer];
}
}
-(void)mouseDown:(NSEvent *)theEvent
{
[self startFireDateTimer];
NSLog(@"WINDOW: mouse down in window!");
[super mouseDown:theEvent];
}
-(void)mouseUp:(NSEvent *)theEvent
{
NSLog(@"WINDOW: mouse up in window!");
[super mouseUp:theEvent];
}
stopTimer
?NSLog(@"Menu: %p", hookToMenu);
- person Peter Hosey   schedule 27.03.2010