X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/90f6792f530002cf3718b0ab0ce7727be1d21729..a4c721ee38d6e7656765a5188f89fe59c854058e:/src/cocoa/NSSlider.mm diff --git a/src/cocoa/NSSlider.mm b/src/cocoa/NSSlider.mm index 5ea545ba4c..3233c5a55a 100644 --- a/src/cocoa/NSSlider.mm +++ b/src/cocoa/NSSlider.mm @@ -24,120 +24,30 @@ WX_IMPLEMENT_OBJC_INTERFACE_HASHMAP(NSSlider) -// ============================================================================ -// @class wxNSSliderTarget -// ============================================================================ -@interface wxNSSliderTarget : NSObject +class wxCocoaNSSliderLastSelectorChanger { -} - -- (void)wxNSSliderUpArrowKeyDown: (id)sender; -- (void)wxNSSliderDownArrowKeyDown: (id)sender; -- (void)wxNSSliderLeftArrowKeyDown: (id)sender; -- (void)wxNSSliderRightArrowKeyDown: (id)sender; -- (void)wxNSSliderPageUpKeyDown: (id)sender; -- (void)wxNSSliderPageDownKeyDown: (id)sender; -- (void)wxNSSliderMoveUp: (id)sender; -- (void)wxNSSliderMoveDown: (id)sender; -- (void)wxNSSliderMoveLeft: (id)sender; -- (void)wxNSSliderMoveRight: (id)sender; -- (void)wxNSSliderPageUp: (id)sender; -- (void)wxNSSliderPageDown: (id)sender; -@end // wxNSSliderTarget - -@implementation wxNSSliderTarget : NSObject - -- (void)wxNSSliderUpArrowKeyDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderUpArrowKeyDown received without associated wx object")); - slider->Cocoa_wxNSSliderUpArrowKeyDown(); -} - -- (void)wxNSSliderDownArrowKeyDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderDownArrowKeyDown received without associated wx object")); - slider->Cocoa_wxNSSliderDownArrowKeyDown(); -} - -- (void)wxNSSliderLeftArrowKeyDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderLeftArrowKeyDown received without associated wx object")); - slider->Cocoa_wxNSSliderLeftArrowKeyDown(); -} - -- (void)wxNSSliderRightArrowKeyDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderRightArrowKeyDown received without associated wx object")); - slider->Cocoa_wxNSSliderRightArrowKeyDown(); -} - -- (void)wxNSSliderPageUpKeyDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderPageUpKeyDown received without associated wx object")); - slider->Cocoa_wxNSSliderPageUpKeyDown(); -} - -- (void)wxNSSliderPageDownKeyDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderPageDownKeyDown received without associated wx object")); - slider->Cocoa_wxNSSliderPageDownKeyDown(); -} - -- (void)wxNSSliderMoveUp: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderMoveUp received without associated wx object")); - slider->Cocoa_wxNSSliderMoveUp(); -} - -- (void)wxNSSliderMoveDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderMoveDown received without associated wx object")); - slider->Cocoa_wxNSSliderMoveDown(); -} - -- (void)wxNSSliderMoveLeft: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderMoveLeft received without associated wx object")); - slider->Cocoa_wxNSSliderMoveLeft(); -} - -- (void)wxNSSliderMoveRight: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderMoveRight received without associated wx object")); - slider->Cocoa_wxNSSliderMoveRight(); -} - -- (void)wxNSSliderPageUp: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderPageUp received without associated wx object")); - slider->Cocoa_wxNSSliderPageUp(); -} - -- (void)wxNSSliderPageDown: (id)sender -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(sender); - wxCHECK_RET(slider,wxT("wxNSSliderPageDown received without associated wx object")); - slider->Cocoa_wxNSSliderPageDown(); -} - -@end // implementation wxNSSliderTarget +public: + wxCocoaNSSliderLastSelectorChanger(SEL newSelector) + { + m_savedResponderSelector = wxCocoaNSSlider::sm_lastResponderSelector; + wxCocoaNSSlider::sm_lastResponderSelector = newSelector; + } + ~wxCocoaNSSliderLastSelectorChanger() + { + wxCocoaNSSlider::sm_lastResponderSelector = m_savedResponderSelector; + } +private: + SEL m_savedResponderSelector; +// Don't allow any default or copy construction + wxCocoaNSSliderLastSelectorChanger(); + wxCocoaNSSliderLastSelectorChanger(const wxCocoaNSSliderLastSelectorChanger&); + void operator=(const wxCocoaNSSliderLastSelectorChanger&); +}; // ============================================================================ // @class WXNSSlider // ============================================================================ - @implementation WXNSSlider : NSSlider // Override to ensure that WXNSSlider gets created with a WXNSSliderCell @@ -146,83 +56,53 @@ WX_IMPLEMENT_OBJC_INTERFACE_HASHMAP(NSSlider) return [WX_GET_OBJC_CLASS(WXNSSliderCell) class]; } +// The following methods are all NSResponder methods which NSSlider responds +// to in order to change its state and send the action message. We override +// them simply to record which one was called. This allows code listening +// only for the action message to determine what caused the action. +// Note that this is perfectly fine being a global because Cocoa processes +// events synchronously and only in the main thread. + - (void)keyDown:(NSEvent *)theEvent { - SEL originalAction = [self action]; - SEL newAction = originalAction; - NSString *theEventCharacters = [theEvent charactersIgnoringModifiers]; - - if ([theEventCharacters length] == 1) - { - switch ([theEventCharacters characterAtIndex:0]) - { - case NSUpArrowFunctionKey: newAction = @selector(wxNSSliderUpArrowKeyDown:); break; - case NSDownArrowFunctionKey: newAction = @selector(wxNSSliderDownArrowKeyDown:); break; - case NSLeftArrowFunctionKey: newAction = @selector(wxNSSliderLeftArrowKeyDown:); break; - case NSRightArrowFunctionKey: newAction = @selector(wxNSSliderRightArrowKeyDown:); break; - case NSPageUpFunctionKey: newAction = @selector(wxNSSliderPageUpKeyDown:); break; - case NSPageDownFunctionKey: newAction = @selector(wxNSSliderPageDownKeyDown:); break; - default: break; - } - } - - [self setAction:newAction]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super keyDown:theEvent]; - [self setAction:originalAction]; } - (void)moveUp:(id)sender { - SEL originalAction = [self action]; - - [self setAction:@selector(wxNSSliderMoveUp:)]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super moveUp:sender]; - [self setAction:originalAction]; } - (void)moveDown:(id)sender { - SEL originalAction = [self action]; - - [self setAction:@selector(wxNSSliderMoveDown:)]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super moveDown:sender]; - [self setAction:originalAction]; } - (void)moveLeft:(id)sender { - SEL originalAction = [self action]; - - [self setAction:@selector(wxNSSliderMoveLeft:)]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super moveLeft:sender]; - [self setAction:originalAction]; } - (void)moveRight:(id)sender { - SEL originalAction = [self action]; - - [self setAction:@selector(wxNSSliderMoveRight:)]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super moveRight:sender]; - [self setAction:originalAction]; } - (void)pageUp:(id)sender { - SEL originalAction = [self action]; - - [self setAction:@selector(wxNSSliderPageUp:)]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super pageUp:sender]; - [self setAction:originalAction]; } - (void)pageDown:(id)sender { - SEL originalAction = [self action]; - - [self setAction:@selector(wxNSSliderPageDown:)]; + wxCocoaNSSliderLastSelectorChanger savedSelector(_cmd); [super pageDown:sender]; - [self setAction:originalAction]; } @end @@ -232,87 +112,51 @@ WX_IMPLEMENT_GET_OBJC_CLASS(WXNSSlider,NSSlider) // @class WXNSSliderCell // ============================================================================ -#define kwxNSSliderStartTracking @"wxNSSliderStartTracking" -#define kwxNSSliderContinueTracking @"wxNSSliderContinueTracking" -#define kwxNSSliderStopTracking @"wxNSSliderStopTracking" - @implementation WXNSSliderCell : NSSliderCell - (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView { BOOL result = [super startTrackingAt:startPoint inView:controlView]; - [[NSNotificationCenter defaultCenter] postNotificationName:kwxNSSliderStartTracking object:controlView]; + + wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(controlView); + if(slider) + slider->CocoaNotification_startTracking(NULL); + return result; } - (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView { BOOL result = [super continueTracking:lastPoint at:currentPoint inView:controlView]; - [[NSNotificationCenter defaultCenter] postNotificationName:kwxNSSliderContinueTracking object:controlView]; + + wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(controlView); + if(slider) + slider->CocoaNotification_continueTracking(NULL); + return result; } - (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag { [super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag]; - [[NSNotificationCenter defaultCenter] postNotificationName:kwxNSSliderStopTracking object:controlView]; + + wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa(controlView); + if(slider) + slider->CocoaNotification_stopTracking(NULL); } @end WX_IMPLEMENT_GET_OBJC_CLASS(WXNSSliderCell,NSSliderCell) -// ============================================================================ -// @class wxNSSliderNotificationObserver -// ============================================================================ -@interface wxNSSliderNotificationObserver : NSObject -{ -} - -struct objc_object *wxCocoaNSSlider::sm_cocoaObserver = [[wxNSSliderNotificationObserver alloc] init]; - -- (void)startTracking: (NSNotification *)notification; -- (void)continueTracking: (NSNotification *)notification; -- (void)stopTracking: (NSNotification *)notification; -@end // interface wxNSSliderNotificationObserver - -@implementation wxNSSliderNotificationObserver : NSObject - -- (void)startTracking: (NSNotification *)notification; -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa([notification object]); - wxCHECK_RET(slider,wxT("startTracking received but no wxSlider exists")); - slider->CocoaNotification_startTracking(notification); -} - -- (void)continueTracking: (NSNotification *)notification; -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa([notification object]); - wxCHECK_RET(slider,wxT("continueTracking received but no wxSlider exists")); - slider->CocoaNotification_continueTracking(notification); -} - -- (void)stopTracking: (NSNotification *)notification; -{ - wxCocoaNSSlider *slider = wxCocoaNSSlider::GetFromCocoa([notification object]); - wxCHECK_RET(slider,wxT("stopTracking received but no wxSlider exists")); - slider->CocoaNotification_stopTracking(notification); -} - -@end // implementation wxNSSliderNotificationObserver - // ============================================================================ // class wxCocoaNSSlider // ============================================================================ -const wxObjcAutoRefFromAlloc wxCocoaNSSlider::sm_cocoaTarget = [[wxNSSliderTarget alloc] init]; +SEL wxCocoaNSSlider::sm_lastResponderSelector; void wxCocoaNSSlider::AssociateNSSlider(WX_NSSlider cocoaNSSlider) { if(cocoaNSSlider) { sm_cocoaHash.insert(wxCocoaNSSliderHash::value_type(cocoaNSSlider,this)); - [[NSNotificationCenter defaultCenter] addObserver:(id)sm_cocoaObserver selector:@selector(startTracking:) name:kwxNSSliderStartTracking object:cocoaNSSlider]; - [[NSNotificationCenter defaultCenter] addObserver:(id)sm_cocoaObserver selector:@selector(continueTracking:) name:kwxNSSliderContinueTracking object:cocoaNSSlider]; - [[NSNotificationCenter defaultCenter] addObserver:(id)sm_cocoaObserver selector:@selector(stopTracking:) name:kwxNSSliderStopTracking object:cocoaNSSlider]; - [cocoaNSSlider setTarget:sm_cocoaTarget]; } } @@ -321,8 +165,5 @@ void wxCocoaNSSlider::DisassociateNSSlider(WX_NSSlider cocoaNSSlider) if(cocoaNSSlider) { sm_cocoaHash.erase(cocoaNSSlider); - [[NSNotificationCenter defaultCenter] removeObserver:(id)sm_cocoaObserver name:kwxNSSliderStartTracking object:cocoaNSSlider]; - [[NSNotificationCenter defaultCenter] removeObserver:(id)sm_cocoaObserver name:kwxNSSliderContinueTracking object:cocoaNSSlider]; - [[NSNotificationCenter defaultCenter] removeObserver:(id)sm_cocoaObserver name:kwxNSSliderStopTracking object:cocoaNSSlider]; } }