API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPKeyBinding.j
Go to the documentation of this file.
1 /*
2  * CPKeyBinding.j
3  * AppKit
4  *
5  * Created by Nicholas Small.
6  * Copyright 2010, 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 
27  @"@.": @"cancelOperation:",
28 
29  @"@a": @"selectAll:",
30  @"^a": @"moveToBeginningOfParagraph:",
31  @"^$a": @"moveToBeginningOfParagraphAndModifySelection:",
32  @"^b": @"moveBackward:",
33  @"^$b": @"moveBackwardAndModifySelection:",
34  @"^~b": @"moveWordBackward:",
35  @"^~$b": @"moveWordBackwardAndModifySelection:",
36  @"^d": @"deleteForward:",
37  @"^e": @"moveToEndOfParagraph:",
38  @"^$e": @"moveToEndOfParagraphAndModifySelection:",
39  @"^f": @"moveForward:",
40  @"^$f": @"moveForwardAndModifySelection:",
41  @"^~f": @"moveWordForward:",
42  @"^~$f": @"moveWordForwardAndModifySelection:",
43  @"^h": @"deleteBackward:",
44  @"^k": @"deleteToEndOfParagraph:",
45  @"^l": @"centerSelectionInVisibleArea:",
46  @"^n": @"moveDown:",
47  @"^$n": @"moveDownAndModifySelection:",
48  @"^o": [@"insertNewlineIgnoringFieldEditor:", @"moveBackward:"],
49  @"^p": @"moveUp:",
50  @"^$p": @"moveUpAndModifySelection:",
51  @"^t": @"transpose:",
52  @"^v": @"pageDown:",
53  @"^$v": @"pageDownAndModifySelection:",
54  @"^y": @"yank:"
55 };
56 
57 CPStandardKeyBindings[CPNewlineCharacter] = @"insertNewline:";
59 CPStandardKeyBindings[CPEnterCharacter] = @"insertNewline:";
60 CPStandardKeyBindings[@"~" + CPNewlineCharacter] = @"insertNewlineIgnoringFieldEditor:";
61 CPStandardKeyBindings[@"~" + CPCarriageReturnCharacter] = @"insertNewlineIgnoringFieldEditor:";
62 CPStandardKeyBindings[@"~" + CPEnterCharacter] = @"insertNewlineIgnoringFieldEditor:";
63 CPStandardKeyBindings[@"^" + CPNewlineCharacter] = @"insertLineBreak:";
64 CPStandardKeyBindings[@"^" + CPCarriageReturnCharacter] = @"insertLineBreak:";
65 CPStandardKeyBindings[@"^" + CPEnterCharacter] = @"insertLineBreak:";
66 
67 CPStandardKeyBindings[CPBackspaceCharacter] = @"deleteBackward:";
68 CPStandardKeyBindings[@"~" + CPBackspaceCharacter] = @"deleteWordBackward:";
69 CPStandardKeyBindings[CPDeleteCharacter] = @"deleteBackward:";
70 CPStandardKeyBindings[@"@" + CPDeleteCharacter] = @"deleteToBeginningOfLine:";
71 CPStandardKeyBindings[@"~" + CPDeleteCharacter] = @"deleteWordBackward:";
72 CPStandardKeyBindings[@"^" + CPDeleteCharacter] = @"deleteBackwardByDecomposingPreviousCharacter:";
73 CPStandardKeyBindings[@"^~" + CPDeleteCharacter] = @"deleteWordBackward:";
74 
75 CPStandardKeyBindings[CPDeleteFunctionKey] = @"deleteForward:";
76 CPStandardKeyBindings[@"~" + CPDeleteFunctionKey] = @"deleteWordForward:";
77 
78 CPStandardKeyBindings[CPTabCharacter] = @"insertTab:";
79 CPStandardKeyBindings[@"~" + CPTabCharacter] = @"insertTabIgnoringFieldEditor:";
80 CPStandardKeyBindings[@"^" + CPTabCharacter] = @"selectNextKeyView:";
81 CPStandardKeyBindings[CPBackTabCharacter] = @"insertBacktab:";
82 CPStandardKeyBindings[@"^" + CPBackTabCharacter] = @"selectPreviousKeyView:";
83 
84 CPStandardKeyBindings[CPEscapeFunctionKey] = @"cancelOperation:";
85 CPStandardKeyBindings[@"~" + CPEscapeFunctionKey] = @"complete:";
86 CPStandardKeyBindings[CPF5FunctionKey] = @"complete:";
87 
88 CPStandardKeyBindings[CPLeftArrowFunctionKey] = @"moveLeft:";
89 CPStandardKeyBindings[@"~" + CPLeftArrowFunctionKey] = @"moveWordLeft:";
90 CPStandardKeyBindings[@"^" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLine:";
91 CPStandardKeyBindings[@"@" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLine:";
92 CPStandardKeyBindings[@"$" + CPLeftArrowFunctionKey] = @"moveLeftAndModifySelection:";
93 CPStandardKeyBindings[@"$~" + CPLeftArrowFunctionKey] = @"moveWordLeftAndModifySelection:";
94 CPStandardKeyBindings[@"$^" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLineAndModifySelection:";
95 CPStandardKeyBindings[@"$@" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLineAndModifySelection:";
96 CPStandardKeyBindings[@"@^" + CPLeftArrowFunctionKey] = @"makeBaseWritingDirectionRightToLeft:";
97 CPStandardKeyBindings[@"@^~" + CPLeftArrowFunctionKey] = @"makeTextWritingDirectionRightToLeft:";
98 
99 CPStandardKeyBindings[CPRightArrowFunctionKey] = @"moveRight:";
100 CPStandardKeyBindings[@"~" + CPRightArrowFunctionKey] = @"moveWordRight:";
101 CPStandardKeyBindings[@"^" + CPRightArrowFunctionKey] = @"moveToRightEndOfLine:";
102 CPStandardKeyBindings[@"@" + CPRightArrowFunctionKey] = @"moveToRightEndOfLine:";
103 CPStandardKeyBindings[@"$" + CPRightArrowFunctionKey] = @"moveRightAndModifySelection:";
104 CPStandardKeyBindings[@"$~" + CPRightArrowFunctionKey] = @"moveWordRightAndModifySelection:";
105 CPStandardKeyBindings[@"$^" + CPRightArrowFunctionKey] = @"moveToRightEndOfLineAndModifySelection:";
106 CPStandardKeyBindings[@"$@" + CPRightArrowFunctionKey] = @"moveToRightEndOfLineAndModifySelection:";
107 CPStandardKeyBindings[@"@^" + CPRightArrowFunctionKey] = @"makeBaseWritingDirectionLeftToRight:";
108 CPStandardKeyBindings[@"@^~" + CPRightArrowFunctionKey] = @"makeTextWritingDirectionLeftToRight:";
109 
110 CPStandardKeyBindings[CPUpArrowFunctionKey] = @"moveUp:";
111 CPStandardKeyBindings[@"~" + CPUpArrowFunctionKey] = [@"moveBackward:", @"moveToBeginningOfParagraph:"];
112 CPStandardKeyBindings[@"^" + CPUpArrowFunctionKey] = @"scrollPageUp:";
113 CPStandardKeyBindings[@"@" + CPUpArrowFunctionKey] = @"moveToBeginningOfDocument:";
114 CPStandardKeyBindings[@"$" + CPUpArrowFunctionKey] = @"moveUpAndModifySelection:";
115 CPStandardKeyBindings[@"$~" + CPUpArrowFunctionKey] = @"moveParagraphBackwardAndModifySelection:";
116 CPStandardKeyBindings[@"$@" + CPUpArrowFunctionKey] = @"moveToBeginningOfDocumentAndModifySelection:";
117 
118 CPStandardKeyBindings[CPDownArrowFunctionKey] = @"moveDown:";
119 CPStandardKeyBindings[@"~" + CPDownArrowFunctionKey] = [@"moveForward:", @"moveToEndOfParagraph:"];
120 CPStandardKeyBindings[@"^" + CPDownArrowFunctionKey] = @"scrollPageDown:";
121 CPStandardKeyBindings[@"@" + CPDownArrowFunctionKey] = @"moveToEndOfDocument:";
122 CPStandardKeyBindings[@"$" + CPDownArrowFunctionKey] = @"moveDownAndModifySelection:";
123 CPStandardKeyBindings[@"$~" + CPDownArrowFunctionKey] = @"moveParagraphForwardAndModifySelection:";
124 CPStandardKeyBindings[@"$@" + CPDownArrowFunctionKey] = @"moveToEndOfDocumentAndModifySelection:";
125 CPStandardKeyBindings[@"@^" + CPDownArrowFunctionKey] = @"makeBaseWritingDirectionNatural:";
126 CPStandardKeyBindings[@"@^~" + CPDownArrowFunctionKey] = @"makeTextWritingDirectionNatural:";
127 
128 CPStandardKeyBindings[CPHomeFunctionKey] = @"scrollToBeginningOfDocument:";
129 CPStandardKeyBindings[@"$" + CPHomeFunctionKey] = @"moveToBeginningOfDocumentAndModifySelection:";
130 CPStandardKeyBindings[CPEndFunctionKey] = @"scrollToEndOfDocument:";
131 CPStandardKeyBindings[@"$" + CPEndFunctionKey] = @"moveToEndOfDocumentAndModifySelection:";
132 
133 CPStandardKeyBindings[CPPageUpFunctionKey] = @"scrollPageUp:";
134 CPStandardKeyBindings[@"~" + CPPageUpFunctionKey] = @"pageUp:";
135 CPStandardKeyBindings[@"$" + CPPageUpFunctionKey] = @"pageUpAndModifySelection:";
136 CPStandardKeyBindings[CPPageDownFunctionKey] = @"scrollPageDown:";
137 CPStandardKeyBindings[@"~" + CPPageDownFunctionKey] = @"pageDown:";
138 CPStandardKeyBindings[@"$" + CPPageDownFunctionKey] = @"pageDownAndModifySelection:";
139 
140 var CPKeyBindingCache = {};
141 
142 @implementation CPKeyBinding : CPObject
143 {
144  CPString _key;
145  unsigned _modifierFlags;
146 
147  CPArray _selectors;
148 
149  CPString _cacheName;
150 }
151 
152 + (void)initialize
153 {
154  if (self !== [CPKeyBinding class])
155  return;
156 
157  [self createKeyBindingsFromJSObject:CPStandardKeyBindings];
158 }
159 
160 + (void)createKeyBindingsFromJSObject:(JSObject)anObject
161 {
162  var binding;
163  for (binding in anObject)
164  [self cacheKeyBinding:[[CPKeyBinding alloc] initWithPhysicalKeyString:binding selectors:anObject[binding]]];
165 }
166 
167 + (void)cacheKeyBinding:(CPKeyBinding)aBinding
168 {
169  if (!aBinding)
170  return;
171 
172  CPKeyBindingCache[[aBinding _cacheName]] = aBinding;
173 }
174 
175 + (CPKeyBinding)keyBindingForKey:(CPString)aKey modifierFlags:(unsigned)aFlag
176 {
177  var tempBinding = [[self alloc] initWithKey:aKey modifierFlags:aFlag selectors:nil];
178  return CPKeyBindingCache[[tempBinding _cacheName]];
179 }
180 
181 + (CPArray)selectorsForKey:(CPString)aKey modifierFlags:(unsigned)aFlag
182 {
183  return [[self keyBindingForKey:aKey modifierFlags:aFlag] selectors];
184 }
185 
186 - (id)initWithPhysicalKeyString:(CPString)binding selectors:(CPArray)selectors
187 {
188  var components = binding.split(@""),
189  modifierFlags = ([components containsObject:@"$"] ? CPShiftKeyMask : 0) |
190  ([components containsObject:@"^"] ? CPControlKeyMask : 0) |
191  ([components containsObject:@"~"] ? CPAlternateKeyMask : 0) |
192  ([components containsObject:@"@"] ? CPCommandKeyMask : 0);
193 
194  if (![selectors isKindOfClass:CPArray])
195  selectors = [selectors];
196 
197  return [self initWithKey:[components lastObject] modifierFlags:modifierFlags selectors:selectors];
198 }
199 
200 - (id)initWithKey:(CPString)aKey modifierFlags:(unsigned)aFlag selectors:(CPArray)selectors
201 {
202  self = [super init];
203 
204  if (self)
205  {
206  _key = aKey;
207  _modifierFlags = aFlag;
208 
209  _selectors = selectors;
210 
211  // We normalize our key binding string in order to properly cache it.
212  // We want to ensure the modifiers are always in the same order.
213  var cacheName = [];
214 
215  if (_modifierFlags & CPCommandKeyMask)
216  cacheName.push(@"@");
217  if (_modifierFlags & CPControlKeyMask)
218  cacheName.push(@"^");
219  if (_modifierFlags & CPAlternateKeyMask)
220  cacheName.push(@"~");
221  if (_modifierFlags & CPShiftKeyMask)
222  cacheName.push(@"$");
223 
224  cacheName.push(_key);
225 
226  _cacheName = cacheName.join(@"");
227  }
228 
229  return self;
230 }
231 
232 - (CPString)key
233 {
234  return _key;
235 }
236 
237 - (unsigned)modifierFlags
238 {
239  return _modifierFlags;
240 }
241 
242 - (CPArray)selectors
243 {
244  return _selectors;
245 }
246 
247 - (CPString)_cacheName
248 {
249  return _cacheName;
250 }
251 
252 - (BOOL)isEqual:(CPKeyBinding)rhs
253 {
254  return _key === [rhs key] && _modifierFlags === [rhs modifierFlags];
255 }
256 
257 - (CPString)description
258 {
259  return [CPString stringWithFormat:@"<KeyBinding string: '%@' modifierFlags: 0x%lx selectors: %@>", _key, _modifierFlags, _selectors];
260 }
261 
262 @end