![]() |
API 0.9.5
|
00001 /* 00002 * CPResponder.j 00003 * AppKit 00004 * 00005 * Created by Francisco Tolmasky. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 00024 00025 CPDeleteKeyCode = 8; 00026 CPTabKeyCode = 9; 00027 CPReturnKeyCode = 13; 00028 CPEscapeKeyCode = 27; 00029 CPSpaceKeyCode = 32; 00030 CPPageUpKeyCode = 33; 00031 CPPageDownKeyCode = 34; 00032 CPLeftArrowKeyCode = 37; 00033 CPUpArrowKeyCode = 38; 00034 CPRightArrowKeyCode = 39; 00035 CPDownArrowKeyCode = 40; 00036 CPDeleteForwardKeyCode = 46; 00037 00044 @implementation CPResponder : CPObject 00045 { 00046 CPMenu _menu; 00047 CPResponder _nextResponder; 00048 } 00049 00050 // Changing the first responder 00054 - (BOOL)acceptsFirstResponder 00055 { 00056 return NO; 00057 } 00058 00064 - (BOOL)becomeFirstResponder 00065 { 00066 return YES; 00067 } 00068 00073 - (BOOL)resignFirstResponder 00074 { 00075 return YES; 00076 } 00077 00078 // Setting the next responder 00083 - (void)setNextResponder:(CPResponder)aResponder 00084 { 00085 _nextResponder = aResponder; 00086 } 00087 00091 - (CPResponder)nextResponder 00092 { 00093 return _nextResponder; 00094 } 00095 00100 - (void)interpretKeyEvents:(CPArray)events 00101 { 00102 var index = 0, 00103 count = [events count]; 00104 00105 for (; index < count; ++index) 00106 { 00107 var event = events[index], 00108 modifierFlags = [event modifierFlags], 00109 character = [event charactersIgnoringModifiers], 00110 selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags]; 00111 00112 if (selectorNames) 00113 { 00114 for (var s = 0, scount = selectorNames.length; s < scount; s++) 00115 { 00116 var selector = selectorNames[s]; 00117 if (!selector) 00118 continue; 00119 00120 [self doCommandBySelector:CPSelectorFromString(selector)]; 00121 } 00122 } 00123 else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)) && [self respondsToSelector:@selector(insertText:)]) 00124 [self insertText:[event characters]]; 00125 } 00126 } 00127 00132 - (void)mouseDown:(CPEvent)anEvent 00133 { 00134 [_nextResponder performSelector:_cmd withObject:anEvent]; 00135 } 00136 00141 - (void)rightMouseDown:(CPEvent)anEvent 00142 { 00143 [_nextResponder performSelector:_cmd withObject:anEvent]; 00144 } 00145 00151 - (void)mouseDragged:(CPEvent)anEvent 00152 { 00153 [_nextResponder performSelector:_cmd withObject:anEvent]; 00154 } 00155 00160 - (void)mouseUp:(CPEvent)anEvent 00161 { 00162 [_nextResponder performSelector:_cmd withObject:anEvent]; 00163 } 00164 00169 - (void)rightMouseUp:(CPEvent)anEvent 00170 { 00171 [_nextResponder performSelector:_cmd withObject:anEvent]; 00172 } 00173 00178 - (void)mouseMoved:(CPEvent)anEvent 00179 { 00180 [_nextResponder performSelector:_cmd withObject:anEvent]; 00181 } 00182 00183 - (void)mouseEntered:(CPEvent)anEvent 00184 { 00185 [_nextResponder performSelector:_cmd withObject:anEvent]; 00186 } 00187 00192 - (void)mouseExited:(CPEvent)anEvent 00193 { 00194 [_nextResponder performSelector:_cmd withObject:anEvent]; 00195 } 00196 00201 - (void)scrollWheel:(CPEvent)anEvent 00202 { 00203 [_nextResponder performSelector:_cmd withObject:anEvent]; 00204 } 00205 00210 - (void)keyDown:(CPEvent)anEvent 00211 { 00212 [_nextResponder performSelector:_cmd withObject:anEvent]; 00213 } 00214 00219 - (void)keyUp:(CPEvent)anEvent 00220 { 00221 [_nextResponder performSelector:_cmd withObject:anEvent]; 00222 } 00223 00228 - (void)flagsChanged:(CPEvent)anEvent 00229 { 00230 [_nextResponder performSelector:_cmd withObject:anEvent]; 00231 } 00232 00246 - (BOOL)performKeyEquivalent:(CPEvent)anEvent 00247 { 00248 return NO; 00249 } 00250 00251 // Action Methods 00256 - (void)insertLineBreak:(id)aSender 00257 { 00258 [self insertNewline:aSender]; 00259 } 00260 00265 - (void)insertNewline:(id)aSender 00266 { 00267 [[self nextResponder] insertNewline:aSender]; 00268 } 00269 00270 - (void)insertTab:(id)sender 00271 { 00272 } 00273 00274 - (void)insertBackTab:(id)sender 00275 { 00276 } 00277 00282 - (void)insertText:(CPString)aString 00283 { 00284 } 00285 00286 // Dispatch methods 00292 - (void)doCommandBySelector:(SEL)aSelector 00293 { 00294 if ([self respondsToSelector:aSelector]) 00295 [self performSelector:aSelector]; 00296 else 00297 [_nextResponder doCommandBySelector:aSelector]; 00298 } 00299 00307 - (BOOL)tryToPerform:(SEL)aSelector with:(id)anObject 00308 { 00309 if ([self respondsToSelector:aSelector]) 00310 { 00311 [self performSelector:aSelector withObject:anObject]; 00312 00313 return YES; 00314 } 00315 00316 return [_nextResponder tryToPerform:aSelector with:anObject]; 00317 } 00318 00319 // Managing a Responder's menu 00320 00321 - (void)setMenu:(CPMenu)aMenu 00322 { 00323 _menu = aMenu; 00324 } 00325 00326 - (CPMenu)menu 00327 { 00328 return _menu; 00329 } 00330 00331 // Getting the Undo Manager 00335 - (CPUndoManager)undoManager 00336 { 00337 return [_nextResponder performSelector:_cmd]; 00338 } 00339 00340 // Terminating the responder chain 00345 - (void)noResponderFor:(SEL)anEventSelector 00346 { 00347 } 00348 00349 @end 00350 00351 var CPResponderNextResponderKey = @"CPResponderNextResponderKey", 00352 CPResponderMenuKey = @"CPResponderMenuKey"; 00353 00354 @implementation CPResponder (CPCoding) 00355 00361 - (id)initWithCoder:(CPCoder)aCoder 00362 { 00363 self = [super init]; 00364 00365 if (self) 00366 { 00367 [self setNextResponder:[aCoder decodeObjectForKey:CPResponderNextResponderKey]]; 00368 [self setMenu:[aCoder decodeObjectForKey:CPResponderMenuKey]]; 00369 } 00370 00371 return self; 00372 } 00373 00378 - (void)encodeWithCoder:(CPCoder)aCoder 00379 { 00380 // This will come out nil on the other side with decodeObjectForKey: 00381 if (_nextResponder !== nil) 00382 [aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey]; 00383 00384 [aCoder encodeObject:_menu forKey:CPResponderMenuKey]; 00385 } 00386 00387 @end