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