Re: Responder chain query
Re: Responder chain query
- Subject: Re: Responder chain query
- From: email@hidden
- Date: Wed, 27 Nov 2013 13:22:12 +0000
On 21 Nov 2013, at 22:29, email@hidden wrote:
> Looking at the action responder chain for a document based app (fig 1-10):
> https://developer.apple.com/library/mac/documentation/cocoa/conceptual/eventoverview/EventArchitecture/EventArchitecture.html
>
> This shows that the action responder chain extends past the window controller up to the document controller.
>
> Sometimes I want to respond to an action and then forward it on up the responder chain like so:
> [self.nextResponder tryToPerform:selector with:sender];
>
> However, in this case the responder chain followed terminates at the window controller (as does the event message window controller).
> This means that higher level items like NSDocument etc are never queued as part of the chain search.
>
> Will I have to manually patch up the responder chain to include the higher level items when doing this sort of thing?
>
I guess the answer is yes.
The following has been included in https://github.com/mugginsoft/XSViewController
Jonathan
#import "NSResponder+XSViewController.h"
NSString *XSVChainTypeKey = @"ChainType";
@implementation NSResponder (XSViewController)
#pragma mark -
#pragma mark Event responder chain
- (NSArray *)xsv_eventResponderChain
{
return [self xsv_eventResponderChainFromResponder:nil];
}
- (NSArray *)xsv_eventResponderChainFromSelf
{
return [self xsv_eventResponderChainFromResponder:self];
}
- (NSArray *)xsv_eventResponderChainFromResponder:(NSResponder *)responder
{
return [self xsv_responderChainFromResponder:responder options:@{XSVChainTypeKey: @(XSVEventChainType)}];
}
#pragma mark -
#pragma mark Action responder chain
- (NSArray *)xsv_actionResponderChain
{
return [self xsv_actionResponderChainFromResponder:nil];
}
- (NSArray *)xsv_actionResponderChainFromSelf
{
return [self xsv_actionResponderChainFromResponder:self];
}
- (NSArray *)xsv_actionResponderChainFromResponder:(NSResponder *)responder
{
return [self xsv_responderChainFromResponder:responder options:@{XSVChainTypeKey: @(XSVActionChainType)}];
}
#pragma mark -
#pragma mark Responder chain construction
- (NSArray *)xsv_responderChainFromResponder:(id)initialResponder options:(NSDictionary *)options
{
// Chain should conform to description given here:
// https://developer.apple.com/library/mac/documentation/cocoa/conceptual/eventoverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW2
NSMutableArray *chain = [NSMutableArray arrayWithCapacity:10];
// If no initial responder then use the window first responder
if (!initialResponder) {
if (![self respondsToSelector:@selector(window)]) {
return chain;
}
NSWindow *window = [(id)self window];
initialResponder = [window firstResponder];
}
// This is going nowhere...
if (!initialResponder) {
return chain;
}
// Probe the accessible chain. By default this will be the event chain
NSResponder *responder = initialResponder;
do {
[chain addObject:responder];
} while ((responder = responder.nextResponder));
responder = [chain lastObject];
// Append action responder chain items
if ([options[XSVChainTypeKey] integerValue] == XSVActionChainType) {
// A window is required
if (![self respondsToSelector:@selector(window)]) {
return chain;
}
NSWindow *window = [(id)responder window];
if (!window) {
return chain;
}
// Append the top level action responder chain
NSArray *actionTopLevelChain = [self xsv_actionResponderChainAboveControllerForWindow:window];
[chain addObjectsFromArray:actionTopLevelChain];
}
return chain;
}
- (NSArray *)xsv_actionResponderChainAboveControllerForWindow:(NSWindow *)window
{
// Chain should conform to description given here:
// https://developer.apple.com/library/mac/documentation/cocoa/conceptual/eventoverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW2
id windowDelegate = [window delegate];
NSWindowController *windowController = [window windowController];
NSDocument *document = [windowController document];
id appDelegate = [NSApp delegate];
NSMutableArray *chain = [NSMutableArray arrayWithCapacity:5];
if (!window) {
return chain;
}
if (windowDelegate) {
[chain addObject:windowDelegate];
}
if (document) {
[chain addObject:document];
}
[chain addObject:NSApp];
if (appDelegate) {
[chain addObject:appDelegate];
}
if (document) {
[chain addObject:[NSDocumentController sharedDocumentController]];
}
return chain;
}
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden