Permalink
Browse files

Merge branch 'master' of git://github.com/280north/cappuccino

Conflicts:
	AppKit/AppKit.j
	AppKit/Platform/DOM/CPPlatformWindow+DOM.j
  • Loading branch information...
2 parents c04064b + a6b7d45 commit d68ef56280f52d651d5c8fbe4737fb901eb66787 @emaillard committed Jun 25, 2010
View
1 AppKit/AppKit.j
@@ -58,6 +58,7 @@
@import "CPImage.j"
@import "CPImageView.j"
@import "CPLayoutManager.j"
+@import "CPKeyBinding.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
@import "CPOpenPanel.j"
View
94 AppKit/CPAlert.j
@@ -83,6 +83,7 @@ var CPAlertWarningImage,
CPPanel _alertPanel;
CPTextField _messageLabel;
+ CPTextField _informativeLabel;
CPImageView _alertImageView;
CPAlertStyle _alertStyle;
@@ -140,35 +141,42 @@ var CPAlertWarningImage,
[_alertPanel setFloatingPanel:YES];
[_alertPanel center];
- [_messageLabel setTextColor:(styleMask & CPHUDBackgroundWindowMask) ? [CPColor whiteColor] : [CPColor blackColor]];
-
var count = [_buttons count];
for(var i=0; i < count; i++)
{
var button = _buttons[i];
-
- [button setFrameSize:CGSizeMake([button frame].size.width, (styleMask == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
-
[button setTheme:(_windowStyle === CPHUDBackgroundWindowMask) ? [CPTheme themeNamed:"Aristo-HUD"] : [CPTheme defaultTheme]];
[[_alertPanel contentView] addSubview:button];
}
-
+
+ [self _layoutButtons];
+
if (!_messageLabel)
{
- var bounds = [[_alertPanel contentView] bounds];
-
- _messageLabel = [[CPTextField alloc] initWithFrame:CGRectMake(57.0, 10.0, CGRectGetWidth(bounds) - 73.0, 62.0)];
+ _messageLabel = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_messageLabel setFont:[CPFont boldSystemFontOfSize:13.0]];
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
[_messageLabel setAlignment:CPJustifiedTextAlignment];
[_messageLabel setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
+
_alertImageView = [[CPImageView alloc] initWithFrame:CGRectMake(15.0, 12.0, 32.0, 32.0)];
+
+ _informativeLabel = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
+ [_informativeLabel setFont:[CPFont systemFontOfSize:12.0]];
+ [_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
+ [_informativeLabel setAlignment:CPJustifiedTextAlignment];
+ [_informativeLabel setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
}
+ [_messageLabel setTextColor:(styleMask & CPHUDBackgroundWindowMask) ? [CPColor whiteColor] : [CPColor blackColor]];
+ [_informativeLabel setTextColor:(styleMask & CPHUDBackgroundWindowMask) ? [CPColor whiteColor] : [CPColor blackColor]];
[[_alertPanel contentView] addSubview:_messageLabel];
[[_alertPanel contentView] addSubview:_alertImageView];
+ [[_alertPanel contentView] addSubview:_informativeLabel];
+
+ [self _layoutMessage];
}
/*!
@@ -231,23 +239,43 @@ var CPAlertWarningImage,
}
/*!
- Set’s the receiver’s message text, or title, to a given text.
+ Sets the receiver’s message text, or title, to a given text.
@param messageText - Message text for the alert.
*/
- (void)setMessageText:(CPString)messageText
{
[_messageLabel setStringValue:messageText];
+ [self _layoutMessage];
}
-/*!
- Return's the receiver's message text body.
+/*!
+ Returns the receiver's message text body.
*/
- (CPString)messageText
{
return [_messageLabel stringValue];
}
/*!
+ Sets the receiver's informative text, shown below the message text.
+ @param informativeText - The informative text.
+*/
+- (void)setInformativeText:(CPString)informativeText
+{
+ [_informativeLabel setStringValue:informativeText];
+ // No need to call _layoutMessage - only the length of the messageText
+ // can affect anything there.
+}
+
+/*!
+ Returns the receiver's informative text.
+*/
+- (CPString)informativeText
+{
+ return [_informativeLabel stringValue];
+}
+
+/*!
Adds a button with a given title to the receiver.
Buttons will be added starting from the right hand side of the \c CPAlert panel.
The first button will have the index 0, the second button 1 and so on.
@@ -260,8 +288,8 @@ var CPAlertWarningImage,
- (void)addButtonWithTitle:(CPString)title
{
var bounds = [[_alertPanel contentView] bounds],
- button = [[CPButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(bounds) - ((_buttonCount + 1) * 90.0), CGRectGetHeight(bounds) - 34.0, 80.0, (_windowStyle == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
-
+ button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
+
[button setTitle:title];
[button setTarget:self];
[button setTag:_buttonCount];
@@ -273,12 +301,48 @@ var CPAlertWarningImage,
[[_alertPanel contentView] addSubview:button];
if (_buttonCount == 0)
- [_alertPanel setDefaultButton:button];
+ [button setKeyEquivalent:CPCarriageReturnCharacter];
else if ([title lowercaseString] === "cancel")
[button setKeyEquivalent:CPEscapeFunctionKey];
+ else
+ [button setKeyEquivalent:nil];
_buttonCount++;
[_buttons addObject:button];
+
+ [self _layoutButtons];
+}
+
+- (void)_layoutButtons
+{
+ var bounds = [[_alertPanel contentView] bounds],
+ count = [_buttons count],
+ offsetX = CGRectGetWidth(bounds),
+ offsetY = CGRectGetHeight(bounds) - 34.0;
+ for(var i=0; i < count; i++)
+ {
+ var button = _buttons[i];
+
+ [button sizeToFit];
+ var buttonBounds = [button bounds],
+ width = MAX(80.0, CGRectGetWidth(buttonBounds)),
+ height = CGRectGetHeight(buttonBounds);
+ offsetX -= (width + 10);
+ [button setFrame:CGRectMake(offsetX, offsetY, width, height)];
+ }
+}
+
+- (void)_layoutMessage
+{
+ var bounds = [[_alertPanel contentView] bounds],
+ width = CGRectGetWidth(bounds) - 73.0,
+ size = [([_messageLabel stringValue] || " ") sizeWithFont:[_messageLabel currentValueForThemeAttribute:@"font"] inWidth:width],
+ contentInset = [_messageLabel currentValueForThemeAttribute:@"content-inset"],
+ height = size.height + contentInset.top + contentInset.bottom;
+
+ [_messageLabel setFrame:CGRectMake(57.0, 10.0, width, height)];
+
+ [_informativeLabel setFrame:CGRectMake(57.0, 10.0 + height + 6.0, width, CGRectGetHeight(bounds) - height - 50.0)];
}
/*!
View
13 AppKit/CPImage.j
@@ -201,6 +201,9 @@ function CPAppKitImage(aFilename, aSize)
var imageOrSize = AppKitImageForNames[aName];
+ if (!imageOrSize)
+ return nil;
+
if (!imageOrSize.isa)
{
imageOrSize = CPAppKitImage("CPImage/" + aName + ".png", imageOrSize);
@@ -213,17 +216,19 @@ function CPAppKitImage(aFilename, aSize)
return imageOrSize;
}
-- (void)setName:(CPString)aName
+- (BOOL)setName:(CPString)aName
{
if (_name === aName)
- return;
+ return YES;
- if (imagesForNames[aName] === self)
- imagesForNames[aName] = nil;
+ if (imagesForNames[aName])
+ return NO;
_name = aName;
imagesForNames[aName] = self;
+
+ return YES;
}
- (CPString)name
View
255 AppKit/CPKeyBinding.j
@@ -0,0 +1,255 @@
+/*
+ * CPKeyBinding.j
+ * AppKit
+ *
+ * Created by Nicholas Small.
+ * Copyright 2010, 280 North, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+@import <Foundation/CPObject.j>
+
+
+CPStandardKeyBindings = {
+ @"@.": @"cancelOperation:",
+
+ @"^a": @"moveToBeginningOfParagraph:",
+ @"^$a": @"moveToBeginningOfParagraphAndModifySelection:",
+ @"^b": @"moveBackward:",
+ @"^$b": @"moveBackwardAndModifySelection:",
+ @"^~b": @"moveWordBackward:",
+ @"^~$b": @"moveWordBackwardAndModifySelection:",
+ @"^d": @"deleteForward:",
+ @"^e": @"moveToEndOfParagraph:",
+ @"^$e": @"moveToEndOfParagraphAndModifySelection:",
+ @"^f": @"moveForward:",
+ @"^$f": @"moveForwardAndModifySelection:",
+ @"^~f": @"moveWordForward:",
+ @"^~$f": @"moveWordForwardAndModifySelection:",
+ @"^h": @"deleteBackward:",
+ @"^k": @"deleteToEndOfParagraph:",
+ @"^l": @"centerSelectionInVisibleArea:",
+ @"^n": @"moveDown:",
+ @"^$n": @"moveDownAndModifySelection:",
+ @"^o": [@"insertNewlineIgnoringFieldEditor:", @"moveBackward:"],
+ @"^p": @"moveUp:",
+ @"^$p": @"moveUpAndModifySelection:",
+ @"^t": @"transpose:",
+ @"^v": @"pageDown:",
+ @"^$v": @"pageDownAndModifySelection:",
+ @"^y": @"yank:"
+};
+
+CPStandardKeyBindings[CPNewlineCharacter] = @"insertNewline:";
+CPStandardKeyBindings[CPCarriageReturnCharacter] = @"insertNewline:";
+CPStandardKeyBindings[CPEnterCharacter] = @"insertNewline:";
+CPStandardKeyBindings[@"~" + CPNewlineCharacter] = @"insertNewlineIgnoringFieldEditor:";
+CPStandardKeyBindings[@"~" + CPCarriageReturnCharacter] = @"insertNewlineIgnoringFieldEditor:";
+CPStandardKeyBindings[@"~" + CPEnterCharacter] = @"insertNewlineIgnoringFieldEditor:";
+CPStandardKeyBindings[@"^" + CPNewlineCharacter] = @"insertLineBreak:";
+CPStandardKeyBindings[@"^" + CPCarriageReturnCharacter] = @"insertLineBreak:";
+CPStandardKeyBindings[@"^" + CPEnterCharacter] = @"insertLineBreak:";
+
+CPStandardKeyBindings[CPBackspaceCharacter] = @"deleteBackward:";
+CPStandardKeyBindings[@"~" + CPBackspaceCharacter] = @"deleteWordBackward:";
+CPStandardKeyBindings[CPDeleteCharacter] = @"deleteBackward:";
+CPStandardKeyBindings[@"@" + CPDeleteCharacter] = @"deleteToBeginningOfLine:";
+CPStandardKeyBindings[@"~" + CPDeleteCharacter] = @"deleteWordBackward:";
+CPStandardKeyBindings[@"^" + CPDeleteCharacter] = @"deleteBackwardByDecomposingPreviousCharacter:";
+CPStandardKeyBindings[@"^~" + CPDeleteCharacter] = @"deleteWordBackward:";
+
+CPStandardKeyBindings[CPDeleteFunctionKey] = @"deleteForward:";
+CPStandardKeyBindings[@"~" + CPDeleteFunctionKey] = @"deleteWordForward:";
+
+CPStandardKeyBindings[CPTabCharacter] = @"insertTab:";
+CPStandardKeyBindings[@"~" + CPTabCharacter] = @"insertTabIgnoringFieldEditor:";
+CPStandardKeyBindings[@"^" + CPTabCharacter] = @"selectNextKeyView:";
+CPStandardKeyBindings[CPBackTabCharacter] = @"insertBacktab:";
+CPStandardKeyBindings[@"^" + CPBackTabCharacter] = @"selectPreviousKeyView:";
+
+CPStandardKeyBindings[CPEscapeFunctionKey] = @"cancelOperation:";
+CPStandardKeyBindings[@"~" + CPEscapeFunctionKey] = @"complete:";
+CPStandardKeyBindings[CPF5FunctionKey] = @"complete:";
+
+CPStandardKeyBindings[CPLeftArrowFunctionKey] = @"moveLeft:";
+CPStandardKeyBindings[@"~" + CPLeftArrowFunctionKey] = @"moveWordLeft:";
+CPStandardKeyBindings[@"^" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLine:";
+CPStandardKeyBindings[@"@" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLine:";
+CPStandardKeyBindings[@"$" + CPLeftArrowFunctionKey] = @"moveLeftAndModifySelection:";
+CPStandardKeyBindings[@"$~" + CPLeftArrowFunctionKey] = @"moveWordLeftAndModifySelection:";
+CPStandardKeyBindings[@"$^" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLineAndModifySelection:";
+CPStandardKeyBindings[@"$@" + CPLeftArrowFunctionKey] = @"moveToLeftEndOfLineAndModifySelection:";
+CPStandardKeyBindings[@"@^" + CPLeftArrowFunctionKey] = @"makeBaseWritingDirectionRightToLeft:";
+CPStandardKeyBindings[@"@^~" + CPLeftArrowFunctionKey] = @"makeTextWritingDirectionRightToLeft:";
+
+CPStandardKeyBindings[CPRightArrowFunctionKey] = @"moveRight:";
+CPStandardKeyBindings[@"~" + CPRightArrowFunctionKey] = @"moveWordRight:";
+CPStandardKeyBindings[@"^" + CPRightArrowFunctionKey] = @"moveToRightEndOfLine:";
+CPStandardKeyBindings[@"@" + CPRightArrowFunctionKey] = @"moveToRightEndOfLine:";
+CPStandardKeyBindings[@"$" + CPRightArrowFunctionKey] = @"moveRightAndModifySelection:";
+CPStandardKeyBindings[@"$~" + CPRightArrowFunctionKey] = @"moveWordRightAndModifySelection:";
+CPStandardKeyBindings[@"$^" + CPRightArrowFunctionKey] = @"moveToRightEndOfLineAndModifySelection:";
+CPStandardKeyBindings[@"$@" + CPRightArrowFunctionKey] = @"moveToRightEndOfLineAndModifySelection:";
+CPStandardKeyBindings[@"@^" + CPRightArrowFunctionKey] = @"makeBaseWritingDirectionLeftToRight:";
+CPStandardKeyBindings[@"@^~" + CPRightArrowFunctionKey] = @"makeTextWritingDirectionLeftToRight:";
+
+CPStandardKeyBindings[CPUpArrowFunctionKey] = @"moveUp:";
+CPStandardKeyBindings[@"~" + CPUpArrowFunctionKey] = [@"moveBackward:", @"moveToBeginningOfParagraph:"];
+CPStandardKeyBindings[@"^" + CPUpArrowFunctionKey] = @"scrollPageUp:";
+CPStandardKeyBindings[@"@" + CPUpArrowFunctionKey] = @"moveToBeginningOfDocument:";
+CPStandardKeyBindings[@"$" + CPUpArrowFunctionKey] = @"moveUpAndModifySelection:";
+CPStandardKeyBindings[@"$~" + CPUpArrowFunctionKey] = @"moveParagraphBackwardAndModifySelection:";
+CPStandardKeyBindings[@"$@" + CPUpArrowFunctionKey] = @"moveToBeginningOfDocumentAndModifySelection:";
+
+CPStandardKeyBindings[CPDownArrowFunctionKey] = @"moveDown:";
+CPStandardKeyBindings[@"~" + CPDownArrowFunctionKey] = [@"moveForward:", @"moveToEndOfParagraph:"];
+CPStandardKeyBindings[@"^" + CPDownArrowFunctionKey] = @"scrollPageDown:";
+CPStandardKeyBindings[@"@" + CPDownArrowFunctionKey] = @"moveToEndOfDocument:";
+CPStandardKeyBindings[@"$" + CPDownArrowFunctionKey] = @"moveDownAndModifySelection:";
+CPStandardKeyBindings[@"$~" + CPDownArrowFunctionKey] = @"moveParagraphForwardAndModifySelection:";
+CPStandardKeyBindings[@"$@" + CPDownArrowFunctionKey] = @"moveToEndOfDocumentAndModifySelection:";
+CPStandardKeyBindings[@"@^" + CPDownArrowFunctionKey] = @"makeBaseWritingDirectionNatural:";
+CPStandardKeyBindings[@"@^~" + CPDownArrowFunctionKey] = @"makeTextWritingDirectionNatural:";
+
+CPStandardKeyBindings[CPHomeFunctionKey] = @"scrollToBeginningOfDocument:";
+CPStandardKeyBindings[@"$" + CPHomeFunctionKey] = @"moveToBeginningOfDocumentAndModifySelection:";
+CPStandardKeyBindings[CPEndFunctionKey] = @"scrollToEndOfDocument:";
+CPStandardKeyBindings[@"$" + CPEndFunctionKey] = @"moveToEndOfDocumentAndModifySelection:";
+
+CPStandardKeyBindings[CPPageUpFunctionKey] = @"scrollPageUp:";
+CPStandardKeyBindings[@"~" + CPPageUpFunctionKey] = @"pageUp:";
+CPStandardKeyBindings[@"$" + CPPageUpFunctionKey] = @"pageUpAndModifySelection:";
+CPStandardKeyBindings[CPPageDownFunctionKey] = @"scrollPageDown:";
+CPStandardKeyBindings[@"~" + CPPageDownFunctionKey] = @"pageDown:";
+CPStandardKeyBindings[@"$" + CPPageDownFunctionKey] = @"pageDownAndModifySelection:";
+
+var CPKeyBindingCache = {};
+
+@implementation CPKeyBinding : CPObject
+{
+ CPString _key;
+ unsigned _modifierFlags;
+
+ CPArray _selectors;
+
+ CPString _cacheName;
+}
+
++ (void)initialize
+{
+ if ([self class] !== CPKeyBinding)
+ return;
+
+ [self createKeyBindingsFromJSObject:CPStandardKeyBindings];
+}
+
++ (void)createKeyBindingsFromJSObject:(JSObject)anObject
+{
+ var binding;
+ for (binding in anObject)
+ {
+ var components = binding.split(@""),
+ modifierFlags = ([components containsObject:@"$"] ? CPShiftKeyMask : 0) |
+ ([components containsObject:@"^"] ? CPControlKeyMask : 0) |
+ ([components containsObject:@"~"] ? CPAlternateKeyMask : 0) |
+ ([components containsObject:@"@"] ? CPCommandKeyMask : 0);
+
+ var selectors = anObject[binding];
+ if (![selectors isKindOfClass:CPArray])
+ selectors = [selectors];
+
+ var keyBinding = [[self alloc] initWithKey:[components lastObject] modifierFlags:modifierFlags selectors:selectors];
+ [self cacheKeyBinding:keyBinding];
+ }
+}
+
++ (void)cacheKeyBinding:(CPKeyBinding)aBinding
+{
+ if (!aBinding)
+ return;
+
+ CPKeyBindingCache[[aBinding _cacheName]] = aBinding;
+}
+
++ (CPKeyBinding)keyBindingForKey:(CPString)aKey modifierFlags:(unsigned)aFlag
+{
+ var tempBinding = [[self alloc] initWithKey:aKey modifierFlags:aFlag selectors:nil];
+ return CPKeyBindingCache[[tempBinding _cacheName]];
+}
+
++ (CPArray)selectorsForKey:(CPString)aKey modifierFlags:(unsigned)aFlag
+{
+ return [[self keyBindingForKey:aKey modifierFlags:aFlag] selectors];
+}
+
+- (id)initWithKey:(CPString)aKey modifierFlags:(unsigned)aFlag selectors:(CPArray)selectors
+{
+ self = [super init];
+
+ if (self)
+ {
+ _key = aKey;
+ _modifierFlags = aFlag;
+
+ _selectors = selectors;
+
+ // We normalize our key binding string in order to properly cache it.
+ // We want to ensure the modifiers are always in the same order.
+ var cacheName = [];
+
+ if (_modifierFlags & CPCommandKeyMask)
+ cacheName.push(@"@");
+ if (_modifierFlags & CPControlKeyMask)
+ cacheName.push(@"^");
+ if (_modifierFlags & CPAlternateKeyMask)
+ cacheName.push(@"~");
+ if (_modifierFlags & CPShiftKeyMask)
+ cacheName.push(@"$");
+
+ cacheName.push(_key);
+
+ _cacheName = cacheName.join(@"");
+ }
+
+ return self;
+}
+
+- (CPString)key
+{
+ return _key;
+}
+
+- (unsigned)modifierFlags
+{
+ return _modifierFlags;
+}
+
+- (CPArray)selectors
+{
+ return _selectors;
+}
+
+- (CPString)_cacheName
+{
+ return _cacheName;
+}
+
+- (BOOL)isEqual:(CPKeyBinding)rhs
+{
+ return _key === [rhs key] && _modifierFlags === [rhs modifierFlags];
+}
+
+@end
View
54 AppKit/CPResponder.j
@@ -104,39 +104,24 @@ CPDeleteForwardKeyCode = 46;
for (; index < count; ++index)
{
- var event = events[index];
+ var event = events[index],
+ modifierFlags = [event modifierFlags],
+ character = [event charactersIgnoringModifiers],
+ selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags];
- switch([[event characters] characterAtIndex:0])
+ if (selectorNames)
{
- case CPPageUpFunctionKey: [self doCommandBySelector:@selector(pageUp:)];
- break;
- case CPPageDownFunctionKey: [self doCommandBySelector:@selector(pageDown:)];
- break;
- case CPLeftArrowFunctionKey: [self doCommandBySelector:@selector(moveLeft:)];
- break;
- case CPRightArrowFunctionKey: [self doCommandBySelector:@selector(moveRight:)];
- break;
- case CPUpArrowFunctionKey: [self doCommandBySelector:@selector(moveUp:)];
- break;
- case CPDownArrowFunctionKey: [self doCommandBySelector:@selector(moveDown:)];
- break;
- case CPDeleteCharacter: [self doCommandBySelector:@selector(deleteBackward:)];
- break;
- case CPCarriageReturnCharacter:
- case CPNewlineCharacter: [self doCommandBySelector:@selector(insertLineBreak:)];
- break;
-
- case CPEscapeFunctionKey: [self doCommandBySelector:@selector(cancel:)];
- break;
-
- case CPTabCharacter: if (!([event modifierFlags] & CPShiftKeyMask))
- [self doCommandBySelector:@selector(insertTab:)];
- else
- [self doCommandBySelector:@selector(insertBackTab:)];
- break;
-
- default: [self insertText:[event characters]];
+ for (var s = 0, scount = selectorNames.length; s < scount; s++)
+ {
+ var selector = selectorNames[s];
+ if (!selector)
+ continue;
+
+ [self doCommandBySelector:CPSelectorFromString(selector)];
+ }
}
+ else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)) && [self respondsToSelector:@selector(insertText:)])
+ [self insertText:[event characters]];
}
}
@@ -236,6 +221,15 @@ CPDeleteForwardKeyCode = 46;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
+/*!
+ Notifies the receiver that the user has pressed or released a modifier key (Shift, Control, and so on).
+ @param anEvent information about the key press
+*/
+- (void)flagsChanged:(CPEvent)anEvent
+{
+ [_nextResponder performSelector:_cmd withObject:anEvent];
+}
+
/*
FIXME This description is bad.
Based on \c anEvent, the receiver should simulate the event.
View
13 AppKit/CPTableView.j
@@ -3070,15 +3070,16 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
// We don't use rowAtPoint here because the drag indicator can appear below the last row
// and rowAtPoint doesn't return rows that are larger than numberOfRows
- var row = FLOOR(dragPoint.y / ( _rowHeight + _intercellSpacing.height ));
-
+ // FIX ME: this is going to break when we implement variable row heights...
+ var row = FLOOR(dragPoint.y / ( _rowHeight + _intercellSpacing.height )),
// Determine if the mouse is currently closer to this row or the row below it
- var lowerRow = row + 1,
+ lowerRow = row + 1,
rect = [self rectOfRow:row],
- lowerRect = [self rectOfRow:lowerRow];
+ bottomPoint = CGRectGetMaxY(rect),
+ bottomThirty = bottomPoint - ((bottomPoint - CGRectGetMinY(rect)) * 0.3);
- if (ABS(CPRectGetMinY(lowerRect) - dragPoint.y) < ABS(dragPoint.y - CPRectGetMinY(rect)))
- row = lowerRow;
+ if (dragPoint.y > MAX(bottomThirty, bottomPoint - 6))
+ row = lowerRow;
if (row >= [self numberOfRows])
row = [self numberOfRows];
View
5 AppKit/CPTextField.j
@@ -807,11 +807,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
if ([[self window] firstResponder] === self)
window.setTimeout(function() { element.select(); }, 0);
- else
- {
- [[self window] makeFirstResponder:self];
+ else if ([self window] !== nil && [[self window] makeFirstResponder:self])
window.setTimeout(function() {[self selectText:sender];}, 0);
- }
}
#endif
}
View
2 AppKit/CPWindow/CPWindow.j
@@ -1379,6 +1379,8 @@ CPTexturedBackgroundWindowMask
switch (type)
{
+ case CPFlagsChanged: return [[self firstResponder] flagsChanged:anEvent];
+
case CPKeyUp: return [[self firstResponder] keyUp:anEvent];
case CPKeyDown: [[self firstResponder] keyDown:anEvent];
View
51 AppKit/Platform/DOM/CPPlatformWindow+DOM.j
@@ -156,6 +156,14 @@ KeyCodesToFunctionUnicodeMap[CPKeyCodes.UP] = CPUpArrowFunctionKey;
KeyCodesToFunctionUnicodeMap[CPKeyCodes.RIGHT] = CPRightArrowFunctionKey;
KeyCodesToFunctionUnicodeMap[CPKeyCodes.DOWN] = CPDownArrowFunctionKey;
+var ModifierKeyCodes = [
+ CPKeyCodes.META,
+ CPKeyCodes.MAC_FF_META,
+ CPKeyCodes.CTRL,
+ CPKeyCodes.ALT,
+ CPKeyCodes.SHIFT
+];
+
var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
@implementation CPPlatformWindow (DOM)
@@ -607,8 +615,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
- (void)keyEvent:(DOMEvent)aDOMEvent
{
var event,
- timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
- sourceElement = (aDOMEvent.target || aDOMEvent.srcElement),
+ timestamp = aDOMEvent.timeStamp || new Date(),
+ sourceElement = aDOMEvent.target || aDOMEvent.srcElement,
windowNumber = [[CPApp keyWindow] windowNumber],
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
@@ -627,22 +635,39 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
switch (aDOMEvent.type)
{
case "keydown": // Grab and store the keycode now since it is correct and consistent at this point.
- if (aDOMEvent.keyCode.keyCode in MozKeyCodeToKeyCodeMap)
+ if (aDOMEvent.keyCode in MozKeyCodeToKeyCodeMap)
_keyCode = MozKeyCodeToKeyCodeMap[aDOMEvent.keyCode];
else
_keyCode = aDOMEvent.keyCode;
if (!_keyCode && aDOMEvent.keyIdentifier && aDOMEvent.keyIdentifier !== "Unidentified")
_keyCode = parseInt("0x"+aDOMEvent.keyIdentifier.substr(2,4));
- var characters = KeyCodesToFunctionUnicodeMap[_keyCode] || String.fromCharCode(_keyCode).toLowerCase();
+ var characters;
+
+ // Is this a special key?
+ if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0)
+ characters = KeyCodesToFunctionUnicodeMap[_keyCode];
+
+ if (!characters)
+ characters = String.fromCharCode(_keyCode).toLowerCase();
+
overrideCharacters = (modifierFlags & CPShiftKeyMask || _capsLockActive) ? characters.toUpperCase() : characters;
// check for caps lock state
if (_keyCode === CPKeyCodes.CAPS_LOCK)
_capsLockActive = YES;
- if (modifierFlags & (CPControlKeyMask | CPCommandKeyMask))
+ if ([ModifierKeyCodes containsObject:_keyCode])
+ {
+ // A modifier key will never fire keypress. We don't need to do any other processing so we just fire it here and break.
+ event = [CPEvent keyEventWithType:CPFlagsChanged location:location modifierFlags:modifierFlags
+ timestamp:timestamp windowNumber:windowNumber context:nil
+ characters:nil charactersIgnoringModifiers:nil isARepeat:NO keyCode:_keyCode];
+
+ break;
+ }
+ else if (modifierFlags & (CPControlKeyMask | CPCommandKeyMask))
{
//we are simply going to skip all keypress events that use cmd/ctrl key
//this lets us be consistent in all browsers and send on the keydown
@@ -699,16 +724,23 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_lastKey = keyCode;
_charCodes[keyCode] = charCode;
- var characters = overrideCharacters || KeyCodesToFunctionUnicodeMap[charCode] || String.fromCharCode(charCode),
- charactersIgnoringModifiers = characters.toLowerCase();
+ var characters = overrideCharacters;
+ // Is this a special key?
+ if (!characters && (aDOMEvent.which === 0 || aDOMEvent.charCode === 0))
+ characters = KeyCodesToFunctionUnicodeMap[charCode];
+
+ if (!characters)
+ characters = String.fromCharCode(charCode);
+
+ charactersIgnoringModifiers = characters.toLowerCase(); // FIXME: This isn't correct. It SHOULD include Shift.
// Safari won't send proper capitalization during cmd-key events
if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && ((modifierFlags & CPShiftKeyMask) || _capsLockActive))
characters = characters.toUpperCase();
event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil
- characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:keyCode];
+ characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:charCode];
if (isNativePasteEvent)
{
@@ -731,6 +763,9 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (keyCode === CPKeyCodes.CAPS_LOCK)
_capsLockActive = NO;
+ if ([ModifierKeyCodes containsObject:keyCode])
+ break;
+
var characters = KeyCodesToFunctionUnicodeMap[charCode] || String.fromCharCode(charCode),
charactersIgnoringModifiers = characters.toLowerCase();
View
12 Foundation/CPBundle.j
@@ -118,6 +118,16 @@ var CPBundlesForURLStrings = { };
return className ? CPClassFromString(className) : Nil;
}
+- (CPString)bundleIdentifier
+{
+ return [self objectForInfoDictionaryKey:@"CPBundleIdentifier"];
+}
+
+- (BOOL)isLoaded
+{
+ return _bundle.isLoaded();
+}
+
- (CPString)pathForResource:(CPString)aFilename
{
return _bundle.pathForResource(aFilename);
@@ -133,8 +143,6 @@ var CPBundlesForURLStrings = { };
return _bundle.valueForInfoDictionaryKey(aKey);
}
-//
-
- (void)loadWithDelegate:(id)aDelegate
{
_delegate = aDelegate;
View
5 Objective-J/CFBundle.js
@@ -235,6 +235,11 @@ CFBundle.prototype.isLoading = function()
return this._loadStatus & CFBundleLoading;
}
+CFBundle.prototype.isLoaded = function()
+{
+ return this._loadStatus & CFBundleLoaded;
+}
+
DISPLAY_NAME(CFBundle.prototype.isLoading);
CFBundle.prototype.load = function(/*BOOL*/ shouldExecute)
View
17 Tests/AppKit/CPResponderTest.j
@@ -21,16 +21,16 @@
- (void)testInterpretKeyEvents
{
var tests = [
- CPKeyCodes.PAGE_UP, CPPageUpFunctionKey, @selector(pageUp:),
- CPKeyCodes.PAGE_DOWN, CPPageDownFunctionKey, @selector(pageDown:),
+ CPKeyCodes.PAGE_UP, CPPageUpFunctionKey, @selector(scrollPageUp:),
+ CPKeyCodes.PAGE_DOWN, CPPageDownFunctionKey, @selector(scrollPageDown:),
CPKeyCodes.LEFT, CPLeftArrowFunctionKey, @selector(moveLeft:),
CPKeyCodes.RIGHT, CPRightArrowFunctionKey, @selector(moveRight:),
CPKeyCodes.UP, CPUpArrowFunctionKey, @selector(moveUp:),
CPKeyCodes.DOWN, CPDownArrowFunctionKey, @selector(moveDown:),
CPKeyCodes.BACKSPACE, CPDeleteCharacter, @selector(deleteBackward:),
- CPKeyCodes.ENTER, CPCarriageReturnCharacter, @selector(insertLineBreak:),
- 0, CPNewlineCharacter, @selector(insertLineBreak:),
- CPKeyCodes.ESC, CPEscapeFunctionKey, @selector(cancel:),
+ CPKeyCodes.ENTER, CPCarriageReturnCharacter, @selector(insertNewline:),
+ 0, CPNewlineCharacter, @selector(insertNewline:),
+ CPKeyCodes.ESC, CPEscapeFunctionKey, @selector(cancelOperation:),
CPKeyCodes.TAB, CPTabCharacter, @selector(insertTab:)
];
@@ -47,13 +47,16 @@
[responder interpretKeyEvents:[keyEvent]];
[self assert:[selector] equals:responder.doCommandCalls];
}
+}
+- (void)testInterpretKeyEventsWithModifierFlags
+{
responder.doCommandCalls = [];
keyEvent = [CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPShiftKeyMask
timestamp:nil windowNumber:nil context:nil
- characters:CPTabCharacter charactersIgnoringModifiers:CPTabCharacter isARepeat:NO keyCode:CPKeyCodes.TAB];
+ characters:CPLeftArrowFunctionKey charactersIgnoringModifiers:CPLeftArrowFunctionKey isARepeat:NO keyCode:CPKeyCodes.LEFT];
[responder interpretKeyEvents:[keyEvent]];
- [self assert:[@selector(insertBackTab:)] equals:responder.doCommandCalls];
+ [self assert:[@selector(moveLeftAndModifySelection:)] equals:responder.doCommandCalls];
}
@end
View
2 Tools/nib2cib/NSButton.j
@@ -93,7 +93,7 @@ _CPButtonBezelStyleHeights[CPHUDBezelStyle] = 20;
_bezelStyle = CPHUDBezelStyle;
}
- if ([cell isBordered] && _frame.size.height === 32.0)
+ if ([cell isBordered])
{
CPLog.info("Adjusting CPButton height from " +_frame.size.height+ " / " + _bounds.size.height+" to " + 24);
_frame.size.height = 24.0;

0 comments on commit d68ef56

Please sign in to comment.