API  0.9.7
 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 
25 @class CPKeyBinding
26 
27 CPDeleteKeyCode = 8;
28 CPTabKeyCode = 9;
29 CPReturnKeyCode = 13;
30 CPEscapeKeyCode = 27;
31 CPSpaceKeyCode = 32;
32 CPPageUpKeyCode = 33;
33 CPPageDownKeyCode = 34;
34 CPLeftArrowKeyCode = 37;
35 CPUpArrowKeyCode = 38;
36 CPRightArrowKeyCode = 39;
37 CPDownArrowKeyCode = 40;
38 CPDeleteForwardKeyCode = 46;
39 
46 @implementation CPResponder : CPObject
47 {
48  CPMenu _menu;
49  CPResponder _nextResponder;
50 }
51 
52 // Changing the first responder
56 - (BOOL)acceptsFirstResponder
57 {
58  return NO;
59 }
60 
66 - (BOOL)becomeFirstResponder
67 {
68  return YES;
69 }
70 
75 - (BOOL)resignFirstResponder
76 {
77  return YES;
78 }
79 
80 // Setting the next responder
85 - (void)setNextResponder:(CPResponder)aResponder
86 {
87  _nextResponder = aResponder;
88 }
89 
93 - (CPResponder)nextResponder
94 {
95  return _nextResponder;
96 }
97 
102 - (void)interpretKeyEvents:(CPArray)events
103 {
104  var index = 0,
105  count = [events count];
106 
107  for (; index < count; ++index)
108  {
109  var event = events[index],
110  modifierFlags = [event modifierFlags],
111  character = [event charactersIgnoringModifiers],
112  selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags];
113 
114  if (selectorNames)
115  {
116  for (var s = 0, scount = selectorNames.length; s < scount; s++)
117  {
118  var selector = selectorNames[s];
119  if (!selector)
120  continue;
121 
122  [self doCommandBySelector:CPSelectorFromString(selector)];
123  }
124  }
125  else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)) && [self respondsToSelector:@selector(insertText:)])
126  [self insertText:[event characters]];
127  }
128 }
129 
134 - (void)mouseDown:(CPEvent)anEvent
135 {
136  [_nextResponder performSelector:_cmd withObject:anEvent];
137 }
138 
143 - (void)rightMouseDown:(CPEvent)anEvent
144 {
145  [_nextResponder performSelector:_cmd withObject:anEvent];
146 }
147 
153 - (void)mouseDragged:(CPEvent)anEvent
154 {
155  [_nextResponder performSelector:_cmd withObject:anEvent];
156 }
157 
162 - (void)mouseUp:(CPEvent)anEvent
163 {
164  [_nextResponder performSelector:_cmd withObject:anEvent];
165 }
166 
171 - (void)rightMouseUp:(CPEvent)anEvent
172 {
173  [_nextResponder performSelector:_cmd withObject:anEvent];
174 }
175 
180 - (void)mouseMoved:(CPEvent)anEvent
181 {
182  [_nextResponder performSelector:_cmd withObject:anEvent];
183 }
184 
185 - (void)mouseEntered:(CPEvent)anEvent
186 {
187  [_nextResponder performSelector:_cmd withObject:anEvent];
188 }
189 
194 - (void)mouseExited:(CPEvent)anEvent
195 {
196  [_nextResponder performSelector:_cmd withObject:anEvent];
197 }
198 
203 - (void)scrollWheel:(CPEvent)anEvent
204 {
205  [_nextResponder performSelector:_cmd withObject:anEvent];
206 }
207 
212 - (void)keyDown:(CPEvent)anEvent
213 {
214  [_nextResponder performSelector:_cmd withObject:anEvent];
215 }
216 
221 - (void)keyUp:(CPEvent)anEvent
222 {
223  [_nextResponder performSelector:_cmd withObject:anEvent];
224 }
225 
230 - (void)flagsChanged:(CPEvent)anEvent
231 {
232  [_nextResponder performSelector:_cmd withObject:anEvent];
233 }
234 
248 - (BOOL)performKeyEquivalent:(CPEvent)anEvent
249 {
250  return NO;
251 }
252 
253 // Action Methods
258 - (void)insertLineBreak:(id)aSender
259 {
260  [self insertNewline:aSender];
261 }
262 
267 - (void)insertNewline:(id)aSender
268 {
269  [[self nextResponder] insertNewline:aSender];
270 }
271 
272 - (void)insertTab:(id)sender
273 {
274 }
275 
276 - (void)insertBackTab:(id)sender
277 {
278 }
279 
284 - (void)insertText:(CPString)aString
285 {
286 }
287 
288 // Dispatch methods
294 - (void)doCommandBySelector:(SEL)aSelector
295 {
296  if ([self respondsToSelector:aSelector])
297  [self performSelector:aSelector];
298  else
299  [_nextResponder doCommandBySelector:aSelector];
300 }
301 
309 - (BOOL)tryToPerform:(SEL)aSelector with:(id)anObject
310 {
311  if ([self respondsToSelector:aSelector])
312  {
313  [self performSelector:aSelector withObject:anObject];
314 
315  return YES;
316  }
317 
318  return [_nextResponder tryToPerform:aSelector with:anObject];
319 }
320 
321 // Managing a Responder's menu
322 
323 - (void)setMenu:(CPMenu)aMenu
324 {
325  _menu = aMenu;
326 }
327 
328 - (CPMenu)menu
329 {
330  return _menu;
331 }
332 
333 // Getting the Undo Manager
337 - (CPUndoManager)undoManager
338 {
339  return [_nextResponder performSelector:_cmd];
340 }
341 
342 // Terminating the responder chain
347 - (void)noResponderFor:(SEL)anEventSelector
348 {
349 }
350 
351 @end
352 
353 var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
354  CPResponderMenuKey = @"CPResponderMenuKey";
355 
356 @implementation CPResponder (CPCoding) <CPCoding>
357 
363 - (id)initWithCoder:(CPCoder)aCoder
364 {
365  self = [super init];
366 
367  if (self)
368  {
369  [self setNextResponder:[aCoder decodeObjectForKey:CPResponderNextResponderKey]];
370  [self setMenu:[aCoder decodeObjectForKey:CPResponderMenuKey]];
371  }
372 
373  return self;
374 }
375 
380 - (void)encodeWithCoder:(CPCoder)aCoder
381 {
382  // This will come out nil on the other side with decodeObjectForKey:
383  if (_nextResponder !== nil)
384  [aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey];
385 
386  [aCoder encodeObject:_menu forKey:CPResponderMenuKey];
387 }
388 
389 @end