On 18 Feb 2009, at 11:28 am, Walker Argendeli wrote:

You might remember how, in Xcode 2, the Build & Go button would perform its action, but if you clicked it and held for a few seconds, a menu would pop up with additional options. I'm trying to have something like that. I have a drop down button with its menu outlet connected to a custom menu with four items: the first is empty, with an image in it so that will show up as the icon for the toolbar. The other three are the other menu items. How would I make it act like a regular button (no dropdown) if it's clicked, but if it's held down for say, 2.5 seconds, the dropdown comes down. Thanks for your help!


I had to do this recently. I couldn't find any built-in support for this, I ended up having to write a custom NSButtonCell subclass. I overrode -startTrackingAt:inView: to kick off a timer for showing the menu, and popped up the menu in the timer callback. Getting the button to highlight properly when the menu was released proved tricky - I didn't solve that entirely satisfactorily, so if anyone can help out there I'd be very grateful.


hth,

--Graham




- (void)                setShowsMenuAfterDelay:(BOOL) showIt
{
        mShowMenuAfterDelay = showIt;
}


- (BOOL)                showsMenuAfterDelay
{
        return mShowMenuAfterDelay;
}



- (BOOL) startTrackingAt:(NSPoint) startPoint inView:(NSView*) controlView
{
// if there is a menu and show after delay is YES, start a timer for showing the menu
        
        if([self menu] && [self showsMenuAfterDelay] && mMenuTimer == nil)
        {
mMenuTimer = [[NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(menuDelayCallback:) userInfo:nil repeats:NO] retain];
                
[[NSRunLoop currentRunLoop] addTimer:mMenuTimer forMode:NSEventTrackingRunLoopMode]; [[NSRunLoop currentRunLoop] addTimer:mMenuTimer forMode:NSDefaultRunLoopMode];
                
                mMouseDownPoint = [controlView convertPoint:startPoint 
toView:nil];
        }
        
        return [super startTrackingAt:startPoint inView:controlView];
}



- (void)                menuDelayCallback:(NSTimer*) timer
{
#pragma unused(timer)
        // show the cell's menu
        
        if([self isHighlighted])
        {
                // pop up the menu and switch tracking to it.
                
                NSMenu* menu = [self menu];
                NSEvent* event = [NSApp currentEvent];
                
[NSMenu popUpContextMenu:menu withEvent:event forView:[self controlView]];

                NSWindow* window = [[self controlView] window];

// on return, post a mouse-up so that the cell tracking completes as normal. The mouse location // is faked to be in the middle of the cell to make sure it gets selected

                NSEvent* fakeMouseUp = [NSEvent mouseEventWithType:NSLeftMouseUp
                                                        location:mMouseDownPoint
                                                        modifierFlags:0
                                                        timestamp:[NSDate 
timeIntervalSinceReferenceDate]
                                                        windowNumber:[window 
windowNumber]
                                                        
context:[NSGraphicsContext currentContext]
                                                        eventNumber:0
                                                        clickCount:1
                                                        pressure:0.0];
                
                [window postEvent:fakeMouseUp atStart:YES];
                
                [(NSControl*)[self controlView] selectCell:self];
                [self setState:NSOnState];
        }
        
        [mMenuTimer release];
        mMenuTimer = nil;
}

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to