Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 171 lines (135 sloc) 4.207 kB
dc5be1c Initial check-in.
uli authored
1 //
2 // UKFirstResponder.m
3 // Shovel
4 //
5 // Created by Uli Kusterer on 04.10.04.
720b0e7 @uliwitness Added licensing information to the source files.
authored
6 // Copyright 2004 Uli Kusterer.
7 //
8 // This software is provided 'as-is', without any express or implied
9 // warranty. In no event will the authors be held liable for any damages
10 // arising from the use of this software.
11 //
12 // Permission is granted to anyone to use this software for any purpose,
13 // including commercial applications, and to alter it and redistribute it
14 // freely, subject to the following restrictions:
15 //
16 // 1. The origin of this software must not be misrepresented; you must not
17 // claim that you wrote the original software. If you use this software
18 // in a product, an acknowledgment in the product documentation would be
19 // appreciated but is not required.
20 //
21 // 2. Altered source versions must be plainly marked as such, and must not be
22 // misrepresented as being the original software.
23 //
24 // 3. This notice may not be removed or altered from any source
25 // distribution.
dc5be1c Initial check-in.
uli authored
26 //
27
28 #import "UKFirstResponder.h"
29
30 @interface UKFirstResponder (PrivateMethods)
31
32 -(id) responderForAction: (SEL)itemAction;
33
34 @end
35
36 static UKFirstResponder* sFirstResponder = nil;
37
38
39 @implementation UKFirstResponder
40
41 +(id) firstResponder
42 {
43 if( !sFirstResponder )
44 sFirstResponder = [[[self class] alloc] init];
45
46 return sFirstResponder;
47 }
48
49
50 // This is a singleton:
51 +(id) init
52 {
53 if( !sFirstResponder )
54 {
55 self = [super init];
56 sFirstResponder = self;
57
58 return self;
59 }
60 else
61 {
62 [self autorelease];
63 return sFirstResponder;
64 }
65 }
66
67 // -----------------------------------------------------------------------------
68 // Finding out what messages the first responder understands/sending messages:
69 // -----------------------------------------------------------------------------
70
71 -(id) performSelector: (SEL)itemAction withObject: (id)obj
72 {
73 BOOL does = [super respondsToSelector: itemAction];
74 if( does )
75 return [super performSelector: itemAction withObject: obj];
76
77 id resp = [self responderForAction: itemAction];
78 if( !resp )
79 [self doesNotRecognizeSelector: itemAction];
80 return [resp performSelector: itemAction withObject: obj];
81 }
82
83 -(id) performSelector: (SEL)itemAction
84 {
85 BOOL does = [super respondsToSelector: itemAction];
86 if( does )
87 return [super performSelector: itemAction];
88
89 id resp = [self responderForAction: itemAction];
90 if( !resp )
91 [self doesNotRecognizeSelector: itemAction];
92 return [resp performSelector: itemAction];
93 }
94
95 -(BOOL) respondsToSelector: (SEL)itemAction
96 {
97 BOOL does = [super respondsToSelector: itemAction];
98
99 return( does || ([self responderForAction: itemAction] != nil) );
100 }
101
102
103 // -----------------------------------------------------------------------------
104 // Forwarding unknown methods to the first responder:
105 // -----------------------------------------------------------------------------
106
107 -(NSMethodSignature*) methodSignatureForSelector: (SEL)itemAction
108 {
109 NSMethodSignature* sig = [super methodSignatureForSelector: itemAction];
110 id friend = [self responderForAction: itemAction];
111
112 if( sig )
113 return sig;
114
115 if( friend )
116 return [friend methodSignatureForSelector: itemAction];
117
118 return nil;
119 }
120
121 -(void) forwardInvocation: (NSInvocation*)invocation
122 {
123 SEL itemAction = [invocation selector];
124 id friend = [self responderForAction: itemAction];
125
126 if( friend )
127 [invocation invokeWithTarget: friend];
128 else
129 [self doesNotRecognizeSelector: itemAction];
130 }
131
132 @end
133
134
135 @implementation UKFirstResponder (PrivateMethods)
136
137 -(id) responderForAction: (SEL)itemAction
138 {
139 NSResponder* resp = [[NSApp keyWindow] firstResponder];
140 id actualResponder = nil;
141
142 do
143 {
144 if( [resp respondsToSelector: itemAction] )
145 actualResponder = resp;
146 else if( [resp respondsToSelector: @selector(delegate)] )
147 {
148 id del = [(id)resp delegate];
149 if( [del respondsToSelector: itemAction] )
150 actualResponder = del;
151 }
152 }
153 while( !actualResponder && (resp = [resp nextResponder]) );
154
155 if( !actualResponder )
156 {
157 if( [NSApp respondsToSelector: itemAction] )
158 actualResponder = NSApp;
159 else
160 {
161 id del = [NSApp delegate];
162 if( [del respondsToSelector: itemAction] )
163 actualResponder = del;
164 }
165 }
166
167 return actualResponder;
168 }
169
170 @end
Something went wrong with that request. Please try again.