API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPResponder.j
Go to the documentation of this file.
1 /*
2  * CPResponder.j
3  * AppKit
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
37 
44 @implementation CPResponder : CPObject
45 {
46  CPMenu _menu;
47  CPResponder _nextResponder;
48 }
49 
50 // Changing the first responder
54 - (BOOL)acceptsFirstResponder
55 {
56  return NO;
57 }
58 
64 - (BOOL)becomeFirstResponder
65 {
66  return YES;
67 }
68 
73 - (BOOL)resignFirstResponder
74 {
75  return YES;
76 }
77 
78 // Setting the next responder
83 - (void)setNextResponder:(CPResponder)aResponder
84 {
85  _nextResponder = aResponder;
86 }
87 
91 - (CPResponder)nextResponder
92 {
93  return _nextResponder;
94 }
95 
100 - (void)interpretKeyEvents:(CPArray)events
101 {
102  var index = 0,
103  count = [events count];
104 
105  for (; index < count; ++index)
106  {
107  var event = events[index],
108  modifierFlags = [event modifierFlags],
109  character = [event charactersIgnoringModifiers],
110  selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags];
111 
112  if (selectorNames)
113  {
114  for (var s = 0, scount = selectorNames.length; s < scount; s++)
115  {
116  var selector = selectorNames[s];
117  if (!selector)
118  continue;
119 
120  [self doCommandBySelector:CPSelectorFromString(selector)];
121  }
122  }
123  else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)) && [self respondsToSelector:@selector(insertText:)])
124  [self insertText:[event characters]];
125  }
126 }
127 
132 - (void)mouseDown:(CPEvent)anEvent
133 {
134  [_nextResponder performSelector:_cmd withObject:anEvent];
135 }
136 
141 - (void)rightMouseDown:(CPEvent)anEvent
142 {
143  [_nextResponder performSelector:_cmd withObject:anEvent];
144 }
145 
151 - (void)mouseDragged:(CPEvent)anEvent
152 {
153  [_nextResponder performSelector:_cmd withObject:anEvent];
154 }
155 
160 - (void)mouseUp:(CPEvent)anEvent
161 {
162  [_nextResponder performSelector:_cmd withObject:anEvent];
163 }
164 
169 - (void)rightMouseUp:(CPEvent)anEvent
170 {
171  [_nextResponder performSelector:_cmd withObject:anEvent];
172 }
173 
178 - (void)mouseMoved:(CPEvent)anEvent
179 {
180  [_nextResponder performSelector:_cmd withObject:anEvent];
181 }
182 
183 - (void)mouseEntered:(CPEvent)anEvent
184 {
185  [_nextResponder performSelector:_cmd withObject:anEvent];
186 }
187 
192 - (void)mouseExited:(CPEvent)anEvent
193 {
194  [_nextResponder performSelector:_cmd withObject:anEvent];
195 }
196 
201 - (void)scrollWheel:(CPEvent)anEvent
202 {
203  [_nextResponder performSelector:_cmd withObject:anEvent];
204 }
205 
210 - (void)keyDown:(CPEvent)anEvent
211 {
212  [_nextResponder performSelector:_cmd withObject:anEvent];
213 }
214 
219 - (void)keyUp:(CPEvent)anEvent
220 {
221  [_nextResponder performSelector:_cmd withObject:anEvent];
222 }
223 
228 - (void)flagsChanged:(CPEvent)anEvent
229 {
230  [_nextResponder performSelector:_cmd withObject:anEvent];
231 }
232 
246 - (BOOL)performKeyEquivalent:(CPEvent)anEvent
247 {
248  return NO;
249 }
250 
251 // Action Methods
256 - (void)insertLineBreak:(id)aSender
257 {
258  [self insertNewline:aSender];
259 }
260 
265 - (void)insertNewline:(id)aSender
266 {
267  [[self nextResponder] insertNewline:aSender];
268 }
269 
270 - (void)insertTab:(id)sender
271 {
272 }
273 
274 - (void)insertBackTab:(id)sender
275 {
276 }
277 
282 - (void)insertText:(CPString)aString
283 {
284 }
285 
286 // Dispatch methods
292 - (void)doCommandBySelector:(SEL)aSelector
293 {
294  if ([self respondsToSelector:aSelector])
295  [self performSelector:aSelector];
296  else
297  [_nextResponder doCommandBySelector:aSelector];
298 }
299 
307 - (BOOL)tryToPerform:(SEL)aSelector with:(id)anObject
308 {
309  if ([self respondsToSelector:aSelector])
310  {
311  [self performSelector:aSelector withObject:anObject];
312 
313  return YES;
314  }
315 
316  return [_nextResponder tryToPerform:aSelector with:anObject];
317 }
318 
319 // Managing a Responder's menu
320 
321 - (void)setMenu:(CPMenu)aMenu
322 {
323  _menu = aMenu;
324 }
325 
327 {
328  return _menu;
329 }
330 
331 // Getting the Undo Manager
335 - (CPUndoManager)undoManager
336 {
337  return [_nextResponder performSelector:_cmd];
338 }
339 
340 // Terminating the responder chain
345 - (void)noResponderFor:(SEL)anEventSelector
346 {
347 }
348 
349 @end
350 
351 var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
352  CPResponderMenuKey = @"CPResponderMenuKey";
353 
354 @implementation CPResponder (CPCoding)
355 
361 - (id)initWithCoder:(CPCoder)aCoder
362 {
363  self = [super init];
364 
365  if (self)
366  {
367  [self setNextResponder:[aCoder decodeObjectForKey:CPResponderNextResponderKey]];
368  [self setMenu:[aCoder decodeObjectForKey:CPResponderMenuKey]];
369  }
370 
371  return self;
372 }
373 
378 - (void)encodeWithCoder:(CPCoder)aCoder
379 {
380  // This will come out nil on the other side with decodeObjectForKey:
381  if (_nextResponder !== nil)
382  [aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey];
383 
384  [aCoder encodeObject:_menu forKey:CPResponderMenuKey];
385 }
386 
387 @end