Merge branch 'master' of git://github.com/280north/cappuccino
@@ -55,6 +55,7 @@
|
||||
@import "CPGeometry.j"
|
||||
@import "CPImage.j"
|
||||
@import "CPImageView.j"
|
||||
@import "CPKeyBinding.j"
|
||||
@import "CPMenu.j"
|
||||
@import "CPMenuItem.j"
|
||||
@import "CPOpenPanel.j"
|
||||
@@ -76,6 +77,7 @@
|
||||
@import "CPTabView.j"
|
||||
@import "CPTableColumn.j"
|
||||
@import "CPTableView.j"
|
||||
@import "CPText.j"
|
||||
@import "CPTextField.j"
|
||||
@import "CPToolbar.j"
|
||||
@import "CPToolbarItem.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,34 +239,57 @@ 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.
|
||||
|
||||
The first button will automatically be given a key equivalent of Return,
|
||||
and any button titled "Cancel" will be given a key equivalent of Escape.
|
||||
|
||||
You really shouldn't need more than 3 buttons.
|
||||
*/
|
||||
- (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];
|
||||
@@ -270,10 +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)];
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -325,7 +325,9 @@ CPRunContinuesResponse = -1002;
|
||||
applicationVersion = [options objectForKey:@"ApplicationVersion"] || [mainInfo objectForKey:@"CPBundleShortVersionString"],
|
||||
copyright = [options objectForKey:@"Copyright"] || [mainInfo objectForKey:@"CPHumanReadableCopyright"];
|
||||
|
||||
var aboutPanelController = [[CPWindowController alloc] initWithWindowCibName:@"AboutPanel"],
|
||||
var aboutPanelPath = [[CPBundle bundleForClass:[CPWindowController class]] pathForResource:@"AboutPanel.cib"],
|
||||
aboutPanelController = [CPWindowController alloc],
|
||||
aboutPanelController = [aboutPanelController initWithWindowCibPath:aboutPanelPath owner:aboutPanelController],
|
||||
aboutPanel = [aboutPanelController window],
|
||||
contentView = [aboutPanel contentView],
|
||||
imageView = [contentView viewWithTag:1],
|
||||
|
||||
@@ -99,6 +99,9 @@ CPButtonStateMixed = CPThemeState("mixed");
|
||||
// NS-style Display Properties
|
||||
CPBezelStyle _bezelStyle;
|
||||
CPControlSize _controlSize;
|
||||
|
||||
CPString _keyEquivalent;
|
||||
unsigned _keyEquivalentModifierMask;
|
||||
}
|
||||
|
||||
+ (id)buttonWithTitle:(CPString)aTitle
|
||||
@@ -142,6 +145,9 @@ CPButtonStateMixed = CPThemeState("mixed");
|
||||
|
||||
_controlSize = CPRegularControlSize;
|
||||
|
||||
_keyEquivalent = "";
|
||||
_keyEquivalentModifierMask = 0;
|
||||
|
||||
// [self setBezelStyle:CPRoundRectBezelStyle];
|
||||
[self setBordered:YES];
|
||||
}
|
||||
@@ -555,6 +561,74 @@ CPButtonStateMixed = CPThemeState("mixed");
|
||||
return [self hasThemeState:CPThemeStateBordered];
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the keyboard shortcut for this button. For special keys see
|
||||
CPEvent.j CP...FunctionKey and CPText.j CP...Character.
|
||||
|
||||
@param aString the keyboard shortcut as a string
|
||||
*/
|
||||
- (void)setKeyEquivalent:(CPString)aString
|
||||
{
|
||||
// Check if the key equivalent is the enter key
|
||||
// Treat \r and \n as the same key equivalent. See issue #710.
|
||||
if (aString === CPNewlineCharacter || aString === CPCarriageReturnCharacter)
|
||||
[[self window] setDefaultButton:self];
|
||||
else if ([[self window] defaultButton] === self)
|
||||
[[self window] setDefaultButton:NO];
|
||||
|
||||
_keyEquivalent = aString || @"";
|
||||
}
|
||||
|
||||
- (void)viewWillMoveToWindow:(CPWindow)aWindow
|
||||
{
|
||||
if ([[self window] defaultButton] === self)
|
||||
[[self window] setDefaultButton:nil];
|
||||
|
||||
if ([self keyEquivalent] === CPNewlineCharacter || [self keyEquivalent] === CPCarriageReturnCharacter)
|
||||
[aWindow setDefaultButton:self];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the keyboard shortcut for this button.
|
||||
*/
|
||||
- (CPString)keyEquivalent
|
||||
{
|
||||
return _keyEquivalent;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the mask used with this button's key equivalent.
|
||||
*/
|
||||
- (void)setKeyEquivalentModifierMask:(unsigned)aMask
|
||||
{
|
||||
_keyEquivalentModifierMask = aMask;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the mask to be used with this button's key equivalent.
|
||||
*/
|
||||
- (unsigned)keyEquivalentModifierMask
|
||||
{
|
||||
return _keyEquivalentModifierMask;
|
||||
}
|
||||
|
||||
/*!
|
||||
Checks the button's key equivalent against that in the event, and if they
|
||||
match simulates a button click.
|
||||
*/
|
||||
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
|
||||
{
|
||||
// Don't handle the key equivalent for the default window because the window will handle it for us
|
||||
if ([[self window] defaultButton] === self)
|
||||
return NO;
|
||||
|
||||
if (![anEvent _triggersKeyEquivalent:[self keyEquivalent] withModifierMask:[self keyEquivalentModifierMask]])
|
||||
return NO;
|
||||
|
||||
[self performClick:nil];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPButton (NS)
|
||||
@@ -575,7 +649,9 @@ var CPButtonImageKey = @"CPButtonImageKey",
|
||||
CPButtonTitleKey = @"CPButtonTitleKey",
|
||||
CPButtonAlternateTitleKey = @"CPButtonAlternateTitleKey",
|
||||
CPButtonIsBorderedKey = @"CPButtonIsBorderedKey",
|
||||
CPButtonImageDimsWhenDisabledKey = @"CPButtonImageDimsWhenDisabledKey";
|
||||
CPButtonImageDimsWhenDisabledKey = @"CPButtonImageDimsWhenDisabledKey",
|
||||
CPButtonKeyEquivalentKey = @"CPButtonKeyEquivalentKey",
|
||||
CPButtonKeyEquivalentMaskKey = @"CPButtonKeyEquivalentMaskKey";
|
||||
|
||||
@implementation CPButton (CPCoding)
|
||||
|
||||
@@ -599,6 +675,11 @@ var CPButtonImageKey = @"CPButtonImageKey",
|
||||
|
||||
[self setImageDimsWhenDisabled:[aCoder decodeObjectForKey:CPButtonImageDimsWhenDisabledKey]];
|
||||
|
||||
if ([aCoder containsValueForKey:CPButtonKeyEquivalentKey])
|
||||
[self setKeyEquivalent:CFData.decodeBase64ToUtf16String([aCoder decodeObjectForKey:CPButtonKeyEquivalentKey])];
|
||||
|
||||
[self setKeyEquivalentModifierMask:[aCoder decodeObjectForKey:CPButtonKeyEquivalentMaskKey]];
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
@@ -621,6 +702,11 @@ var CPButtonImageKey = @"CPButtonImageKey",
|
||||
[aCoder encodeObject:_alternateTitle forKey:CPButtonAlternateTitleKey];
|
||||
|
||||
[aCoder encodeObject:[self imageDimsWhenDisabled] forKey:CPButtonImageDimsWhenDisabledKey];
|
||||
|
||||
if (_keyEquivalent)
|
||||
[aCoder encodeObject:CFData.encodeBase64Utf16String(_keyEquivalent) forKey:CPButtonKeyEquivalentKey];
|
||||
|
||||
[aCoder encodeInt:_keyEquivalentModifierMask forKey:CPButtonKeyEquivalentMaskKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -312,8 +312,10 @@
|
||||
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
|
||||
[_items[index] setSelected:YES];
|
||||
|
||||
[[CPKeyValueBinding getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
|
||||
[_delegate collectionViewDidChangeSelection:self]
|
||||
[_delegate collectionViewDidChangeSelection:self];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -737,9 +739,12 @@
|
||||
@end
|
||||
|
||||
@implementation CPCollectionView (KeyboardInteraction)
|
||||
- (CPIndexSet)_selectionForEvent:(CPEvent)anEvent withNewIndex:(int)anIndex direction:(int)aDirection
|
||||
|
||||
- (void)_modifySelectionWithNewIndex:(int)anIndex direction:(int)aDirection expand:(BOOL)shouldExpand
|
||||
{
|
||||
if (_allowsMultipleSelection && [anEvent modifierFlags] & CPShiftKeyMask)
|
||||
anIndex = MIN(MAX(anIndex, 0), [[self items] count]-1);
|
||||
|
||||
if (_allowsMultipleSelection && shouldExpand)
|
||||
{
|
||||
var indexes = [_selectionIndexes copy],
|
||||
bottomAnchor = [indexes firstIndex],
|
||||
@@ -754,7 +759,8 @@
|
||||
else
|
||||
indexes = [CPIndexSet indexSetWithIndex:anIndex];
|
||||
|
||||
return indexes;
|
||||
[self setSelectionIndexes:indexes];
|
||||
[self _scrollToSelection];
|
||||
}
|
||||
|
||||
- (void)_scrollToSelection
|
||||
@@ -771,26 +777,36 @@
|
||||
if (index === CPNotFound)
|
||||
index = [[self items] count];
|
||||
|
||||
index = MAX(index - 1, 0);
|
||||
[self _modifySelectionWithNewIndex:index - 1 direction:-1 expand:NO];
|
||||
}
|
||||
|
||||
[self setSelectionIndexes:[self _selectionForEvent:[CPApp currentEvent] withNewIndex:index direction:-1]];
|
||||
[self _scrollToSelection];
|
||||
- (void)moveLeftAndModifySelection:(id)sender
|
||||
{
|
||||
var index = [[self selectionIndexes] firstIndex];
|
||||
if (index === CPNotFound)
|
||||
index = [[self items] count];
|
||||
|
||||
[self _modifySelectionWithNewIndex:index - 1 direction:-1 expand:YES];
|
||||
}
|
||||
|
||||
- (void)moveRight:(id)sender
|
||||
{
|
||||
var index = MIN([[self selectionIndexes] lastIndex] + 1, [[self items] count]-1);
|
||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + 1 direction:1 expand:NO];
|
||||
}
|
||||
|
||||
[self setSelectionIndexes:[self _selectionForEvent:[CPApp currentEvent] withNewIndex:index direction:1]];
|
||||
[self _scrollToSelection];
|
||||
- (void)moveRightAndModifySelection:(id)sender
|
||||
{
|
||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + 1 direction:1 expand:YES];
|
||||
}
|
||||
|
||||
- (void)moveDown:(id)sender
|
||||
{
|
||||
var index = MIN([[self selectionIndexes] lastIndex] + [self numberOfColumns], [[self items] count]-1);
|
||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + [self numberOfColumns] direction:1 expand:NO];
|
||||
}
|
||||
|
||||
[self setSelectionIndexes:[self _selectionForEvent:[CPApp currentEvent] withNewIndex:index direction:1]];
|
||||
[self _scrollToSelection];
|
||||
- (void)moveDownAndModifySelection:(id)sender
|
||||
{
|
||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + [self numberOfColumns] direction:1 expand:YES];
|
||||
}
|
||||
|
||||
- (void)moveUp:(id)sender
|
||||
@@ -799,10 +815,16 @@
|
||||
if (index == CPNotFound)
|
||||
index = [[self items] count];
|
||||
|
||||
index = MAX(0, index - [self numberOfColumns]);
|
||||
[self _modifySelectionWithNewIndex:index - [self numberOfColumns] direction:-1 expand:NO];
|
||||
}
|
||||
|
||||
[self setSelectionIndexes:[self _selectionForEvent:[CPApp currentEvent] withNewIndex:index direction:-1]];
|
||||
[self _scrollToSelection];
|
||||
- (void)moveUpAndModifySelection:(id)sender
|
||||
{
|
||||
var index = [[self selectionIndexes] firstIndex];
|
||||
if (index == CPNotFound)
|
||||
index = [[self items] count];
|
||||
|
||||
[self _modifySelectionWithNewIndex:index - [self numberOfColumns] direction:-1 expand:YES];
|
||||
}
|
||||
|
||||
- (void)deleteBackward:(id)sender
|
||||
@@ -847,11 +869,13 @@
|
||||
|
||||
@end
|
||||
|
||||
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
|
||||
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
|
||||
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey",
|
||||
CPCollectionViewSelectableKey = @"CPCollectionViewSelectableKey",
|
||||
CPCollectionViewBackgroundColorsKey = @"CPCollectionViewBackgroundColorsKey";
|
||||
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
|
||||
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
|
||||
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey",
|
||||
CPCollectionViewMaxNumberOfRowsKey = @"CPCollectionViewMaxNumberOfRowsKey",
|
||||
CPCollectionViewMaxNumberOfColumnsKey = @"CPCollectionViewMaxNumberOfColumnsKey",
|
||||
CPCollectionViewSelectableKey = @"CPCollectionViewSelectableKey",
|
||||
CPCollectionViewBackgroundColorsKey = @"CPCollectionViewBackgroundColorsKey";
|
||||
|
||||
|
||||
@implementation CPCollectionView (CPCoding)
|
||||
@@ -872,6 +896,9 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
|
||||
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
|
||||
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
|
||||
|
||||
_maxNumberOfRows = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfRowsKey] || 0;
|
||||
_maxNumberOfColumns = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfColumnsKey] || 0;
|
||||
|
||||
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
|
||||
|
||||
_isSelectable = [aCoder decodeBoolForKey:CPCollectionViewSelectableKey];
|
||||
@@ -898,6 +925,9 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
|
||||
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
|
||||
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
|
||||
|
||||
[aCoder encodeInt:_maxNumberOfRows forKey:CPCollectionViewMaxNumberOfRowsKey];
|
||||
[aCoder encodeInt:_maxNumberOfColumns forKey:CPCollectionViewMaxNumberOfColumnsKey];
|
||||
|
||||
[aCoder encodeBool:_isSelectable forKey:CPCollectionViewSelectableKey];
|
||||
|
||||
[aCoder encodeFloat:_verticalMargin forKey:CPCollectionViewVerticalMarginKey];
|
||||
|
||||
@@ -422,7 +422,7 @@ var cachedBlackColor,
|
||||
parseInt(parts[1], 10) / 255.0,
|
||||
parseInt(parts[2], 10) / 255.0,
|
||||
parts[3] ? parseInt(parts[3], 10) / 255.0 : 1.0
|
||||
]
|
||||
];
|
||||
|
||||
_cssString = aString;
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ var currentCursor = nil,
|
||||
|
||||
+ (void)unhide
|
||||
{
|
||||
[self _setCursorCSS:[currentCursor _cssString]]
|
||||
[self _setCursorCSS:[currentCursor _cssString]];
|
||||
}
|
||||
|
||||
+ (void)setHiddenUntilMouseMoves:(BOOL)flag
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
@import <Foundation/CPObject.j>
|
||||
@import "CPText.j"
|
||||
|
||||
#include "CoreGraphics/CGGeometry.h"
|
||||
|
||||
@@ -41,7 +42,7 @@ CPAppKitDefined = 13;
|
||||
CPSystemDefined = 14;
|
||||
CPApplicationDefined = 15;
|
||||
CPPeriodic = 16;
|
||||
CPCursorUpdate = 17;
|
||||
CPCursorUpdate = 17;
|
||||
CPScrollWheel = 22;
|
||||
CPOtherMouseDown = 25;
|
||||
CPOtherMouseUp = 26;
|
||||
@@ -52,8 +53,7 @@ CPTouchStart = 28;
|
||||
CPTouchMove = 29;
|
||||
CPTouchEnd = 30;
|
||||
CPTouchCancel = 31;
|
||||
|
||||
|
||||
|
||||
CPAlphaShiftKeyMask = 1 << 16;
|
||||
CPShiftKeyMask = 1 << 17;
|
||||
CPControlKeyMask = 1 << 18;
|
||||
@@ -87,26 +87,102 @@ CPPeriodicMask = 1 << CPPeriodic;
|
||||
CPScrollWheelMask = 1 << CPScrollWheel;
|
||||
CPAnyEventMask = 0xffffffff;
|
||||
|
||||
CPDOMEventDoubleClick = "dblclick",
|
||||
CPDOMEventMouseDown = "mousedown",
|
||||
CPDOMEventMouseUp = "mouseup",
|
||||
CPDOMEventMouseMoved = "mousemove",
|
||||
CPDOMEventMouseDragged = "mousedrag",
|
||||
CPDOMEventKeyUp = "keyup",
|
||||
CPDOMEventKeyDown = "keydown",
|
||||
CPDOMEventKeyPress = "keypress";
|
||||
CPDOMEventCopy = "copy";
|
||||
CPDOMEventPaste = "paste";
|
||||
CPDOMEventScrollWheel = "mousewheel";
|
||||
CPDOMEventTouchStart = "touchstart";
|
||||
CPDOMEventTouchMove = "touchmove";
|
||||
CPDOMEventTouchEnd = "touchend";
|
||||
CPDOMEventTouchCancel = "touchcancel";
|
||||
CPUpArrowFunctionKey = "\uF700";
|
||||
CPDownArrowFunctionKey = "\uF701";
|
||||
CPLeftArrowFunctionKey = "\uF702";
|
||||
CPRightArrowFunctionKey = "\uF703";
|
||||
CPF1FunctionKey = "\uF704";
|
||||
CPF2FunctionKey = "\uF705";
|
||||
CPF3FunctionKey = "\uF706";
|
||||
CPF4FunctionKey = "\uF707";
|
||||
CPF5FunctionKey = "\uF708";
|
||||
CPF6FunctionKey = "\uF709";
|
||||
CPF7FunctionKey = "\uF70A";
|
||||
CPF8FunctionKey = "\uF70B";
|
||||
CPF9FunctionKey = "\uF70C";
|
||||
CPF10FunctionKey = "\uF70D";
|
||||
CPF11FunctionKey = "\uF70E";
|
||||
CPF12FunctionKey = "\uF70F";
|
||||
CPF13FunctionKey = "\uF710";
|
||||
CPF14FunctionKey = "\uF711";
|
||||
CPF15FunctionKey = "\uF712";
|
||||
CPF16FunctionKey = "\uF713";
|
||||
CPF17FunctionKey = "\uF714";
|
||||
CPF18FunctionKey = "\uF715";
|
||||
CPF19FunctionKey = "\uF716";
|
||||
CPF20FunctionKey = "\uF717";
|
||||
CPF21FunctionKey = "\uF718";
|
||||
CPF22FunctionKey = "\uF719";
|
||||
CPF23FunctionKey = "\uF71A";
|
||||
CPF24FunctionKey = "\uF71B";
|
||||
CPF25FunctionKey = "\uF71C";
|
||||
CPF26FunctionKey = "\uF71D";
|
||||
CPF27FunctionKey = "\uF71E";
|
||||
CPF28FunctionKey = "\uF71F";
|
||||
CPF29FunctionKey = "\uF720";
|
||||
CPF30FunctionKey = "\uF721";
|
||||
CPF31FunctionKey = "\uF722";
|
||||
CPF32FunctionKey = "\uF723";
|
||||
CPF33FunctionKey = "\uF724";
|
||||
CPF34FunctionKey = "\uF725";
|
||||
CPF35FunctionKey = "\uF726";
|
||||
CPInsertFunctionKey = "\uF727";
|
||||
CPDeleteFunctionKey = "\uF728";
|
||||
CPHomeFunctionKey = "\uF729";
|
||||
CPBeginFunctionKey = "\uF72A";
|
||||
CPEndFunctionKey = "\uF72B";
|
||||
CPPageUpFunctionKey = "\uF72C";
|
||||
CPPageDownFunctionKey = "\uF72D";
|
||||
CPPrintScreenFunctionKey = "\uF72E";
|
||||
CPScrollLockFunctionKey = "\uF72F";
|
||||
CPPauseFunctionKey = "\uF730";
|
||||
CPSysReqFunctionKey = "\uF731";
|
||||
CPBreakFunctionKey = "\uF732";
|
||||
CPResetFunctionKey = "\uF733";
|
||||
CPStopFunctionKey = "\uF734";
|
||||
CPMenuFunctionKey = "\uF735";
|
||||
CPUserFunctionKey = "\uF736";
|
||||
CPSystemFunctionKey = "\uF737";
|
||||
CPPrintFunctionKey = "\uF738";
|
||||
CPClearLineFunctionKey = "\uF739";
|
||||
CPClearDisplayFunctionKey = "\uF73A";
|
||||
CPInsertLineFunctionKey = "\uF73B";
|
||||
CPDeleteLineFunctionKey = "\uF73C";
|
||||
CPInsertCharFunctionKey = "\uF73D";
|
||||
CPDeleteCharFunctionKey = "\uF73E";
|
||||
CPPrevFunctionKey = "\uF73F";
|
||||
CPNextFunctionKey = "\uF740";
|
||||
CPSelectFunctionKey = "\uF741";
|
||||
CPExecuteFunctionKey = "\uF742";
|
||||
CPUndoFunctionKey = "\uF743";
|
||||
CPRedoFunctionKey = "\uF744";
|
||||
CPFindFunctionKey = "\uF745";
|
||||
CPHelpFunctionKey = "\uF746";
|
||||
CPModeSwitchFunctionKey = "\uF747";
|
||||
CPEscapeFunctionKey = "\u001B";
|
||||
|
||||
|
||||
CPDOMEventDoubleClick = "dblclick",
|
||||
CPDOMEventMouseDown = "mousedown",
|
||||
CPDOMEventMouseUp = "mouseup",
|
||||
CPDOMEventMouseMoved = "mousemove",
|
||||
CPDOMEventMouseDragged = "mousedrag",
|
||||
CPDOMEventKeyUp = "keyup",
|
||||
CPDOMEventKeyDown = "keydown",
|
||||
CPDOMEventKeyPress = "keypress";
|
||||
CPDOMEventCopy = "copy";
|
||||
CPDOMEventPaste = "paste";
|
||||
CPDOMEventScrollWheel = "mousewheel";
|
||||
CPDOMEventTouchStart = "touchstart";
|
||||
CPDOMEventTouchMove = "touchmove";
|
||||
CPDOMEventTouchEnd = "touchend";
|
||||
CPDOMEventTouchCancel = "touchcancel";
|
||||
|
||||
var _CPEventPeriodicEventPeriod = 0,
|
||||
_CPEventPeriodicEventTimer = nil;
|
||||
_CPEventPeriodicEventTimer = nil,
|
||||
_CPEventUpperCaseRegex = new RegExp("[A-Z]");
|
||||
|
||||
/*!
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPEvent
|
||||
CPEvent encapsulates the details of a Cappuccino keyboard or mouse event.
|
||||
@@ -155,7 +231,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)repeatKey keyCode:(unsigned short)code
|
||||
{
|
||||
return [[self alloc] _initKeyEventWithType:anEventType location:aPoint modifierFlags:modifierFlags
|
||||
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext
|
||||
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext
|
||||
characters:characters charactersIgnoringModifiers:unmodCharacters isARepeat:repeatKey keyCode:code];
|
||||
}
|
||||
|
||||
@@ -173,7 +249,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
@throws CPInternalInconsistencyException if an invalid event type is provided
|
||||
@return the new mouse event
|
||||
*/
|
||||
+ (id)mouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
||||
+ (id)mouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
||||
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
||||
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
|
||||
{
|
||||
@@ -204,12 +280,12 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
||||
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned)modifierFlags
|
||||
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
|
||||
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_type = anEventType;
|
||||
@@ -222,7 +298,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
_pressure = aPressure;
|
||||
_window = [CPApp windowWithWindowNumber:aWindowNumber];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -232,7 +308,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)isARepeat keyCode:(unsigned short)code
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_type = anEventType;
|
||||
@@ -246,7 +322,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
_keyCode = code;
|
||||
_windowNumber = aWindowNumber;
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -256,7 +332,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
subtype:(short)aSubtype data1:(int)aData1 data2:(int)aData2
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_type = anEventType;
|
||||
@@ -267,7 +343,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
_subtype = aSubtype;
|
||||
_data1 = aData1;
|
||||
_data2 = aData2;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -445,23 +521,76 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
return _deltaZ;
|
||||
}
|
||||
|
||||
- (BOOL)_triggersKeyEquivalent:(CPString)aKeyEquivalent withModifierMask:aKeyEquivalentModifierMask
|
||||
{
|
||||
if (!aKeyEquivalent)
|
||||
return NO;
|
||||
|
||||
if (_CPEventUpperCaseRegex.test(aKeyEquivalent))
|
||||
aKeyEquivalentModifierMask |= CPShiftKeyMask;
|
||||
|
||||
if (CPBrowserIsOperatingSystem(CPWindowsOperatingSystem) && (aKeyEquivalentModifierMask & CPCommandKeyMask))
|
||||
{
|
||||
aKeyEquivalentModifierMask |= CPControlKeyMask;
|
||||
aKeyEquivalentModifierMask &= ~CPCommandKeyMask;
|
||||
}
|
||||
|
||||
if ((_modifierFlags & (CPShiftKeyMask | CPAlternateKeyMask | CPCommandKeyMask | CPControlKeyMask)) !== aKeyEquivalentModifierMask)
|
||||
return NO;
|
||||
|
||||
// Treat \r and \n as the same key equivalent. See issue #710.
|
||||
if (_characters === CPNewlineCharacter || _characters === CPCarriageReturnCharacter)
|
||||
return CPNewlineCharacter === aKeyEquivalent || CPCarriageReturnCharacter === aKeyEquivalent;
|
||||
|
||||
return [_characters caseInsensitiveCompare:aKeyEquivalent] === CPOrderedSame;
|
||||
}
|
||||
|
||||
- (BOOL)_couldBeKeyEquivalent
|
||||
{
|
||||
if (_type !== CPKeyDown)
|
||||
return NO;
|
||||
|
||||
var characterCount = _characters.length;
|
||||
|
||||
if (!characterCount)
|
||||
return NO;
|
||||
|
||||
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
|
||||
return YES;
|
||||
|
||||
for(var i=0; i<characterCount; i++)
|
||||
{
|
||||
switch(_characters.charAt(i))
|
||||
{
|
||||
case CPBackspaceCharacter:
|
||||
case CPDeleteCharacter:
|
||||
case CPDeleteFunctionKey:
|
||||
case CPTabCharacter:
|
||||
case CPCarriageReturnCharacter:
|
||||
case CPNewlineCharacter:
|
||||
case CPEscapeFunctionKey:
|
||||
case CPPageUpFunctionKey:
|
||||
case CPPageDownFunctionKey:
|
||||
case CPLeftArrowFunctionKey:
|
||||
case CPUpArrowFunctionKey:
|
||||
case CPRightArrowFunctionKey:
|
||||
case CPDownArrowFunctionKey:
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
// FIXME: More cases? Space?
|
||||
return _type === CPKeyDown &&
|
||||
_modifierFlags & (CPCommandKeyMask | CPControlKeyMask) &&
|
||||
[_characters length] > 0;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*!
|
||||
Generates periodic events every \c aPeriod seconds.
|
||||
Gene rates periodic events every \c aPeriod seconds.
|
||||
@param aDelay the number of seconds before the first event
|
||||
@param aPeriod the length of time in seconds between successive events
|
||||
*/
|
||||
+ (void)startPeriodicEventsAfterDelay:(CPTimeInterval)aDelay withPeriod:(CPTimeInterval)aPeriod
|
||||
{
|
||||
_CPEventPeriodicEventPeriod = aPeriod;
|
||||
|
||||
|
||||
// FIXME: OH TIMERS!!!
|
||||
_CPEventPeriodicEventTimer = window.setTimeout(function() { _CPEventPeriodicEventTimer = window.setInterval(_CPEventFirePeriodEvent, aPeriod * 1000.0); }, aDelay * 1000.0);
|
||||
}
|
||||
@@ -473,9 +602,9 @@ var _CPEventPeriodicEventPeriod = 0,
|
||||
{
|
||||
if (_CPEventPeriodicEventTimer === nil)
|
||||
return;
|
||||
|
||||
|
||||
window.clearTimeout(_CPEventPeriodicEventTimer);
|
||||
|
||||
|
||||
_CPEventPeriodicEventTimer = nil;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,9 @@ function CPAppKitImage(aFilename, aSize)
|
||||
|
||||
var imageOrSize = AppKitImageForNames[aName];
|
||||
|
||||
if (!imageOrSize)
|
||||
return nil;
|
||||
|
||||
if (!imageOrSize.isa)
|
||||
{
|
||||
imageOrSize = CPAppKitImage("CPImage/" + aName + ".png", imageOrSize);
|
||||
@@ -205,17 +208,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
|
||||
|
||||
@@ -35,6 +35,16 @@ CPScaleProportionally = 0;
|
||||
CPScaleToFit = 1;
|
||||
CPScaleNone = 2;
|
||||
|
||||
CPImageAlignCenter = 0;
|
||||
CPImageAlignTop = 1;
|
||||
CPImageAlignTopLeft = 2;
|
||||
CPImageAlignTopRight = 3;
|
||||
CPImageAlignLeft = 4;
|
||||
CPImageAlignBottom = 5;
|
||||
CPImageAlignBottomLeft = 6;
|
||||
CPImageAlignBottomRight = 7;
|
||||
CPImageAlignRight = 8;
|
||||
|
||||
var CPImageViewShadowBackgroundColor = nil;
|
||||
|
||||
var LEFT_SHADOW_INSET = 3.0,
|
||||
@@ -52,14 +62,15 @@ var LEFT_SHADOW_INSET = 3.0,
|
||||
*/
|
||||
@implementation CPImageView : CPControl
|
||||
{
|
||||
DOMElement _DOMImageElement;
|
||||
DOMElement _DOMImageElement;
|
||||
|
||||
BOOL _hasShadow;
|
||||
CPView _shadowView;
|
||||
BOOL _hasShadow;
|
||||
CPView _shadowView;
|
||||
|
||||
BOOL _isEditable;
|
||||
BOOL _isEditable;
|
||||
|
||||
CGRect _imageRect;
|
||||
CGRect _imageRect;
|
||||
CPImageAlignment _imageAlignment;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -191,6 +202,30 @@ var LEFT_SHADOW_INSET = 3.0,
|
||||
[self hideOrDisplayContents];
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the type of image alignment that should be used to
|
||||
render the image.
|
||||
@param anImageAlignment the type of scaling to use
|
||||
*/
|
||||
- (void)setImageAlignment:(CPImageAlignment)anImageAlignment
|
||||
{
|
||||
if (_imageAlignment == anImageAlignment)
|
||||
return;
|
||||
|
||||
_imageAlignment = anImageAlignment;
|
||||
|
||||
if (![self image])
|
||||
return;
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (unsigned)imageAlignment
|
||||
{
|
||||
return _imageAlignment;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the type of image scaling that should be used to
|
||||
render the image.
|
||||
@@ -318,8 +353,45 @@ var LEFT_SHADOW_INSET = 3.0,
|
||||
#endif
|
||||
}
|
||||
|
||||
var x = (boundsWidth - width) / 2.0,
|
||||
y = (boundsHeight - height) / 2.0;
|
||||
var x, y;
|
||||
|
||||
switch (_imageAlignment)
|
||||
{
|
||||
case CPImageAlignLeft:
|
||||
case CPImageAlignTopLeft:
|
||||
case CPImageAlignBottomLeft:
|
||||
x = 0.0;
|
||||
break;
|
||||
|
||||
case CPImageAlignRight:
|
||||
case CPImageAlignTopRight:
|
||||
case CPImageAlignBottomRight:
|
||||
x = boundsWidth - width;
|
||||
break;
|
||||
|
||||
default:
|
||||
x = (boundsWidth - width) / 2.0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_imageAlignment)
|
||||
{
|
||||
case CPImageAlignTop:
|
||||
case CPImageAlignTopLeft:
|
||||
case CPImageAlignTopRight:
|
||||
y = 0.0;
|
||||
break;
|
||||
|
||||
case CPImageAlignBottom:
|
||||
case CPImageAlignBottomLeft:
|
||||
case CPImageAlignBottomRight:
|
||||
y = boundsHeight - height;
|
||||
break;
|
||||
|
||||
default:
|
||||
y = (boundsHeight - height) / 2.0;
|
||||
break;
|
||||
}
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
|
||||
@@ -380,10 +452,11 @@ var LEFT_SHADOW_INSET = 3.0,
|
||||
|
||||
@end
|
||||
|
||||
var CPImageViewImageKey = @"CPImageViewImageKey",
|
||||
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
|
||||
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey",
|
||||
CPImageViewIsEditableKey = @"CPImageViewIsEditableKey";
|
||||
var CPImageViewImageKey = @"CPImageViewImageKey",
|
||||
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
|
||||
CPImageViewImageAlignmentKey = @"CPImageViewImageAlignmentKey",
|
||||
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey",
|
||||
CPImageViewIsEditableKey = @"CPImageViewIsEditableKey";
|
||||
|
||||
@implementation CPImageView (CPCoding)
|
||||
|
||||
@@ -416,6 +489,7 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
||||
#endif
|
||||
|
||||
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
|
||||
[self setImageAlignment:[aCoder decodeIntForKey:CPImageViewImageAlignmentKey]];
|
||||
|
||||
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
|
||||
[self setEditable:YES];
|
||||
@@ -450,6 +524,7 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
||||
_subviews = actualSubviews;
|
||||
|
||||
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
|
||||
[aCoder encodeInt:_imageAlignment forKey:CPImageViewImageAlignmentKey];
|
||||
|
||||
if (_isEditable)
|
||||
[aCoder encodeBool:_isEditable forKey:CPImageViewIsEditableKey];
|
||||
|
||||
@@ -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
|
||||
@@ -108,7 +108,7 @@ var CPBindingOperationAnd = 0,
|
||||
count = allKeys.length;
|
||||
|
||||
while (count--)
|
||||
[anObject unbind:[bindings objectForKey:allKeys[count]]]
|
||||
[anObject unbind:[bindings objectForKey:allKeys[count]]];
|
||||
|
||||
[bindingsMap removeObjectForKey:[anObject hash]];
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@ var _CPMenuBarVisible = NO,
|
||||
_CPMenuBarAttributes = nil,
|
||||
_CPMenuBarSharedWindow = nil;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPMenu
|
||||
|
||||
Menus provide the user with a list of actions and/or submenus. Submenus themselves are full fledged menus
|
||||
Menus provide the user with a list of actions and/or submenus. Submenus themselves are full fledged menus
|
||||
and so a heirarchical structure appears.
|
||||
*/
|
||||
@implementation CPMenu : CPObject
|
||||
@@ -69,12 +69,12 @@ var _CPMenuBarVisible = NO,
|
||||
float _minimumWidth;
|
||||
|
||||
CPMutableArray _items;
|
||||
|
||||
|
||||
BOOL _autoenablesItems;
|
||||
BOOL _showsStateColumn;
|
||||
|
||||
id _delegate;
|
||||
|
||||
|
||||
CPMenuItem _highlightedIndex;
|
||||
_CPMenuWindow _menuWindow;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if (_CPMenuBarVisible === menuBarShouldBeVisible)
|
||||
return;
|
||||
|
||||
|
||||
_CPMenuBarVisible = menuBarShouldBeVisible;
|
||||
|
||||
if ([CPPlatform supportsNativeMainMenu])
|
||||
@@ -105,13 +105,13 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if (!_CPMenuBarSharedWindow)
|
||||
_CPMenuBarSharedWindow = [[_CPMenuBarWindow alloc] init];
|
||||
|
||||
|
||||
[_CPMenuBarSharedWindow setMenu:[CPApp mainMenu]];
|
||||
|
||||
|
||||
[_CPMenuBarSharedWindow setTitle:_CPMenuBarTitle];
|
||||
[_CPMenuBarSharedWindow setIconImage:_CPMenuBarIconImage];
|
||||
[_CPMenuBarSharedWindow setIconImageAlphaValue:_CPMenuBarIconImageAlphaValue];
|
||||
|
||||
|
||||
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
|
||||
[_CPMenuBarSharedWindow setTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextColor"]];
|
||||
[_CPMenuBarSharedWindow setTitleColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTitleColor"]];
|
||||
@@ -120,12 +120,12 @@ var _CPMenuBarVisible = NO,
|
||||
[_CPMenuBarSharedWindow setHighlightColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightColor"]];
|
||||
[_CPMenuBarSharedWindow setHighlightTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightTextColor"]];
|
||||
[_CPMenuBarSharedWindow setHighlightTextShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightTextShadowColor"]];
|
||||
|
||||
|
||||
[_CPMenuBarSharedWindow orderFront:self];
|
||||
}
|
||||
else
|
||||
[_CPMenuBarSharedWindow orderOut:self];
|
||||
|
||||
|
||||
// FIXME: There must be a better way to do this.
|
||||
#if PLATFORM(DOM)
|
||||
[[CPPlatformWindow primaryPlatformWindow] resizeEvent:nil];
|
||||
@@ -159,9 +159,9 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if (_CPMenuBarAttributes == attributes)
|
||||
return;
|
||||
|
||||
|
||||
_CPMenuBarAttributes = [attributes copy];
|
||||
|
||||
|
||||
var textColor = [attributes objectForKey:@"CPMenuBarTextColor"],
|
||||
titleColor = [attributes objectForKey:@"CPMenuBarTitleColor"],
|
||||
textShadowColor = [attributes objectForKey:@"CPMenuBarTextShadowColor"],
|
||||
@@ -169,40 +169,40 @@ var _CPMenuBarVisible = NO,
|
||||
highlightColor = [attributes objectForKey:@"CPMenuBarHighlightColor"],
|
||||
highlightTextColor = [attributes objectForKey:@"CPMenuBarHighlightTextColor"],
|
||||
highlightTextShadowColor = [attributes objectForKey:@"CPMenuBarHighlightTextShadowColor"];
|
||||
|
||||
|
||||
if (!textColor && titleColor)
|
||||
[_CPMenuBarAttributes setObject:titleColor forKey:@"CPMenuBarTextColor"];
|
||||
|
||||
|
||||
else if (textColor && !titleColor)
|
||||
[_CPMenuBarAttributes setObject:textColor forKey:@"CPMenuBarTitleColor"];
|
||||
|
||||
|
||||
else if (!textColor && !titleColor)
|
||||
{
|
||||
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTextColor"];
|
||||
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTitleColor"];
|
||||
}
|
||||
|
||||
|
||||
if (!textShadowColor && titleShadowColor)
|
||||
[_CPMenuBarAttributes setObject:titleShadowColor forKey:@"CPMenuBarTextShadowColor"];
|
||||
|
||||
|
||||
else if (textShadowColor && !titleShadowColor)
|
||||
[_CPMenuBarAttributes setObject:textShadowColor forKey:@"CPMenuBarTitleShadowColor"];
|
||||
|
||||
|
||||
else if (!textShadowColor && !titleShadowColor)
|
||||
{
|
||||
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTextShadowColor"];
|
||||
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTitleShadowColor"];
|
||||
}
|
||||
|
||||
|
||||
if (!highlightColor)
|
||||
[_CPMenuBarAttributes setObject:[CPColor colorWithCalibratedRed:94.0/255.0 green:130.0/255.0 blue:186.0/255.0 alpha:1.0] forKey:@"CPMenuBarHighlightColor"];
|
||||
|
||||
|
||||
if (!highlightTextColor)
|
||||
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarHighlightTextColor"];
|
||||
|
||||
|
||||
if (!highlightTextShadowColor)
|
||||
[_CPMenuBarAttributes setObject:[CPColor blackColor] forKey:@"CPMenuBarHighlightTextShadowColor"];
|
||||
|
||||
|
||||
if (_CPMenuBarSharedWindow)
|
||||
{
|
||||
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
|
||||
@@ -231,7 +231,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if (self === [CPApp mainMenu])
|
||||
return MENUBAR_HEIGHT;
|
||||
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@@ -249,18 +249,18 @@ var _CPMenuBarVisible = NO,
|
||||
- (id)initWithTitle:(CPString)aTitle
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_title = aTitle;
|
||||
_items = [];
|
||||
|
||||
|
||||
_autoenablesItems = YES;
|
||||
_showsStateColumn = YES;
|
||||
|
||||
[self setMinimumWidth:0];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ var _CPMenuBarVisible = NO,
|
||||
|
||||
[aMenuItem setMenu:self];
|
||||
[_items insertObject:aMenuItem atIndex:anIndex];
|
||||
|
||||
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPMenuDidAddItemNotification
|
||||
object:self
|
||||
@@ -306,7 +306,7 @@ var _CPMenuBarVisible = NO,
|
||||
- (CPMenuItem)insertItemWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent atIndex:(unsigned)anIndex
|
||||
{
|
||||
var item = [[CPMenuItem alloc] initWithTitle:aTitle action:anAction keyEquivalent:aKeyEquivalent];
|
||||
|
||||
|
||||
[self insertItem:item atIndex:anIndex];
|
||||
|
||||
return item;
|
||||
@@ -351,10 +351,10 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if (anIndex < 0 || anIndex >= _items.length)
|
||||
return;
|
||||
|
||||
|
||||
[_items[anIndex] setMenu:nil];
|
||||
[_items removeObjectAtIndex:anIndex];
|
||||
|
||||
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPMenuDidRemoveItemNotification
|
||||
object:self
|
||||
@@ -369,7 +369,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if ([aMenuItem menu] != self)
|
||||
return;
|
||||
|
||||
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPMenuDidChangeItemNotification
|
||||
object:self
|
||||
@@ -385,10 +385,10 @@ var _CPMenuBarVisible = NO,
|
||||
- (CPMenuItem)itemWithTag:(int)aTag
|
||||
{
|
||||
var index = [self indexOfItemWithTag:aTag];
|
||||
|
||||
|
||||
if (index == CPNotFound)
|
||||
return nil;
|
||||
|
||||
|
||||
return _items[index];
|
||||
}
|
||||
|
||||
@@ -400,10 +400,10 @@ var _CPMenuBarVisible = NO,
|
||||
- (CPMenuItem)itemWithTitle:(CPString)aTitle
|
||||
{
|
||||
var index = [self indexOfItemWithTitle:aTitle];
|
||||
|
||||
|
||||
if (index == CPNotFound)
|
||||
return nil;
|
||||
|
||||
|
||||
return _items[index];
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
if ([aMenuItem menu] !== self)
|
||||
return CPNotFound;
|
||||
|
||||
|
||||
return [_items indexOfObjectIdenticalTo:aMenuItem];
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
var index = 0,
|
||||
count = _items.length;
|
||||
|
||||
|
||||
for (; index < count; ++index)
|
||||
if ([_items[index] title] === aTitle)
|
||||
return index;
|
||||
@@ -472,7 +472,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
var index = 0,
|
||||
count = _items.length;
|
||||
|
||||
|
||||
for (; index < count; ++index)
|
||||
if ([_items[index] tag] == aTag)
|
||||
return index;
|
||||
@@ -490,11 +490,11 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
var index = 0,
|
||||
count = _items.length;
|
||||
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
var item = _items[index];
|
||||
|
||||
|
||||
if ([item target] == aTarget && (!anAction || [item action] == anAction))
|
||||
return index;
|
||||
}
|
||||
@@ -511,7 +511,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
var index = 0,
|
||||
count = _items.length;
|
||||
|
||||
|
||||
for (; index < count; ++index)
|
||||
if ([[_items[index] representedObject] isEqual:anObject])
|
||||
return index;
|
||||
@@ -528,7 +528,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
var index = 0,
|
||||
count = _items.length;
|
||||
|
||||
|
||||
for (; index < count; ++index)
|
||||
if ([_items[index] submenu] == aMenu)
|
||||
return index;
|
||||
@@ -546,7 +546,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
[aMenuItem setTarget:aMenuItem];
|
||||
[aMenuItem setAction:@selector(submenuAction:)];
|
||||
|
||||
|
||||
[aMenuItem setSubmenu:aMenu];
|
||||
}
|
||||
|
||||
@@ -683,7 +683,7 @@ var _CPMenuBarVisible = NO,
|
||||
itemIndex = [self indexOfItem:anItem];
|
||||
|
||||
if (itemIndex === CPNotFound)
|
||||
throw "In call to popUpMenuPositioningItem:atLocation:inView:callback:, menu item " +
|
||||
throw "In call to popUpMenuPositioningItem:atLocation:inView:callback:, menu item " +
|
||||
anItem + " is not present in menu " + self;
|
||||
}
|
||||
|
||||
@@ -784,10 +784,10 @@ var _CPMenuBarVisible = NO,
|
||||
+ (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont
|
||||
{
|
||||
var delegate = [aMenu delegate];
|
||||
|
||||
|
||||
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
|
||||
[delegate menuWillOpen:aMenu];
|
||||
|
||||
|
||||
if (!aFont)
|
||||
aFont = [CPFont systemFontOfSize:12.0];
|
||||
|
||||
@@ -938,17 +938,7 @@ var _CPMenuBarVisible = NO,
|
||||
var item = _items[index],
|
||||
modifierMask = [item keyEquivalentModifierMask];
|
||||
|
||||
if ([item keyEquivalent] === [[item keyEquivalent] uppercaseString])
|
||||
modifierMask |= CPShiftKeyMask;
|
||||
|
||||
if (CPBrowserIsOperatingSystem(CPWindowsOperatingSystem) && (modifierMask & CPCommandKeyMask))
|
||||
{
|
||||
modifierMask |= CPControlKeyMask;
|
||||
modifierMask &= ~CPCommandKeyMask;
|
||||
}
|
||||
|
||||
if ((modifierFlags & (CPShiftKeyMask | CPAlternateKeyMask | CPCommandKeyMask | CPControlKeyMask)) == modifierMask &&
|
||||
[characters caseInsensitiveCompare:[item keyEquivalent]] == CPOrderedSame)
|
||||
if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[item keyEquivalentModifierMask]])
|
||||
{
|
||||
if ([item isEnabled])
|
||||
[self performActionForItemAtIndex:index];
|
||||
@@ -956,7 +946,7 @@ var _CPMenuBarVisible = NO,
|
||||
{
|
||||
//beep?
|
||||
}
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -975,7 +965,7 @@ var _CPMenuBarVisible = NO,
|
||||
- (void)performActionForItemAtIndex:(unsigned)anIndex
|
||||
{
|
||||
var item = _items[anIndex];
|
||||
|
||||
|
||||
[CPApp sendAction:[item action] to:[item target] from:item];
|
||||
}
|
||||
|
||||
@@ -1064,7 +1054,7 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_title = [aCoder decodeObjectForKey:CPMenuTitleKey];
|
||||
@@ -1076,7 +1066,7 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
|
||||
|
||||
[self setMinimumWidth:0];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ var SharedMenuManager = nil;
|
||||
|
||||
// Close Menu Event.
|
||||
if (type === CPAppKitDefined)
|
||||
return [self completeTracking]
|
||||
return [self completeTracking];
|
||||
|
||||
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES];
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
@import "CPView.j"
|
||||
@import "_CPMenuItemView.j"
|
||||
|
||||
/*!
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPMenuItem
|
||||
|
||||
@@ -43,39 +43,39 @@
|
||||
|
||||
CPString _title;
|
||||
//CPAttributedString _attributedTitle;
|
||||
|
||||
|
||||
CPFont _font;
|
||||
|
||||
|
||||
id _target;
|
||||
SEL _action;
|
||||
|
||||
|
||||
BOOL _isEnabled;
|
||||
BOOL _isHidden;
|
||||
|
||||
|
||||
int _tag;
|
||||
int _state;
|
||||
|
||||
|
||||
CPImage _image;
|
||||
CPImage _alternateImage;
|
||||
CPImage _onStateImage;
|
||||
CPImage _offStateImage;
|
||||
CPImage _mixedStateImage;
|
||||
|
||||
|
||||
CPMenu _submenu;
|
||||
CPMenu _menu;
|
||||
|
||||
|
||||
CPString _keyEquivalent;
|
||||
unsigned _keyEquivalentModifierMask;
|
||||
|
||||
|
||||
int _mnemonicLocation;
|
||||
|
||||
|
||||
BOOL _isAlternate;
|
||||
int _indentationLevel;
|
||||
|
||||
|
||||
CPString _toolTip;
|
||||
id _representedObject;
|
||||
CPView _view;
|
||||
|
||||
|
||||
_CPMenuItemView _menuItemView;
|
||||
}
|
||||
|
||||
@@ -94,19 +94,19 @@
|
||||
- (id)initWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_isSeparator = NO;
|
||||
|
||||
_title = aTitle;
|
||||
_action = anAction;
|
||||
|
||||
|
||||
_isEnabled = YES;
|
||||
|
||||
|
||||
_tag = 0;
|
||||
_state = CPOffState;
|
||||
|
||||
|
||||
_keyEquivalent = aKeyEquivalent || @"";
|
||||
_keyEquivalentModifierMask = CPPlatformActionKeyMask;
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
_mnemonicLocation = CPNotFound;
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
if (_isHidden == isHidden)
|
||||
return;
|
||||
|
||||
|
||||
_isHidden = isHidden;
|
||||
|
||||
[_menu itemChanged:self];
|
||||
@@ -173,9 +173,9 @@
|
||||
{
|
||||
if (_isHidden)
|
||||
return YES;
|
||||
|
||||
|
||||
var supermenu = [_menu supermenu];
|
||||
|
||||
|
||||
if ([[supermenu itemAtIndex:[supermenu indexOfItemWithSubmenu:_menu]] isHiddenOrHasHiddenAncestor])
|
||||
return YES;
|
||||
|
||||
@@ -228,11 +228,11 @@
|
||||
|
||||
if (_title == aTitle)
|
||||
return;
|
||||
|
||||
|
||||
_title = aTitle;
|
||||
|
||||
|
||||
[_menuItemView setDirty];
|
||||
|
||||
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
|
||||
@@ -260,11 +260,11 @@
|
||||
{
|
||||
if (_font == aFont)
|
||||
return;
|
||||
|
||||
|
||||
_font = aFont;
|
||||
|
||||
[_menu itemChanged:self];
|
||||
|
||||
|
||||
[_menuItemView setDirty];
|
||||
}
|
||||
|
||||
@@ -316,9 +316,9 @@ CPOffState
|
||||
{
|
||||
if (_state == aState)
|
||||
return;
|
||||
|
||||
|
||||
_state = aState;
|
||||
|
||||
|
||||
[_menu itemChanged:self];
|
||||
|
||||
[_menuItemView setDirty];
|
||||
@@ -346,11 +346,11 @@ CPOffState
|
||||
{
|
||||
if (_image == anImage)
|
||||
return;
|
||||
|
||||
|
||||
_image = anImage;
|
||||
|
||||
[_menuItemView setDirty];
|
||||
|
||||
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ CPOffState
|
||||
{
|
||||
if (_onStateImage == anImage)
|
||||
return;
|
||||
|
||||
|
||||
_onStateImage = anImage;
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
@@ -409,7 +409,7 @@ CPOffState
|
||||
{
|
||||
if (_offStateImage == anImage)
|
||||
return;
|
||||
|
||||
|
||||
_offStateImage = anImage;
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
@@ -430,7 +430,7 @@ CPOffState
|
||||
{
|
||||
if (_mixedStateImage == anImage)
|
||||
return;
|
||||
|
||||
|
||||
_mixedStateImage = anImage;
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
@@ -648,14 +648,14 @@ CPControlKeyMask
|
||||
- (void)setTitleWithMnemonicLocation:(CPString)aTitle
|
||||
{
|
||||
var location = [aTitle rangeOfString:@"&"].location;
|
||||
|
||||
|
||||
if (location == CPNotFound)
|
||||
[self setTitle:aTitle];
|
||||
else
|
||||
{
|
||||
[self setTitle:[aTitle substringToIndex:location] + [aTitle substringFromIndex:location + 1]];
|
||||
[self setMnemonicLocation:location];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -696,7 +696,7 @@ CPControlKeyMask
|
||||
{
|
||||
if (aLevel < 0)
|
||||
[CPException raise:CPInvalidArgumentException reason:"setIndentationLevel: argument must be greater than or equal to 0."];
|
||||
|
||||
|
||||
_indentationLevel = MIN(15, aLevel);
|
||||
}
|
||||
|
||||
@@ -755,11 +755,11 @@ CPControlKeyMask
|
||||
{
|
||||
if (_view === aView)
|
||||
return;
|
||||
|
||||
|
||||
_view = aView;
|
||||
|
||||
|
||||
[_menuItemView setDirty];
|
||||
|
||||
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
|
||||
@@ -790,7 +790,7 @@ CPControlKeyMask
|
||||
{
|
||||
if (!_menuItemView)
|
||||
_menuItemView = [[_CPMenuItemView alloc] initWithFrame:CGRectMakeZero() forMenuItem:self];
|
||||
|
||||
|
||||
return _menuItemView;
|
||||
}
|
||||
|
||||
@@ -844,15 +844,15 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_isSeparator = [aCoder containsValueForKey:CPMenuItemIsSeparatorKey] && [aCoder decodeBoolForKey:CPMenuItemIsSeparatorKey];
|
||||
|
||||
_title = [aCoder decodeObjectForKey:CPMenuItemTitleKey];
|
||||
|
||||
|
||||
// _font;
|
||||
|
||||
|
||||
_target = [aCoder decodeObjectForKey:CPMenuItemTargetKey];
|
||||
_action = [aCoder decodeObjectForKey:CPMenuItemActionKey];
|
||||
|
||||
@@ -887,7 +887,7 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
|
||||
_representedObject = DEFAULT_VALUE(CPMenuItemRepresentedObjectKey, nil);
|
||||
_view = DEFAULT_VALUE(CPMenuItemViewKey, nil);
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -901,11 +901,11 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
|
||||
[aCoder encodeBool:_isSeparator forKey:CPMenuItemIsSeparatorKey];
|
||||
|
||||
[aCoder encodeObject:_title forKey:CPMenuItemTitleKey];
|
||||
|
||||
|
||||
[aCoder encodeObject:_target forKey:CPMenuItemTargetKey];
|
||||
[aCoder encodeObject:_action forKey:CPMenuItemActionKey];
|
||||
|
||||
ENCODE_IFNOT(CPMenuItemIsEnabledKey, _isEnabled, YES);
|
||||
ENCODE_IFNOT(CPMenuItemIsEnabledKey, _isEnabled, YES);
|
||||
ENCODE_IFNOT(CPMenuItemIsHiddenKey, _isHidden, NO);
|
||||
|
||||
ENCODE_IFNOT(CPMenuItemTagKey, _tag, 0);
|
||||
@@ -913,7 +913,7 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
|
||||
|
||||
ENCODE_IFNOT(CPMenuItemImageKey, _image, nil);
|
||||
ENCODE_IFNOT(CPMenuItemAlternateImageKey, _alternateImage, nil);
|
||||
|
||||
|
||||
ENCODE_IFNOT(CPMenuItemSubmenuKey, _submenu, nil);
|
||||
ENCODE_IFNOT(CPMenuItemMenuKey, _menu, nil);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
|
||||
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
|
||||
|
||||
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
|
||||
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]
|
||||
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
|
||||
|
||||
var bundle = [CPBundle bundleForClass:self];
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ var _CPMenuItemSelectionColor = nil,
|
||||
return;
|
||||
|
||||
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
|
||||
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]
|
||||
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
|
||||
|
||||
var bundle = [CPBundle bundleForClass:self];
|
||||
|
||||
|
||||
@@ -1245,13 +1245,34 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
CGContextAddLineToPoint(context, 0.0, 0.0);
|
||||
|
||||
|
||||
CGContextClosePath(context);
|
||||
var isHighlighted = [self hasThemeState:CPThemeStateHighlighted];
|
||||
var color = [self hasThemeState:CPThemeStateSelected] ? (isHighlighted ? [CPColor lightGrayColor] : [CPColor whiteColor]) : (isHighlighted ? [CPColor blackColor] : [CPColor grayColor]);
|
||||
|
||||
CGContextSetFillColor(context, color);
|
||||
CGContextSetFillColor(context,
|
||||
colorForDisclosureTriangle([self hasThemeState:CPThemeStateSelected],
|
||||
[self hasThemeState:CPThemeStateHighlighted]));
|
||||
CGContextFillPath(context);
|
||||
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
if(_angle === 0.0) {
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
} else {
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
}
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.8]);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var colorForDisclosureTriangle = function(isSelected, isHighlighted) {
|
||||
return isSelected
|
||||
? (isHighlighted
|
||||
? [CPColor colorWithCalibratedWhite:0.9 alpha: 1.0]
|
||||
: [CPColor colorWithCalibratedWhite:1.0 alpha: 1.0])
|
||||
: (isHighlighted
|
||||
? [CPColor colorWithCalibratedWhite:0.4 alpha: 1.0]
|
||||
: [CPColor colorWithCalibratedWhite:0.5 alpha: 1.0]);
|
||||
}
|
||||
|
||||
@@ -22,23 +22,23 @@
|
||||
|
||||
@import <Foundation/CPObject.j>
|
||||
|
||||
|
||||
CPDeleteKeyCode = 8;
|
||||
CPTabKeyCode = 9;
|
||||
CPReturnKeyCode = 13;
|
||||
CPEscapeKeyCode = 27;
|
||||
CPSpaceKeyCode = 32;
|
||||
CPPageUpKeyCode = 33;
|
||||
CPPageDownKeyCode = 34;
|
||||
CPLeftArrowKeyCode = 37;
|
||||
CPUpArrowKeyCode = 38;
|
||||
CPRightArrowKeyCode = 39;
|
||||
CPDownArrowKeyCode = 40;
|
||||
CPDeleteKeyCode = 8;
|
||||
CPTabKeyCode = 9;
|
||||
CPReturnKeyCode = 13;
|
||||
CPEscapeKeyCode = 27;
|
||||
CPSpaceKeyCode = 32;
|
||||
CPPageUpKeyCode = 33;
|
||||
CPPageDownKeyCode = 34;
|
||||
CPLeftArrowKeyCode = 37;
|
||||
CPUpArrowKeyCode = 38;
|
||||
CPRightArrowKeyCode = 39;
|
||||
CPDownArrowKeyCode = 40;
|
||||
CPDeleteForwardKeyCode = 46;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPResponder
|
||||
|
||||
|
||||
Subclasses of CPResonder can be part of the responder chain.
|
||||
*/
|
||||
@implementation CPResponder : CPObject
|
||||
@@ -104,42 +104,24 @@ CPDownArrowKeyCode = 40;
|
||||
|
||||
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 keyCode])
|
||||
if (selectorNames)
|
||||
{
|
||||
case CPPageUpKeyCode: [self doCommandBySelector:@selector(pageUp:)];
|
||||
break;
|
||||
case CPPageDownKeyCode: [self doCommandBySelector:@selector(pageDown:)];
|
||||
break;
|
||||
case CPLeftArrowKeyCode: [self doCommandBySelector:@selector(moveLeft:)];
|
||||
break;
|
||||
case CPRightArrowKeyCode: [self doCommandBySelector:@selector(moveRight:)];
|
||||
break;
|
||||
case CPUpArrowKeyCode: [self doCommandBySelector:@selector(moveUp:)];
|
||||
break;
|
||||
case CPDownArrowKeyCode: [self doCommandBySelector:@selector(moveDown:)];
|
||||
break;
|
||||
case CPDeleteKeyCode: [self doCommandBySelector:@selector(deleteBackward:)];
|
||||
break;
|
||||
case CPReturnKeyCode:
|
||||
case 3: [self doCommandBySelector:@selector(insertLineBreak:)];
|
||||
break;
|
||||
|
||||
case CPEscapeKeyCode: [self doCommandBySelector:@selector(cancel:)];
|
||||
break;
|
||||
for (var s = 0, scount = selectorNames.length; s < scount; s++)
|
||||
{
|
||||
var selector = selectorNames[s];
|
||||
if (!selector)
|
||||
continue;
|
||||
|
||||
case CPTabKeyCode: var shift = [event modifierFlags] & CPShiftKeyMask;
|
||||
|
||||
if (!shift)
|
||||
[self doCommandBySelector:@selector(insertTab:)];
|
||||
else
|
||||
[self doCommandBySelector:@selector(insertBackTab:)];
|
||||
|
||||
break;
|
||||
|
||||
default: [self insertText:[event characters]];
|
||||
[self doCommandBySelector:CPSelectorFromString(selector)];
|
||||
}
|
||||
}
|
||||
else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)) && [self respondsToSelector:@selector(insertText:)])
|
||||
[self insertText:[event characters]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +221,15 @@ CPDownArrowKeyCode = 40;
|
||||
[_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.
|
||||
@@ -315,7 +306,7 @@ CPDownArrowKeyCode = 40;
|
||||
if([self respondsToSelector:aSelector])
|
||||
{
|
||||
[self performSelector:aSelector withObject:anObject];
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -366,10 +357,10 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey";
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
_nextResponder = [aCoder decodeObjectForKey:CPResponderNextResponderKey];
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ var CPSplitViewHorizontalImage = nil,
|
||||
_isPaneSplitter = shouldBePaneSplitter;
|
||||
|
||||
if(_DOMDividerElements[_drawingDivider])
|
||||
[self _setupDOMDivider]
|
||||
[self _setupDOMDivider];
|
||||
|
||||
// The divider changes size when pane splitter mode is toggled, so the
|
||||
// subviews need to change size too.
|
||||
|
||||
@@ -654,9 +654,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
return;
|
||||
|
||||
_sourceListActiveGradient = [aDictionary valueForKey:CPSourceListGradient];
|
||||
_sourceListActiveTopLineColor = [aDictionary valueForKey:CPSourceListTopLineColor]
|
||||
_sourceListActiveTopLineColor = [aDictionary valueForKey:CPSourceListTopLineColor];
|
||||
_sourceListActiveBottomLineColor = [aDictionary valueForKey:CPSourceListBottomLineColor];
|
||||
[self setNeedsDisplay:YES]
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -909,6 +909,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
else
|
||||
_selectedRowIndexes = [rows copy];
|
||||
|
||||
// update last selected row
|
||||
_lastSelectedRow = ([rows count] > 0) ? [rows lastIndex] : -1;
|
||||
|
||||
[self _updateHighlightWithOldRows:previousSelectedIndexes newRows:_selectedRowIndexes];
|
||||
[_tableDrawView display]; // FIXME: should be setNeedsDisplayInRect:enclosing rect of new (de)selected rows
|
||||
// but currently -drawRect: is not implemented here
|
||||
@@ -1020,7 +1023,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
|
||||
- (int)selectedRow
|
||||
{
|
||||
return [_selectedRowIndexes lastIndex];
|
||||
return _lastSelectedRow;
|
||||
}
|
||||
|
||||
- (CPIndexSet)selectedRowIndexes
|
||||
@@ -3067,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];
|
||||
@@ -3268,8 +3272,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
}
|
||||
}
|
||||
|
||||
_lastSelectedRow = ([newSelection count] > 0) ? aRow : -1;
|
||||
|
||||
// if empty selection is not allowed and the new selection has nothing selected, abort
|
||||
if (!_allowsEmptySelection && [newSelection count] === 0)
|
||||
return;
|
||||
@@ -3358,6 +3360,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
[self scrollRowToVisible:i];
|
||||
}
|
||||
|
||||
- (void)moveDownAndModifySelection:(id)sender
|
||||
{
|
||||
[self moveDown:sender];
|
||||
}
|
||||
|
||||
- (void)moveUp:(id)sender
|
||||
{
|
||||
if (_implementedDelegateMethods & CPTableViewDelegate_selectionShouldChangeInTableView_ &&
|
||||
@@ -3405,6 +3412,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
[self scrollRowToVisible:i];
|
||||
}
|
||||
|
||||
- (void)moveUpAndModifySelection:(id)sender
|
||||
{
|
||||
[self moveUp:sender];
|
||||
}
|
||||
|
||||
- (void)deleteBackward:(id)sender
|
||||
{
|
||||
if([_delegate respondsToSelector: @selector(tableViewDeleteKeyPressed:)])
|
||||
@@ -3481,7 +3493,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
_gridColor = [aCoder decodeObjectForKey:CPTableViewGridColorKey] || [CPColor grayColor];
|
||||
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey] || CPTableViewGridNone;
|
||||
|
||||
_usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey]
|
||||
_usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey];
|
||||
_alternatingRowBackgroundColors =
|
||||
[[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]];
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* CPText.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Alexander Ljungberg.
|
||||
* Copyright 2010, WireLoad, LLC.
|
||||
*
|
||||
* 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 "CPView.j"
|
||||
|
||||
CPEnterCharacter = "\u0003";
|
||||
CPBackspaceCharacter = "\u0008";
|
||||
CPTabCharacter = "\u0009";
|
||||
CPNewlineCharacter = "\u000a";
|
||||
CPFormFeedCharacter = "\u000c";
|
||||
CPCarriageReturnCharacter = "\u000d";
|
||||
CPBackTabCharacter = "\u0019";
|
||||
CPDeleteCharacter = "\u007f";
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1679,7 +1679,7 @@ setBoundsOrigin:
|
||||
var theWindow = [self window];
|
||||
|
||||
[theWindow _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
|
||||
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes]
|
||||
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes];
|
||||
[theWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
|
||||
|
||||
_registeredDraggedTypesArray = nil;
|
||||
|
||||
@@ -79,9 +79,9 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
||||
while (animationIndex--)
|
||||
{
|
||||
var dictionary = [_viewAnimations objectAtIndex:animationIndex],
|
||||
view = [self _targetView:dictionary]
|
||||
startFrame = [self _startFrame:dictionary]
|
||||
endFrame = [self _endFrame:dictionary]
|
||||
view = [self _targetView:dictionary],
|
||||
startFrame = [self _startFrame:dictionary],
|
||||
endFrame = [self _endFrame:dictionary],
|
||||
differenceFrame = _CGRectMakeZero();
|
||||
|
||||
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
|
||||
|
||||
@@ -194,13 +194,13 @@ var SHADOW_MARGIN_LEFT = 20.0,
|
||||
SHADOW_MARGIN_TOP = 10.0,
|
||||
SHADOW_MARGIN_BOTTOM = 10.0,
|
||||
SHADOW_DISTANCE = 5.0,
|
||||
|
||||
|
||||
_CPWindowShadowColor = nil;
|
||||
|
||||
|
||||
var CPWindowSaveImage = nil,
|
||||
CPWindowSavingImage = nil;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPWindow
|
||||
|
||||
@@ -213,33 +213,33 @@ var CPWindowSaveImage = nil,
|
||||
<p>A window always contains a content view which is the highest level view available for public (application) use. This view fills the area of the window inside any decoration/border. This is the only part of the window that application programmers are allowed to draw in directly.</p>
|
||||
|
||||
<p>You can convert between view coordinates and window base coordinates using the [CPView -convertPoint:fromView:], [CPView -convertPoint:toView:], [CPView -convertRect:fromView:], and [CPView -convertRect:toView:] methods with a nil view argument.
|
||||
|
||||
|
||||
@par Delegate Methods
|
||||
|
||||
|
||||
@delegate -(void)windowDidResize:(CPNotification)notification;
|
||||
Sent from the notification center when the window has been resized.
|
||||
@param notification contains information about the resize event
|
||||
|
||||
|
||||
@delegate -(CPUndoManager)windowWillReturnUndoManager:(CPWindow)window;
|
||||
Called to obtain the undo manager for a window
|
||||
@param window the window for which to return the undo manager
|
||||
@return the window's undo manager
|
||||
|
||||
|
||||
@delegate -(void)windowDidBecomeMain:(CPNotification)notification;
|
||||
Sent from the notification center when the delegate's window becomes
|
||||
the main window.
|
||||
@param notification contains information about the event
|
||||
|
||||
|
||||
@delegate -(void)windowDidResignMain:(CPNotification)notification;
|
||||
Sent from the notification center when the delegate's window has
|
||||
resigned main window status.
|
||||
@param notification contains information about the event
|
||||
|
||||
|
||||
@delegate -(void)windowDidResignKey:(CPNotification)notification;
|
||||
Sent from the notification center when the delegate's window has
|
||||
resigned key window status.
|
||||
@param notification contains information about the event
|
||||
|
||||
|
||||
@delegate -(BOOL)windowShouldClose:(id)window;
|
||||
Called when the user tries to close the window.
|
||||
@param window the window to close
|
||||
@@ -311,15 +311,17 @@ var CPWindowSaveImage = nil,
|
||||
#endif
|
||||
|
||||
unsigned _autoresizingMask;
|
||||
|
||||
|
||||
BOOL _delegateRespondsToWindowWillReturnUndoManagerSelector;
|
||||
|
||||
BOOL _isFullPlatformWindow;
|
||||
_CPWindowFullPlatformWindowSession _fullPlatformWindowSession;
|
||||
|
||||
|
||||
CPDictionary _sheetContext;
|
||||
CPWindow _parentView;
|
||||
BOOL _isSheet;
|
||||
|
||||
_CPWindowFrameAnimation _frameAnimation;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -330,9 +332,9 @@ var CPWindowSaveImage = nil,
|
||||
{
|
||||
if (self != [CPWindow class])
|
||||
return;
|
||||
|
||||
|
||||
var bundle = [CPBundle bundleForClass:[CPWindow class]];
|
||||
|
||||
|
||||
CPWindowSavingImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(16.0, 16.0)]
|
||||
}
|
||||
|
||||
@@ -359,7 +361,7 @@ CPTexturedBackgroundWindowMask
|
||||
- (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned int)aStyleMask
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
var windowViewClass = [[self class] _windowViewClassForStyleMask:aStyleMask];
|
||||
@@ -393,7 +395,7 @@ CPTexturedBackgroundWindowMask
|
||||
// Set up our window number.
|
||||
_windowNumber = [CPApp._windows count];
|
||||
CPApp._windows[_windowNumber] = self;
|
||||
|
||||
|
||||
_styleMask = aStyleMask;
|
||||
|
||||
[self setLevel:CPNormalWindowLevel];
|
||||
@@ -408,15 +410,15 @@ CPTexturedBackgroundWindowMask
|
||||
[_windowView setNextResponder:self];
|
||||
|
||||
[self setMovableByWindowBackground:aStyleMask & CPHUDBackgroundWindowMask];
|
||||
|
||||
|
||||
// Create a generic content view.
|
||||
[self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
|
||||
|
||||
|
||||
_firstResponder = self;
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_DOMElement = document.createElement("div");
|
||||
|
||||
|
||||
_DOMElement.style.position = "absolute";
|
||||
_DOMElement.style.visibility = "visible";
|
||||
_DOMElement.style.zIndex = 0;
|
||||
@@ -442,7 +444,7 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
[self setShowsResizeIndicator:_styleMask & CPResizableWindowMask];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -659,9 +661,10 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
if (shouldAnimate)
|
||||
{
|
||||
var animation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
||||
|
||||
[animation startAnimation];
|
||||
[_frameAnimation stopAnimation];
|
||||
_frameAnimation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
||||
|
||||
[_frameAnimation startAnimation];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -882,12 +885,12 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (_contentView)
|
||||
[_contentView removeFromSuperview];
|
||||
|
||||
|
||||
var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
|
||||
|
||||
|
||||
_contentView = aView;
|
||||
[_contentView setFrame:[self contentRectForFrameRect:bounds]];
|
||||
|
||||
|
||||
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
[_windowView addSubview:_contentView];
|
||||
}
|
||||
@@ -943,24 +946,24 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (CGSizeEqualToSize(_minSize, aSize))
|
||||
return;
|
||||
|
||||
|
||||
_minSize = CGSizeCreateCopy(aSize);
|
||||
|
||||
var size = CGSizeMakeCopy([self frame].size),
|
||||
needsFrameChange = NO;
|
||||
|
||||
|
||||
if (size.width < _minSize.width)
|
||||
{
|
||||
size.width = _minSize.width;
|
||||
needsFrameChange = YES;
|
||||
}
|
||||
|
||||
|
||||
if (size.height < _minSize.height)
|
||||
{
|
||||
size.height = _minSize.height;
|
||||
needsFrameChange = YES;
|
||||
}
|
||||
|
||||
|
||||
if (needsFrameChange)
|
||||
[self setFrameSize:size];
|
||||
}
|
||||
@@ -983,24 +986,24 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (CGSizeEqualToSize(_maxSize, aSize))
|
||||
return;
|
||||
|
||||
|
||||
_maxSize = CGSizeCreateCopy(aSize);
|
||||
|
||||
var size = CGSizeMakeCopy([self frame].size),
|
||||
needsFrameChange = NO;
|
||||
|
||||
|
||||
if (size.width > _maxSize.width)
|
||||
{
|
||||
size.width = _maxSize.width;
|
||||
needsFrameChange = YES;
|
||||
}
|
||||
|
||||
|
||||
if (size.height > _maxSize.height)
|
||||
{
|
||||
size.height = _maxSize.height;
|
||||
needsFrameChange = YES;
|
||||
}
|
||||
|
||||
|
||||
if (needsFrameChange)
|
||||
[self setFrameSize:size];
|
||||
}
|
||||
@@ -1041,10 +1044,10 @@ CPTexturedBackgroundWindowMask
|
||||
if (_hasShadow && !_shadowView)
|
||||
{
|
||||
var bounds = [_windowView bounds];
|
||||
|
||||
_shadowView = [[CPView alloc] initWithFrame:CGRectMake(-SHADOW_MARGIN_LEFT, -SHADOW_MARGIN_TOP + SHADOW_DISTANCE,
|
||||
|
||||
_shadowView = [[CPView alloc] initWithFrame:CGRectMake(-SHADOW_MARGIN_LEFT, -SHADOW_MARGIN_TOP + SHADOW_DISTANCE,
|
||||
SHADOW_MARGIN_LEFT + CGRectGetWidth(bounds) + SHADOW_MARGIN_RIGHT, SHADOW_MARGIN_TOP + CGRectGetHeight(bounds) + SHADOW_MARGIN_BOTTOM)];
|
||||
|
||||
|
||||
if (!_CPWindowShadowColor)
|
||||
{
|
||||
var bundle = [CPBundle bundleForClass:[CPWindow class]];
|
||||
@@ -1067,7 +1070,7 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
[_shadowView setBackgroundColor:_CPWindowShadowColor];
|
||||
[_shadowView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
CPDOMDisplayServerInsertBefore(_DOMElement, _shadowView._DOMElement, _windowView._DOMElement);
|
||||
#endif
|
||||
@@ -1133,7 +1136,7 @@ CPTexturedBackgroundWindowMask
|
||||
selector:@selector(windowDidBecomeKey:)
|
||||
name:CPWindowDidBecomeKeyNotification
|
||||
object:self];
|
||||
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(windowDidBecomeMain:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
@@ -1229,7 +1232,7 @@ CPTexturedBackgroundWindowMask
|
||||
if(!aResponder || ![aResponder acceptsFirstResponder] || ![aResponder becomeFirstResponder])
|
||||
{
|
||||
_firstResponder = self;
|
||||
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -1282,9 +1285,9 @@ CPTexturedBackgroundWindowMask
|
||||
- (void)setTitle:(CPString)aTitle
|
||||
{
|
||||
_title = aTitle;
|
||||
|
||||
|
||||
[_windowView setTitle:aTitle];
|
||||
|
||||
|
||||
[self _synchronizeMenuBarTitleWithWindowTitle];
|
||||
}
|
||||
|
||||
@@ -1376,8 +1379,18 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CPFlagsChanged: return [[self firstResponder] flagsChanged:anEvent];
|
||||
|
||||
case CPKeyUp: return [[self firstResponder] keyUp:anEvent];
|
||||
case CPKeyDown: return [[self firstResponder] keyDown:anEvent];
|
||||
|
||||
case CPKeyDown: [[self firstResponder] keyDown:anEvent];
|
||||
|
||||
// Trigger the default button if needed
|
||||
if (![self disableKeyEquivalentForDefaultButton])
|
||||
if ([anEvent _triggersKeyEquivalent:[[self defaultButton] keyEquivalent] withModifierMask:[[self defaultButton] keyEquivalentModifierMask]])
|
||||
[[self defaultButton] performClick:self];
|
||||
|
||||
return;
|
||||
|
||||
case CPScrollWheel: return [[_windowView hitTest:point] scrollWheel:anEvent];
|
||||
|
||||
@@ -1536,7 +1549,7 @@ CPTexturedBackgroundWindowMask
|
||||
- (void)makeKeyAndOrderFront:(id)aSender
|
||||
{
|
||||
[self orderFront:self];
|
||||
|
||||
|
||||
[self makeKeyWindow];
|
||||
[self makeMainWindow];
|
||||
}
|
||||
@@ -1600,7 +1613,7 @@ CPTexturedBackgroundWindowMask
|
||||
if (!pasteboardTypes)
|
||||
return;
|
||||
|
||||
[_inclusiveRegisteredDraggedTypes minusSet:pasteboardTypes]
|
||||
[_inclusiveRegisteredDraggedTypes minusSet:pasteboardTypes];
|
||||
|
||||
if ([_inclusiveRegisteredDraggedTypes count] === 0)
|
||||
_inclusiveRegisteredDraggedTypes = nil;
|
||||
@@ -1631,7 +1644,7 @@ CPTexturedBackgroundWindowMask
|
||||
return;
|
||||
|
||||
[self _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
|
||||
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes]
|
||||
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes];
|
||||
[self _noteRegisteredDraggedTypes:_registeredDraggedTypes];
|
||||
|
||||
_registeredDraggedTypesArray = nil;
|
||||
@@ -1644,7 +1657,7 @@ CPTexturedBackgroundWindowMask
|
||||
- (CPArray)registeredDraggedTypes
|
||||
{
|
||||
if (!_registeredDraggedTypesArray)
|
||||
_registeredDraggedTypesArray = [_registeredDraggedTypes allObjects]
|
||||
_registeredDraggedTypesArray = [_registeredDraggedTypes allObjects];
|
||||
|
||||
return _registeredDraggedTypesArray;
|
||||
}
|
||||
@@ -1670,9 +1683,9 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (_isDocumentEdited == isDocumentEdited)
|
||||
return;
|
||||
|
||||
|
||||
_isDocumentEdited = isDocumentEdited;
|
||||
|
||||
|
||||
[CPMenu _setMenuBarIconImageAlphaValue:_isDocumentEdited ? 0.5 : 1.0];
|
||||
|
||||
[_windowView setDocumentEdited:isDocumentEdited];
|
||||
@@ -1690,11 +1703,11 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (_isDocumentSaving == isDocumentSaving)
|
||||
return;
|
||||
|
||||
|
||||
_isDocumentSaving = isDocumentSaving;
|
||||
|
||||
|
||||
[self _synchronizeSaveMenuWithDocumentSaving];
|
||||
|
||||
|
||||
[_windowView windowDidChangeDocumentSaving];
|
||||
}
|
||||
|
||||
@@ -1711,16 +1724,16 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
var mainMenu = [CPApp mainMenu],
|
||||
index = [mainMenu indexOfItemWithTitle:_isDocumentSaving ? @"Save" : @"Saving..."];
|
||||
|
||||
|
||||
if (index == CPNotFound)
|
||||
return;
|
||||
|
||||
|
||||
var item = [mainMenu itemAtIndex:index];
|
||||
|
||||
|
||||
if (_isDocumentSaving)
|
||||
{
|
||||
CPWindowSaveImage = [item image];
|
||||
|
||||
|
||||
[item setTitle:@"Saving..."];
|
||||
[item setImage:CPWindowSavingImage];
|
||||
[item setEnabled:NO];
|
||||
@@ -1810,7 +1823,7 @@ CPTexturedBackgroundWindowMask
|
||||
if (![_delegate windowShouldClose:self])
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Only check self is delegate does NOT implement this. This also ensures this when delegate == self (returns true).
|
||||
else if ([self respondsToSelector:@selector(windowShouldClose:)] && ![self windowShouldClose:self])
|
||||
return;
|
||||
@@ -1820,8 +1833,8 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
var index = [documents indexOfObject:[_windowController document]];
|
||||
|
||||
[documents[index] shouldCloseWindowController:_windowController
|
||||
delegate:self
|
||||
[documents[index] shouldCloseWindowController:_windowController
|
||||
delegate:self
|
||||
shouldCloseSelector:@selector(_windowControllerContainingDocument:shouldClose:contextInfo:)
|
||||
contextInfo:{documents:[documents copy], visited:0, index:index}];
|
||||
}
|
||||
@@ -1845,8 +1858,8 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
[windowController setDocument:documents[index]];
|
||||
|
||||
[documents[index] shouldCloseWindowController:_windowController
|
||||
delegate:self
|
||||
[documents[index] shouldCloseWindowController:_windowController
|
||||
delegate:self
|
||||
shouldCloseSelector:@selector(_windowControllerContainingDocument:shouldClose:contextInfo:)
|
||||
contextInfo:context];
|
||||
}
|
||||
@@ -1883,7 +1896,7 @@ CPTexturedBackgroundWindowMask
|
||||
// FIXME: Also check if we can resize and titlebar.
|
||||
if ([self isVisible])
|
||||
return YES;
|
||||
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -1942,10 +1955,16 @@ CPTexturedBackgroundWindowMask
|
||||
else
|
||||
{
|
||||
var mainMenu = [CPApp mainMenu],
|
||||
menuWindow = mainMenu ? mainMenu._menuWindow : nil;
|
||||
menuBarClass = objj_getClass("_CPMenuBarWindow"),
|
||||
menuWindow;
|
||||
|
||||
for (var i = 0; i < windowCount; i++)
|
||||
{
|
||||
var currentWindow = allWindows[i];
|
||||
|
||||
if ([currentWindow isKindOfClass:menuBarClass])
|
||||
menuWindow = currentWindow;
|
||||
|
||||
if (currentWindow === self || currentWindow === menuWindow)
|
||||
continue;
|
||||
|
||||
@@ -1971,10 +1990,16 @@ CPTexturedBackgroundWindowMask
|
||||
else
|
||||
{
|
||||
var mainMenu = [CPApp mainMenu],
|
||||
menuWindow = mainMenu ? mainMenu._menuWindow : nil;
|
||||
menuBarClass = objj_getClass("_CPMenuBarWindow"),
|
||||
menuWindow;
|
||||
|
||||
for (var i = 0; i < windowCount; i++)
|
||||
{
|
||||
var currentWindow = allWindows[i];
|
||||
|
||||
if ([currentWindow isKindOfClass:menuBarClass])
|
||||
menuWindow = currentWindow;
|
||||
|
||||
if (currentWindow === self || currentWindow === menuWindow)
|
||||
continue;
|
||||
|
||||
@@ -2005,25 +2030,25 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (_toolbar === aToolbar)
|
||||
return;
|
||||
|
||||
|
||||
// If this has an owner, dump it!
|
||||
[[aToolbar _window] setToolbar:nil];
|
||||
|
||||
|
||||
// This is no longer out toolbar.
|
||||
[_toolbar _setWindow:nil];
|
||||
|
||||
|
||||
_toolbar = aToolbar;
|
||||
|
||||
|
||||
// THIS is our toolbar.
|
||||
[_toolbar _setWindow:self];
|
||||
|
||||
|
||||
[self _noteToolbarChanged];
|
||||
}
|
||||
|
||||
- (void)toggleToolbarShown:(id)aSender
|
||||
{
|
||||
var toolbar = [self toolbar];
|
||||
|
||||
|
||||
[toolbar setVisible:![toolbar isVisible]];
|
||||
}
|
||||
|
||||
@@ -2039,10 +2064,10 @@ CPTexturedBackgroundWindowMask
|
||||
else
|
||||
{
|
||||
newFrame = CGRectMakeCopy([self frame]);
|
||||
|
||||
|
||||
newFrame.origin = frame.origin;
|
||||
}
|
||||
|
||||
|
||||
[self setFrame:newFrame];
|
||||
/*
|
||||
[_windowView setAnimatingToolbar:YES];
|
||||
@@ -2054,11 +2079,12 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
- (void)_setFrame:(CGRect)aFrame delegate:(id)delegate duration:(int)duration curve:(CPAnimationCurve)curve
|
||||
{
|
||||
var animation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
||||
[animation setDelegate:delegate];
|
||||
[animation setAnimationCurve:curve];
|
||||
[animation setDuration:duration];
|
||||
[animation startAnimation];
|
||||
[_frameAnimation stopAnimation];
|
||||
_frameAnimation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
||||
[_frameAnimation setDelegate:delegate];
|
||||
[_frameAnimation setAnimationCurve:curve];
|
||||
[_frameAnimation setDuration:duration];
|
||||
[_frameAnimation startAnimation];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
@@ -2068,7 +2094,7 @@ CPTexturedBackgroundWindowMask
|
||||
var attachedSheet = [self attachedSheet];
|
||||
var contentRect = [[self contentView] frame],
|
||||
sheetFrame = CGRectMakeCopy([attachedSheet frame]);
|
||||
|
||||
|
||||
sheetFrame.origin.y = CGRectGetMinY(_frame) + CGRectGetMinY(contentRect);
|
||||
sheetFrame.origin.x = CGRectGetMinX(_frame) + FLOOR((CGRectGetWidth(_frame) - CGRectGetWidth(sheetFrame)) / 2.0);
|
||||
|
||||
@@ -2080,8 +2106,8 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
var sheetFrame = [aSheet frame];
|
||||
|
||||
_sheetContext = {"sheet":aSheet, "modalDelegate":aModalDelegate, "endSelector":aDidEndSelector, "contextInfo":aContextInfo, "frame":CGRectMakeCopy(sheetFrame), "returnCode":-1, "opened": NO};
|
||||
|
||||
_sheetContext = {"sheet":aSheet, "modalDelegate":aModalDelegate, "endSelector":aDidEndSelector, "contextInfo":aContextInfo, "frame":CGRectMakeCopy(sheetFrame), "returnCode":-1, "opened": NO};
|
||||
|
||||
[self _attachSheetWindow:aSheet];
|
||||
}
|
||||
|
||||
@@ -2091,12 +2117,12 @@ CPTexturedBackgroundWindowMask
|
||||
var sheetFrame = [aSheet frame],
|
||||
frame = [self frame],
|
||||
sheetContent = [aSheet contentView];
|
||||
|
||||
|
||||
[self _setUpMasksForView:sheetContent];
|
||||
|
||||
|
||||
aSheet._isSheet = YES;
|
||||
aSheet._parentView = self;
|
||||
|
||||
|
||||
var originx = frame.origin.x + FLOOR((frame.size.width - sheetFrame.size.width)/2),
|
||||
originy = frame.origin.y + [[self contentView] frame].origin.y,
|
||||
startFrame = CGRectMake(originx, originy, sheetFrame.size.width, 0),
|
||||
@@ -2104,7 +2130,7 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowWillBeginSheetNotification object:self];
|
||||
[CPApp runModalForWindow:aSheet];
|
||||
|
||||
|
||||
[aSheet orderFront:self];
|
||||
[aSheet setFrame:startFrame display:YES animate:NO];
|
||||
_sheetContext["opened"] = YES;
|
||||
@@ -2112,7 +2138,7 @@ CPTexturedBackgroundWindowMask
|
||||
[aSheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseOut];
|
||||
|
||||
// Should run the main loop here until _isAnimating = FALSE
|
||||
[aSheet becomeKeyWindow];
|
||||
[aSheet becomeKeyWindow];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
@@ -2123,9 +2149,9 @@ CPTexturedBackgroundWindowMask
|
||||
endFrame = CGRectMakeCopy(startFrame);
|
||||
|
||||
endFrame.size.height = 0;
|
||||
|
||||
|
||||
_sheetContext["frame"] = startFrame;
|
||||
|
||||
|
||||
var sheetContent = [sheet contentView];
|
||||
[self _setUpMasksForView:sheetContent];
|
||||
|
||||
@@ -2141,27 +2167,27 @@ CPTexturedBackgroundWindowMask
|
||||
return;
|
||||
|
||||
var sheetContent = [sheet contentView];
|
||||
|
||||
|
||||
if (_sheetContext["opened"] === YES)
|
||||
{
|
||||
[self _restoreMasksForView:sheetContent];
|
||||
return;
|
||||
}
|
||||
|
||||
[CPApp stopModal];
|
||||
|
||||
[CPApp stopModal];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowDidEndSheetNotification object:self];
|
||||
|
||||
[sheet orderOut:self];
|
||||
|
||||
var lastFrame = _sheetContext["frame"];
|
||||
[sheet setFrame:lastFrame];
|
||||
|
||||
|
||||
[self _restoreMasksForView:sheetContent];
|
||||
|
||||
var delegate = _sheetContext["modalDelegate"],
|
||||
endSelector = _sheetContext["endSelector"];
|
||||
|
||||
if (delegate != nil && endSelector != nil)
|
||||
if (delegate != nil && endSelector != nil)
|
||||
objj_msgSend(delegate, endSelector, sheet, _sheetContext["returnCode"], _sheetContext["contextInfo"]);
|
||||
|
||||
_sheetContext = nil;
|
||||
@@ -2173,7 +2199,7 @@ CPTexturedBackgroundWindowMask
|
||||
var views = [aView subviews];
|
||||
|
||||
[views addObject:aView];
|
||||
|
||||
|
||||
for (var i = 0, count = [views count]; i < count; i++)
|
||||
{
|
||||
var view = [views objectAtIndex:i],
|
||||
@@ -2189,7 +2215,7 @@ CPTexturedBackgroundWindowMask
|
||||
var views = [aView subviews];
|
||||
|
||||
[views addObject:aView];
|
||||
|
||||
|
||||
for (var i = 0, count = [views count]; i < count; i++)
|
||||
{
|
||||
var view = [views objectAtIndex:i],
|
||||
@@ -2207,7 +2233,7 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (_sheetContext === nil)
|
||||
return nil;
|
||||
|
||||
|
||||
return _sheetContext["sheet"];
|
||||
}
|
||||
|
||||
@@ -2238,7 +2264,7 @@ CPTexturedBackgroundWindowMask
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)performKeyEquivalent:(CPEvent)anEvent
|
||||
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
|
||||
{
|
||||
// FIXME: should we be starting at the root, in other words _windowView?
|
||||
// The evidence seems to point to no...
|
||||
@@ -2249,14 +2275,11 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
// It's not clear why we do performKeyEquivalent again here...
|
||||
// Perhaps to allow something to happen between sendEvent: and keyDown:?
|
||||
if (![anEvent _couldBeKeyEquivalent] || ![self performKeyEquivalent:anEvent])
|
||||
[self interpretKeyEvents:[anEvent]];
|
||||
}
|
||||
if ([anEvent _couldBeKeyEquivalent] && [self performKeyEquivalent:anEvent])
|
||||
return;
|
||||
|
||||
- (void)insertNewline:(id)sender
|
||||
{
|
||||
if (_defaultButton && _defaultButtonEnabled)
|
||||
[_defaultButton performClick:nil];
|
||||
// Interpret the key events
|
||||
[self interpretKeyEvents:[anEvent]];
|
||||
}
|
||||
|
||||
- (void)insertTab:(id)sender
|
||||
@@ -2288,7 +2311,7 @@ CPTexturedBackgroundWindowMask
|
||||
- (void)recalculateKeyViewLoop
|
||||
{
|
||||
var subviews = [];
|
||||
|
||||
|
||||
[self _appendSubviewsOf:_contentView toArray:subviews];
|
||||
|
||||
var keyViewOrder = [subviews sortedArrayUsingFunction:keyViewComparator context:_contentView],
|
||||
@@ -2296,7 +2319,7 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
for (var i=0; i<count; i++)
|
||||
[keyViewOrder[i] setNextKeyView:keyViewOrder[(i+1)%count]];
|
||||
|
||||
|
||||
_keyViewLoopIsDirty = NO;
|
||||
}
|
||||
|
||||
@@ -2317,7 +2340,7 @@ CPTexturedBackgroundWindowMask
|
||||
return;
|
||||
|
||||
_autorecalculatesKeyViewLoop = shouldRecalculate;
|
||||
|
||||
|
||||
if (_keyViewLoopIsDirty)
|
||||
[self recalculateKeyViewLoop];
|
||||
else if (_autorecalculatesKeyViewLoop)
|
||||
@@ -2369,11 +2392,12 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
- (void)setDefaultButton:(CPButton)aButton
|
||||
{
|
||||
if (_defaultButton === aButton)
|
||||
return;
|
||||
|
||||
[_defaultButton setDefaultButton:NO];
|
||||
|
||||
_defaultButton = aButton;
|
||||
|
||||
[_defaultButton setDefaultButton:YES];
|
||||
[_defaultButton setDefaultButton:YES];
|
||||
}
|
||||
|
||||
- (CPButton)defaultButton
|
||||
@@ -2440,7 +2464,7 @@ var keyViewComparator = function(a, b, context)
|
||||
{
|
||||
if ([self isFullPlatformWindow])
|
||||
return [self setFrame:[_platformWindow visibleFrame]];
|
||||
|
||||
|
||||
if (_autoresizingMask == CPWindowNotSizable)
|
||||
return;
|
||||
|
||||
@@ -2455,7 +2479,7 @@ var keyViewComparator = function(a, b, context)
|
||||
newFrame.origin.x += dX;
|
||||
if (_autoresizingMask & CPWindowWidthSizable)
|
||||
newFrame.size.width += dX;
|
||||
|
||||
|
||||
if (_autoresizingMask & CPWindowMinYMargin)
|
||||
newFrame.origin.y += dY;
|
||||
if (_autoresizingMask & CPWindowHeightSizable)
|
||||
@@ -2627,7 +2651,7 @@ var interpolate = function(fromValue, toValue, progress)
|
||||
@implementation _CPWindowFrameAnimation : CPAnimation
|
||||
{
|
||||
CPWindow _window;
|
||||
|
||||
|
||||
CGRect _startFrame;
|
||||
CGRect _targetFrame;
|
||||
}
|
||||
@@ -2635,31 +2659,31 @@ var interpolate = function(fromValue, toValue, progress)
|
||||
- (id)initWithWindow:(CPWindow)aWindow targetFrame:(CGRect)aTargetFrame
|
||||
{
|
||||
self = [super initWithDuration:0.2 animationCurve:CPAnimationLinear];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_window = aWindow;
|
||||
|
||||
|
||||
_targetFrame = CGRectMakeCopy(aTargetFrame);
|
||||
_startFrame = CGRectMakeCopy([_window frame]);
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)startAnimation
|
||||
{
|
||||
[super startAnimation];
|
||||
|
||||
|
||||
_window._isAnimating = YES;
|
||||
}
|
||||
|
||||
- (void)setCurrentProgress:(float)aProgress
|
||||
{
|
||||
[super setCurrentProgress:aProgress];
|
||||
|
||||
|
||||
var value = [self currentValue];
|
||||
|
||||
|
||||
if (value == 1.0)
|
||||
_window._isAnimating = NO;
|
||||
|
||||
|
||||
@@ -43,21 +43,21 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
||||
|
||||
_CPHUDWindowViewBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
|
||||
[
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground0.png"] size:CPSizeMake(6.0, 78.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground1.png"] size:CPSizeMake(1.0, 78.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(6.0, 78.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground0.png"] size:CPSizeMake(7.0, 37.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground1.png"] size:CPSizeMake(1.0, 37.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(7.0, 37.0)],
|
||||
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(6.0, 1.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(5.0, 5.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(6.0, 1.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(7.0, 1.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(2.0, 2.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(7.0, 1.0)],
|
||||
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(6.0, 6.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground7.png"] size:CPSizeMake(6.0, 6.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground8.png"] size:CPSizeMake(6.0, 6.0)]
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(7.0, 3.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground7.png"] size:CPSizeMake(1.0, 3.0)],
|
||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground8.png"] size:CPSizeMake(7.0, 3.0)]
|
||||
]]];
|
||||
|
||||
_CPHUDWindowViewCloseImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowClose.png"] size:CPSizeMake(20.0, 20.0)];
|
||||
_CPHUDWindowViewCloseActiveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowCloseActive.png"] size:CPSizeMake(20.0, 20.0)];
|
||||
_CPHUDWindowViewCloseImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowClose.png"] size:CPSizeMake(18.0, 18.0)];
|
||||
_CPHUDWindowViewCloseActiveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowCloseActive.png"] size:CPSizeMake(18.0, 18.0)];
|
||||
}
|
||||
|
||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
@@ -148,7 +148,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
||||
{
|
||||
var closeSize = [_CPHUDWindowViewCloseImage size];
|
||||
|
||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(4.0, 4.0, closeSize.width, closeSize.height)];
|
||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 5.0, closeSize.width, closeSize.height)];
|
||||
|
||||
[_closeButton setBordered:NO];
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
if (_window)
|
||||
return;
|
||||
|
||||
[[CPBundle bundleForClass:[_cibOwner class]] loadCibFile:[self windowCibPath] externalNameTable:[CPDictionary dictionaryWithObject:_cibOwner forKey:CPCibOwner]];
|
||||
[[CPBundle mainBundle] loadCibFile:[self windowCibPath] externalNameTable:[CPDictionary dictionaryWithObject:_cibOwner forKey:CPCibOwner]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -430,7 +430,7 @@
|
||||
if (_windowCibPath)
|
||||
return _windowCibPath;
|
||||
|
||||
return [[CPBundle bundleForClass:[_cibOwner class]] pathForResource:_windowCibName + @".cib"];
|
||||
return [[CPBundle mainBundle] pathForResource:_windowCibName + @".cib"];
|
||||
}
|
||||
|
||||
// Setting and Getting Window Attributes
|
||||
|
||||
@@ -150,7 +150,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
|
||||
|
||||
var topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
|
||||
|
||||
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects]
|
||||
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects];
|
||||
[objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
|
||||
[objectData awakeWithOwner:owner topLevelObjects:topLevelObjects];
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* THIS DOCUMENTATION STOLEN DIRECTLY FROM GOOGLE CLOSURE (licensed under Apache 2)
|
||||
*
|
||||
*
|
||||
* Different web browsers have very different keyboard event handling. Most
|
||||
* importantly is that only certain browsers repeat keydown events:
|
||||
* IE, Opera, FF/Win32, and Safari 3 repeat keydown events.
|
||||
@@ -111,6 +111,7 @@
|
||||
@import <Foundation/CPRunLoop.j>
|
||||
|
||||
@import "CPEvent.j"
|
||||
@import "CPText.j"
|
||||
@import "CPCompatibility.j"
|
||||
|
||||
@import "CPDOMWindowLayer.j"
|
||||
@@ -138,10 +139,31 @@ var KeyCodesToPrevent = {},
|
||||
MozKeyCodeToKeyCodeMap = {
|
||||
61: 187, // =, equals
|
||||
59: 186 // ;, semicolon
|
||||
};
|
||||
},
|
||||
KeyCodesToFunctionUnicodeMap = {};
|
||||
|
||||
KeyCodesToPrevent[CPKeyCodes.A] = YES;
|
||||
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.BACKSPACE] = CPDeleteCharacter;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.DELETE] = CPDeleteFunctionKey;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.TAB] = CPTabCharacter;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.ENTER] = CPCarriageReturnCharacter;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.ESC] = CPEscapeFunctionKey;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.PAGE_UP] = CPPageUpFunctionKey;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.PAGE_DOWN] = CPPageDownFunctionKey;
|
||||
KeyCodesToFunctionUnicodeMap[CPKeyCodes.LEFT] = CPLeftArrowFunctionKey;
|
||||
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)
|
||||
@@ -306,11 +328,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
keyEventSelector = @selector(keyEvent:),
|
||||
keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector),
|
||||
keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); },
|
||||
|
||||
|
||||
mouseEventSelector = @selector(mouseEvent:),
|
||||
mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector),
|
||||
mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); },
|
||||
|
||||
|
||||
contextMenuEventSelector = @selector(contextMenuEvent:),
|
||||
contextMenuEventImplementation = class_getMethodImplementation(theClass, contextMenuEventSelector),
|
||||
contextMenuEventCallback = function (anEvent) { return contextMenuEventImplementation(self, nil, anEvent); },
|
||||
@@ -318,7 +340,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
scrollEventSelector = @selector(scrollEvent:),
|
||||
scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector),
|
||||
scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); },
|
||||
|
||||
|
||||
touchEventSelector = @selector(touchEvent:),
|
||||
touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector),
|
||||
touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); };
|
||||
@@ -356,7 +378,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
_DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO);
|
||||
_DOMWindow.addEventListener("mousewheel", scrollEventCallback, NO);
|
||||
|
||||
_DOMWindow.addEventListener("resize", resizeEventCallback, NO);
|
||||
_DOMWindow.addEventListener("resize", resizeEventCallback, NO);
|
||||
|
||||
_DOMWindow.addEventListener("unload", function()
|
||||
{
|
||||
@@ -400,16 +422,16 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
theDocument.attachEvent("onmousemove", mouseEventCallback);
|
||||
theDocument.attachEvent("ondblclick", mouseEventCallback);
|
||||
theDocument.attachEvent("oncontextmenu", contextMenuEventCallback);
|
||||
|
||||
|
||||
theDocument.attachEvent("onkeyup", keyEventCallback);
|
||||
theDocument.attachEvent("onkeydown", keyEventCallback);
|
||||
theDocument.attachEvent("onkeypress", keyEventCallback);
|
||||
|
||||
|
||||
_DOMWindow.attachEvent("onresize", resizeEventCallback);
|
||||
|
||||
|
||||
_DOMWindow.onmousewheel = scrollEventCallback;
|
||||
theDocument.onmousewheel = scrollEventCallback;
|
||||
|
||||
|
||||
_DOMBodyElement.ondrag = function () { return NO; };
|
||||
_DOMBodyElement.onselectstart = function () { return _DOMWindow.event.srcElement === _DOMPasteboardElement; };
|
||||
|
||||
@@ -593,15 +615,15 @@ 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) |
|
||||
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
|
||||
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
|
||||
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
|
||||
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
|
||||
(aDOMEvent.metaKey ? CPCommandKeyMask : 0);
|
||||
|
||||
//We want to stop propagation if this is a command key AND this character or keycode has been added to our blacklist
|
||||
//We want to stop propagation if this is a command key AND this character or keycode has been added to our blacklist
|
||||
StopDOMEventPropagation = !!(!(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) ||
|
||||
CharacterKeysToPrevent[String.fromCharCode(aDOMEvent.keyCode || aDOMEvent.charCode).toLowerCase()] ||
|
||||
KeyCodesToPrevent[aDOMEvent.keyCode]);
|
||||
@@ -613,19 +635,36 @@ 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;
|
||||
|
||||
var characters = 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
|
||||
@@ -633,7 +672,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
var eligibleForCopyPaste = [self _validateCopyCutOrPasteEvent:aDOMEvent flags:modifierFlags];
|
||||
|
||||
// If this could be a native PASTE event, then we need to further examine it before
|
||||
// If this could be a native PASTE event, then we need to further examine it before
|
||||
// sending a CPEvent. Select our element to see if anything gets pasted in it.
|
||||
if (characters === "v" && eligibleForCopyPaste)
|
||||
{
|
||||
@@ -646,7 +685,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
isNativePasteEvent = YES;
|
||||
}
|
||||
|
||||
// However, of this could be a native COPY event, we need to let the normal event-process take place so it
|
||||
// However, of this could be a native COPY event, we need to let the normal event-process take place so it
|
||||
// can capture our internal Cappuccino pasteboard.
|
||||
else if ((characters == "c" || characters == "x") && eligibleForCopyPaste)
|
||||
{
|
||||
@@ -668,10 +707,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
//this branch is taken by "remedial" key events
|
||||
// In this state we continue to keypress and send the CPEvent
|
||||
}
|
||||
|
||||
|
||||
case "keypress":
|
||||
// we unconditionally break on keypress events with modifiers,
|
||||
// because we forced the event to be sent on the keydown
|
||||
// we unconditionally break on keypress events with modifiers,
|
||||
// because we forced the event to be sent on the keydown
|
||||
if (aDOMEvent.type === "keypress" && (modifierFlags & (CPControlKeyMask | CPCommandKeyMask)))
|
||||
break;
|
||||
|
||||
@@ -682,8 +721,15 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
_lastKey = keyCode;
|
||||
_charCodes[keyCode] = charCode;
|
||||
|
||||
var characters = overrideCharacters || 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))
|
||||
@@ -691,7 +737,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -700,10 +746,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case "keyup": var keyCode = aDOMEvent.keyCode,
|
||||
charCode = _charCodes[keyCode];
|
||||
|
||||
|
||||
_keyCode = -1;
|
||||
_lastKey = -1;
|
||||
_charCodes[keyCode] = nil;
|
||||
@@ -714,12 +760,15 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
if (keyCode === CPKeyCodes.CAPS_LOCK)
|
||||
_capsLockActive = NO;
|
||||
|
||||
var characters = String.fromCharCode(charCode),
|
||||
if ([ModifierKeyCodes containsObject:keyCode])
|
||||
break;
|
||||
|
||||
var characters = KeyCodesToFunctionUnicodeMap[charCode] || String.fromCharCode(charCode),
|
||||
charactersIgnoringModifiers = characters.toLowerCase();
|
||||
|
||||
|
||||
if (!(modifierFlags & CPShiftKeyMask) && (modifierFlags & CPCommandKeyMask) && !_capsLockActive)
|
||||
characters = charactersIgnoringModifiers;
|
||||
|
||||
|
||||
event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags
|
||||
timestamp: timestamp windowNumber:windowNumber context:nil
|
||||
characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode];
|
||||
@@ -867,10 +916,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
{
|
||||
x += element.offsetLeft;
|
||||
y += element.offsetTop;
|
||||
|
||||
|
||||
} while (element = element.offsetParent);
|
||||
}
|
||||
|
||||
|
||||
location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));
|
||||
}
|
||||
else if (aDOMEvent._overrideLocation)
|
||||
@@ -882,9 +931,9 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
deltaY = 0.0,
|
||||
windowNumber = 0,
|
||||
timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
|
||||
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
|
||||
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
|
||||
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
|
||||
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
|
||||
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
|
||||
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
|
||||
(aDOMEvent.metaKey ? CPCommandKeyMask : 0);
|
||||
|
||||
StopDOMEventPropagation = YES;
|
||||
@@ -903,31 +952,31 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
deltaX = aDOMEvent.wheelDeltaX / 120.0;
|
||||
deltaY = aDOMEvent.wheelDeltaY / 120.0;
|
||||
}
|
||||
|
||||
|
||||
else if (aDOMEvent.wheelDelta)
|
||||
deltaY = aDOMEvent.wheelDelta / 120.0;
|
||||
|
||||
else if (aDOMEvent.detail)
|
||||
|
||||
else if (aDOMEvent.detail)
|
||||
deltaY = -aDOMEvent.detail / 3.0;
|
||||
|
||||
|
||||
else
|
||||
return;
|
||||
return;
|
||||
|
||||
if(!CPFeatureIsCompatible(CPJavaScriptNegativeMouseWheelValues))
|
||||
{
|
||||
deltaX = -deltaX;
|
||||
deltaY = -deltaY;
|
||||
}
|
||||
|
||||
|
||||
var event = [CPEvent mouseEventWithType:CPScrollWheel location:location modifierFlags:modifierFlags
|
||||
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0 ];
|
||||
|
||||
|
||||
event._DOMEvent = aDOMEvent;
|
||||
event._deltaX = deltaX;
|
||||
event._deltaY = deltaY;
|
||||
|
||||
|
||||
[CPApp sendEvent:event];
|
||||
|
||||
|
||||
if (StopDOMEventPropagation)
|
||||
CPDOMEventStop(aDOMEvent, self);
|
||||
|
||||
@@ -970,7 +1019,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1)))
|
||||
{
|
||||
var newEvent = {};
|
||||
|
||||
|
||||
switch(aDOMEvent.type)
|
||||
{
|
||||
case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown;
|
||||
@@ -984,27 +1033,27 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
}
|
||||
|
||||
var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0];
|
||||
|
||||
|
||||
newEvent.clientX = touch.clientX;
|
||||
newEvent.clientY = touch.clientY;
|
||||
|
||||
|
||||
newEvent.timestamp = aDOMEvent.timestamp;
|
||||
newEvent.target = aDOMEvent.target;
|
||||
|
||||
|
||||
newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false;
|
||||
|
||||
|
||||
newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()};
|
||||
newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()};
|
||||
|
||||
|
||||
[self mouseEvent:newEvent];
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aDOMEvent.preventDefault)
|
||||
aDOMEvent.preventDefault();
|
||||
|
||||
|
||||
if (aDOMEvent.stopPropagation)
|
||||
aDOMEvent.stopPropagation();
|
||||
}
|
||||
@@ -1026,7 +1075,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
_overriddenEventType = nil;
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
var event,
|
||||
@@ -1034,9 +1083,9 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
|
||||
sourceElement = (aDOMEvent.target || aDOMEvent.srcElement),
|
||||
windowNumber = 0,
|
||||
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
|
||||
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
|
||||
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
|
||||
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
|
||||
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
|
||||
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
|
||||
(aDOMEvent.metaKey ? CPCommandKeyMask : 0);
|
||||
|
||||
StopDOMEventPropagation = YES;
|
||||
@@ -1062,7 +1111,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
if(_mouseIsDown)
|
||||
{
|
||||
event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseDownIsRightClick ? CPRightMouseUp : CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0);
|
||||
|
||||
|
||||
_mouseIsDown = NO;
|
||||
_lastMouseUp = event;
|
||||
_mouseDownWindow = nil;
|
||||
@@ -1075,7 +1124,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if (type === "mousedown")
|
||||
{
|
||||
if (sourceElement.tagName === "INPUT" && sourceElement != _DOMFocusElement)
|
||||
@@ -1091,11 +1140,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
//fake a down and up event so that event tracking mode will work correctly
|
||||
[CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseDown location:location modifierFlags:modifierFlags
|
||||
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
|
||||
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
|
||||
clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]];
|
||||
|
||||
[CPApp sendEvent:[CPEvent mouseEventWithType:CPLeftMouseUp location:location modifierFlags:modifierFlags
|
||||
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
|
||||
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
|
||||
clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0]];
|
||||
|
||||
return;
|
||||
@@ -1116,7 +1165,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
_mouseIsDown = YES;
|
||||
_lastMouseDown = event;
|
||||
}
|
||||
|
||||
|
||||
else // if (type === "mousemove" || type === "drag")
|
||||
{
|
||||
if (_DOMEventMode)
|
||||
@@ -1130,7 +1179,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
if (event && (!isDragging || !supportsNativeDragAndDrop))
|
||||
{
|
||||
event._DOMEvent = aDOMEvent;
|
||||
|
||||
|
||||
[CPApp sendEvent:event];
|
||||
}
|
||||
|
||||
@@ -1157,7 +1206,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
if (!layer)
|
||||
return [];
|
||||
|
||||
|
||||
return [layer orderedWindows];
|
||||
}
|
||||
|
||||
@@ -1170,19 +1219,19 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
if (!layer && aFlag)
|
||||
{
|
||||
layer = [[CPDOMWindowLayer alloc] initWithLevel:aLevel];
|
||||
|
||||
|
||||
[_windowLayers setObject:layer forKey:aLevel];
|
||||
|
||||
// Find the nearest layer. This is similar to a binary search,
|
||||
// Find the nearest layer. This is similar to a binary search,
|
||||
// only we know we won't find the value.
|
||||
var low = 0,
|
||||
high = _windowLevels.length - 1,
|
||||
middle;
|
||||
|
||||
|
||||
while (low <= high)
|
||||
{
|
||||
middle = FLOOR((low + high) / 2);
|
||||
|
||||
|
||||
if (_windowLevels[middle] > aLevel)
|
||||
high = middle - 1;
|
||||
else
|
||||
@@ -1190,7 +1239,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
}
|
||||
|
||||
var insertionIndex = 0;
|
||||
if (middle !== undefined)
|
||||
if (middle !== undefined)
|
||||
insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1
|
||||
|
||||
[_windowLevels insertObject:aLevel atIndex:insertionIndex];
|
||||
@@ -1198,7 +1247,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
_DOMBodyElement.appendChild(layer._DOMElement);
|
||||
}
|
||||
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
@@ -1206,11 +1255,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
{
|
||||
[CPPlatform initializeScreenIfNecessary];
|
||||
|
||||
// Grab the appropriate level for the layer, and create it if
|
||||
// Grab the appropriate level for the layer, and create it if
|
||||
// necessary (if we are not simply removing the window).
|
||||
var layer = [self layerAtLevel:[aWindow level] create:aPlace !== CPWindowOut];
|
||||
|
||||
// Ignore otherWindow, simply remove this window from it's level.
|
||||
// Ignore otherWindow, simply remove this window from it's level.
|
||||
// If layer is nil, this will be a no-op.
|
||||
if (aPlace === CPWindowOut)
|
||||
return [layer removeWindow:aWindow];
|
||||
@@ -1263,10 +1312,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
// Skip any windows above or at the dragging level.
|
||||
if (levels[levelCount] >= CPDraggingWindowLevel)
|
||||
continue;
|
||||
|
||||
|
||||
var windows = [layers objectForKey:levels[levelCount]]._windows,
|
||||
windowCount = windows.length;
|
||||
|
||||
|
||||
while (windowCount--)
|
||||
{
|
||||
var theWindow = windows[windowCount];
|
||||
@@ -1278,7 +1327,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -1308,7 +1357,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
|
||||
- (CPWindow)hitTest:(CPPoint)location
|
||||
{
|
||||
if (self._only)
|
||||
if (self._only)
|
||||
return self._only;
|
||||
|
||||
var levels = _windowLevels,
|
||||
@@ -1324,7 +1373,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
while (windowCount-- && !theWindow)
|
||||
{
|
||||
var candidateWindow = windows[windowCount];
|
||||
|
||||
|
||||
if (!candidateWindow._ignoresMouseEvents && [candidateWindow containsPoint:location])
|
||||
theWindow = candidateWindow;
|
||||
}
|
||||
@@ -1334,10 +1383,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
|
||||
}
|
||||
|
||||
/*!
|
||||
When using command (mac) or control (windows), keys are propagated to the browser by default.
|
||||
When using command (mac) or control (windows), keys are propagated to the browser by default.
|
||||
To prevent a character key from propagating (to prevent its default action, and instead use it
|
||||
in your own application), use these methods. These methods are additive -- the list builds until you clear it.
|
||||
|
||||
|
||||
@param characters a list of characters to stop propagating keypresses to the browser.
|
||||
*/
|
||||
+ (void)preventCharacterKeysFromPropagating:(CPArray)characters
|
||||
@@ -1418,11 +1467,11 @@ var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
|
||||
{
|
||||
if (!aComparisonEvent)
|
||||
return 1;
|
||||
|
||||
|
||||
var comparisonLocation = [aComparisonEvent locationInWindow];
|
||||
|
||||
return (aTimestamp - [aComparisonEvent timestamp] < CLICK_TIME_DELTA &&
|
||||
ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA &&
|
||||
|
||||
return (aTimestamp - [aComparisonEvent timestamp] < CLICK_TIME_DELTA &&
|
||||
ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA &&
|
||||
ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? [aComparisonEvent clickCount] + 1 : 1;
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 179 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 331 B After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 1002 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 997 B |
|
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 1002 B |
|
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 1017 B |
|
Before Width: | Height: | Size: 115 B After Width: | Height: | Size: 1000 B |
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 1019 B |
|
Before Width: | Height: | Size: 349 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 663 B After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 894 B |
@@ -17,7 +17,7 @@ function findCibClassDependencies(cibPath) {
|
||||
}
|
||||
|
||||
// make sure CPApp is init'd
|
||||
[CPApplication sharedApplication]
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
try {
|
||||
var x = [cib pressInstantiate];
|
||||
@@ -61,7 +61,7 @@ function findCibClassDependencies(cibPath) {
|
||||
|
||||
var topLevelObjects = nil;//[anExternalNameTable objectForKey:CPCibTopLevelObjects];
|
||||
|
||||
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects]
|
||||
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects];
|
||||
// [objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
|
||||
// [objectData awakeWithOwner:owner topLevelObjects:topLevelObjects];
|
||||
|
||||
|
||||
@@ -796,7 +796,7 @@
|
||||
*/
|
||||
- (CPArray)sortedArrayUsingSelector:(SEL)aSelector
|
||||
{
|
||||
var sorted = [self copy]
|
||||
var sorted = [self copy];
|
||||
|
||||
[sorted sortUsingSelector:aSelector];
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -177,10 +177,11 @@ var CPDateReferenceDate = new Date(Date.UTC(2001, 1, 1, 0, 0, 0, 0));
|
||||
*/
|
||||
- (CPString)description
|
||||
{
|
||||
var hours = Math.floor(self.getTimezoneOffset() / 60),
|
||||
var positive = self.getTimezoneOffset() >= 0,
|
||||
hours = FLOOR(self.getTimezoneOffset() / 60),
|
||||
minutes = self.getTimezoneOffset() - hours * 60;
|
||||
|
||||
return [CPString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +%02d%02d", self.getFullYear(), self.getMonth() + 1, self.getDate(), self.getHours(), self.getMinutes(), self.getSeconds(), hours, minutes];
|
||||
return [CPString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d %s%02d%02d", self.getFullYear(), self.getMonth()+1, self.getDate(), self.getHours(), self.getMinutes(), self.getSeconds(), positive ? "+" : "-", ABS(hours), ABS(minutes)];
|
||||
}
|
||||
|
||||
- (id)copy
|
||||
|
||||
@@ -426,6 +426,11 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
|
||||
}
|
||||
else
|
||||
{
|
||||
// The isBefore path may not have been called as would happen if didChangeX
|
||||
// was called alone.
|
||||
if (!changes)
|
||||
changes = [CPDictionary new];
|
||||
|
||||
[changes removeObjectForKey:CPKeyValueChangeNotificationIsPriorKey];
|
||||
|
||||
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey];
|
||||
@@ -738,7 +743,7 @@ var _kvoInsertMethodForMethod = function _kvoInsertMethodForMethod(theKey, theMe
|
||||
{
|
||||
[self willChange:CPKeyValueChangeInsertion valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey];
|
||||
theMethod.method_imp(self, _cmd, object, index);
|
||||
[self didChange:CPKeyValueChangeInsertion valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey]
|
||||
[self didChange:CPKeyValueChangeInsertion valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,7 +753,7 @@ var _kvoReplaceMethodForMethod = function _kvoReplaceMethodForMethod(theKey, the
|
||||
{
|
||||
[self willChange:CPKeyValueChangeReplacement valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey];
|
||||
theMethod.method_imp(self, _cmd, index, object);
|
||||
[self didChange:CPKeyValueChangeReplacement valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey]
|
||||
[self didChange:CPKeyValueChangeReplacement valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,7 +763,7 @@ var _kvoRemoveMethodForMethod = function _kvoRemoveMethodForMethod(theKey, theMe
|
||||
{
|
||||
[self willChange:CPKeyValueChangeRemoval valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey];
|
||||
theMethod.method_imp(self, _cmd, index);
|
||||
[self didChange:CPKeyValueChangeRemoval valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey]
|
||||
[self didChange:CPKeyValueChangeRemoval valuesAtIndexes:[CPIndexSet indexSetWithIndex:index] forKey:theKey];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -548,7 +548,7 @@ CPLog(@"Got some class: %@", inst);
|
||||
objj_class.prototype.toString = objj_object.prototype.toString = function()
|
||||
{
|
||||
if (this.isa && class_getInstanceMethod(this.isa, "description") != NULL)
|
||||
return [this description]
|
||||
return [this description];
|
||||
else
|
||||
return String(this) + " (-description not implemented)";
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
*/
|
||||
+ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
|
||||
{
|
||||
var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat]
|
||||
var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat];
|
||||
|
||||
//add to the runloop
|
||||
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
|
||||
|
||||
@@ -726,6 +726,12 @@ if (_currentGroup == nil)
|
||||
change:(CPDictionary)aChange
|
||||
context:(id)aContext
|
||||
{
|
||||
// Don't add no-ops to the undo stack.
|
||||
var before = [aChange valueForKey:CPKeyValueChangeOldKey],
|
||||
after = [aChange valueForKey:CPKeyValueChangeNewKey];
|
||||
if (before === after || (before !== nil && before.isa && (after === nil || after.isa) && [before isEqual:after]))
|
||||
return;
|
||||
|
||||
[[self prepareWithInvocationTarget:anObject]
|
||||
applyChange:[aChange inverseChangeDictionary]
|
||||
toKeyPath:aKeyPath];
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -227,6 +227,11 @@ CFData.decodeBase64ToString = function(input, strip)
|
||||
return CFData.bytesToString(CFData.decodeBase64ToArray(input, strip));
|
||||
}
|
||||
|
||||
CFData.decodeBase64ToUtf16String = function(input, strip)
|
||||
{
|
||||
return CFData.bytesToUtf16String(CFData.decodeBase64ToArray(input, strip));
|
||||
}
|
||||
|
||||
CFData.bytesToString = function(bytes)
|
||||
{
|
||||
// This is relatively efficient, I think:
|
||||
@@ -242,3 +247,28 @@ CFData.encodeBase64String = function(input)
|
||||
|
||||
return CFData.encodeBase64Array(temp);
|
||||
}
|
||||
|
||||
CFData.bytesToUtf16String = function(bytes)
|
||||
{
|
||||
// Strings are encoded with 16 bits per character.
|
||||
var temp = [];
|
||||
for (var i = 0; i < bytes.length; i+=2)
|
||||
temp.push(bytes[i+1] << 8 | bytes[i]);
|
||||
// This is relatively efficient, I think:
|
||||
return String.fromCharCode.apply(NULL, temp);
|
||||
}
|
||||
|
||||
|
||||
CFData.encodeBase64Utf16String = function(input)
|
||||
{
|
||||
// charCodeAt returns UTF-16.
|
||||
var temp = [];
|
||||
for (var i = 0; i < input.length; i++)
|
||||
{
|
||||
var c = input.charCodeAt(i);
|
||||
temp.push(input.charCodeAt(i) & 0xFF);
|
||||
temp.push((input.charCodeAt(i) & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
return CFData.encodeBase64Array(temp);
|
||||
}
|
||||
|
||||
@@ -219,12 +219,6 @@ CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*B
|
||||
|
||||
CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
|
||||
{
|
||||
for (var i in this._requestHeaders)
|
||||
{
|
||||
if (this._requestHeaders.hasOwnProperty(i))
|
||||
this._nativeRequest.setRequestHeader(i, this._requestHeaders[i]);
|
||||
}
|
||||
|
||||
if (!this._isOpen)
|
||||
{
|
||||
delete this._nativeRequest.onreadystatechange;
|
||||
@@ -232,6 +226,12 @@ CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
|
||||
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
|
||||
}
|
||||
|
||||
for (var i in this._requestHeaders)
|
||||
{
|
||||
if (this._requestHeaders.hasOwnProperty(i))
|
||||
this._nativeRequest.setRequestHeader(i, this._requestHeaders[i]);
|
||||
}
|
||||
|
||||
if (this._mimeType && "overrideMimeType" in this._nativeRequest)
|
||||
this._nativeRequest.overrideMimeType(this._mimeType);
|
||||
|
||||
|
||||
@@ -306,6 +306,8 @@ var XML_XML = "xml",
|
||||
#define PARENT_NODE(anXMLNode) (anXMLNode.parentNode)
|
||||
#define DOCUMENT_ELEMENT(aDocument) (aDocument.documentElement)
|
||||
|
||||
#define HAS_ATTRIBUTE_VALUE(anXMLNode, anAttributeName, aValue) (anXMLNode.getAttribute(anAttributeName) === aValue)
|
||||
|
||||
#define IS_OF_TYPE(anXMLNode, aType) (NODE_NAME(anXMLNode) === aType)
|
||||
#define IS_PLIST(anXMLNode) IS_OF_TYPE(anXMLNode, PLIST_PLIST)
|
||||
|
||||
@@ -559,13 +561,17 @@ CFPropertyList.propertyListFromXML = function(/*String | XMLNode*/ aStringOrXMLN
|
||||
case PLIST_DICTIONARY: object = new CFMutableDictionary();
|
||||
containers.push(object);
|
||||
break;
|
||||
|
||||
|
||||
case PLIST_NUMBER_REAL: object = parseFloat(CHILD_VALUE(XMLNode));
|
||||
break;
|
||||
case PLIST_NUMBER_INTEGER: object = parseInt(CHILD_VALUE(XMLNode), 10);
|
||||
break;
|
||||
|
||||
case PLIST_STRING: object = decodeHTMLComponent(FIRST_CHILD(XMLNode) ? CHILD_VALUE(XMLNode) : "");
|
||||
|
||||
case PLIST_STRING: if (HAS_ATTRIBUTE_VALUE(XMLNode, "type", "base64"))
|
||||
object = FIRST_CHILD(XMLNode) ? CFData.decodeBase64ToString(CHILD_VALUE(XMLNode)) : "";
|
||||
else
|
||||
object = decodeHTMLComponent(FIRST_CHILD(XMLNode) ? CHILD_VALUE(XMLNode) : "");
|
||||
|
||||
break;
|
||||
|
||||
case PLIST_BOOLEAN_TRUE: object = YES;
|
||||
|
||||
@@ -50,7 +50,7 @@ GLOBAL(objj_method) = function(/*String*/ aName, /*IMP*/ anImplementation, /*Str
|
||||
|
||||
DISPLAY_NAME(objj_method);
|
||||
|
||||
GLOBAL(objj_class) = function()
|
||||
GLOBAL(objj_class) = function(displayName)
|
||||
{
|
||||
this.isa = NULL;
|
||||
|
||||
@@ -67,7 +67,14 @@ GLOBAL(objj_class) = function()
|
||||
this.method_store = function() { };
|
||||
this.method_dtable = this.method_store.prototype;
|
||||
|
||||
#if DEBUG
|
||||
// naming the allocator allows the WebKit heap snapshot tool to display object class names correctly
|
||||
// HACK: displayName property is not respected so we must eval a function to name it
|
||||
this.allocator = eval("(function " + (displayName || "OBJJ_OBJECT").replace(/\W/g, "_") + "() { })");
|
||||
#else
|
||||
this.allocator = function() { };
|
||||
#endif
|
||||
|
||||
this._UID = -1;
|
||||
}
|
||||
|
||||
@@ -325,8 +332,8 @@ var REGISTERED_CLASSES = { };
|
||||
|
||||
GLOBAL(objj_allocateClassPair) = function(/*Class*/ superclass, /*String*/ aName)
|
||||
{
|
||||
var classObject = new objj_class(),
|
||||
metaClassObject = new objj_class(),
|
||||
var classObject = new objj_class(aName),
|
||||
metaClassObject = new objj_class(aName),
|
||||
rootClassObject = classObject;
|
||||
|
||||
// If we don't have a superclass, we are the root class.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
@import <AppKit/CPButton.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPText.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@@ -34,4 +35,71 @@
|
||||
wasClicked = YES;
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalent
|
||||
{
|
||||
[button setTarget:self];
|
||||
[button setAction:@selector(clickMe:)];
|
||||
[button setKeyEquivalent:"a"];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"b" charactersIgnoringModifiers:"b" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:wasClicked];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[self assertTrue:wasClicked];
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalentWithModifierMask
|
||||
{
|
||||
[button setTarget:self];
|
||||
[button setAction:@selector(clickMe:)];
|
||||
[button setKeyEquivalent:"a"];
|
||||
[button setKeyEquivalentModifierMask:CPAlternateKeyMask];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:wasClicked];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:CPAlternateKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[self assertTrue:wasClicked];
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalentWithShiftMask
|
||||
{
|
||||
[button setTarget:self];
|
||||
[button setAction:@selector(clickMe:)];
|
||||
[button setKeyEquivalent:"A"];
|
||||
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:wasClicked];
|
||||
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:CPShiftKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"A" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[self assertTrue:wasClicked];
|
||||
}
|
||||
|
||||
- (void)testSpecialKeyEquivalent
|
||||
{
|
||||
[button setTarget:self];
|
||||
[button setAction:@selector(clickMe:)];
|
||||
[button setKeyEquivalent:CPEscapeFunctionKey];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:CPDeleteCharacter charactersIgnoringModifiers:CPDeleteCharacter isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:wasClicked];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:wasClicked];
|
||||
[button performKeyEquivalent:[CPEvent keyEventWithType:CPKeyUp location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:CPEscapeFunctionKey charactersIgnoringModifiers:CPEscapeFunctionKey isARepeat:NO keyCode:0]];
|
||||
[self assertTrue:wasClicked];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPWindow.j>
|
||||
@import <AppKit/CPEvent.j>
|
||||
@import <AppKit/CPButton.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPKeyEquivalentPerformance : OJTestCase
|
||||
|
||||
- (void)testKeyEquivalentSpeed
|
||||
{
|
||||
var REPEATS = 1000,
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0,0,200,150)
|
||||
styleMask:CPWindowNotSizable],
|
||||
contentView = [theWindow contentView],
|
||||
subView1 = [[CPView alloc] initWithFrame:CGRectMakeZero()],
|
||||
subView2 = [[CPView alloc] initWithFrame:CGRectMakeZero()],
|
||||
button1 = [CPButton buttonWithTitle:"when"],
|
||||
button2 = [CPButton buttonWithTitle:"you have eliminated"],
|
||||
button3 = [CPButton buttonWithTitle:"the impossible"];
|
||||
|
||||
[contentView addSubview:subView1];
|
||||
[contentView addSubview:subView2];
|
||||
[subView1 addSubview:button1];
|
||||
[subView2 addSubview:button2];
|
||||
[subView2 addSubview:button3];
|
||||
|
||||
[button1 setTarget:self];
|
||||
[button1 setAction:@selector(clicked:)];
|
||||
[button1 setKeyEquivalent:"a"];
|
||||
[button1 setKeyEquivalentModifierMask:CPControlKeyMask];
|
||||
button1.clicks = 0;
|
||||
|
||||
[button2 setTarget:self];
|
||||
[button2 setAction:@selector(clicked:)];
|
||||
[button2 setKeyEquivalent:"a"];
|
||||
[button2 setKeyEquivalentModifierMask:CPAlternateKeyMask|CPCommandKeyMask];
|
||||
button2.clicks = 0;
|
||||
|
||||
[button3 setTarget:self];
|
||||
[button3 setAction:@selector(clicked:)];
|
||||
[button3 setKeyEquivalent:"A"];
|
||||
[button3 setKeyEquivalentModifierMask:CPControlKeyMask];
|
||||
button3.clicks = 0;
|
||||
|
||||
var start = (new Date).getTime();
|
||||
|
||||
for (var i=0; i<REPEATS; i++)
|
||||
{
|
||||
[theWindow sendEvent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPControlKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[theWindow sendEvent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPAlternateKeyMask|CPCommandKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
[theWindow sendEvent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPControlKeyMask|CPShiftKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"a" charactersIgnoringModifiers:"a" isARepeat:NO keyCode:0]];
|
||||
}
|
||||
|
||||
var end = (new Date).getTime();
|
||||
|
||||
[self assert:REPEATS equals:button1.clicks message:"button1"];
|
||||
[self assert:REPEATS equals:button2.clicks message:"button2"];
|
||||
[self assert:REPEATS equals:button3.clicks message:"button3"];
|
||||
|
||||
CPLog.warn("testKeyEquivalentSpeed: "+(end-start)+"ms");
|
||||
|
||||
}
|
||||
|
||||
- (void)clicked:(id)sender
|
||||
{
|
||||
sender.clicks++;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,182 @@
|
||||
|
||||
@import <AppKit/CPMenu.j>
|
||||
@import <AppKit/CPMenuItem.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPText.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPMenuTest : OJTestCase
|
||||
{
|
||||
CPMenu menu;
|
||||
BOOL escapeWasCalled;
|
||||
BOOL escapeNoModifierWasCalled;
|
||||
BOOL openDocumentWasCalled;
|
||||
BOOL saveDocumentWasCalled;
|
||||
BOOL saveDocumentAsWasCalled;
|
||||
BOOL undoWasCalled;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// Set up a fairly complete menu to have something to work with.
|
||||
menu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
|
||||
|
||||
var newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
|
||||
[menu addItem:newMenuItem];
|
||||
|
||||
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
|
||||
[menu addItem:openMenuItem];
|
||||
|
||||
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
|
||||
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
|
||||
// S
|
||||
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
|
||||
// ...vs Shift-S
|
||||
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:@"S"]];
|
||||
|
||||
|
||||
// Cmd-Escape
|
||||
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Escape the monotonous" action:@selector(escape:) keyEquivalent:CPEscapeFunctionKey]];
|
||||
// Escape
|
||||
var pureEscape = [[CPMenuItem alloc] initWithTitle:@"Escape the cruel" action:@selector(escapeNoModifier:) keyEquivalent:CPEscapeFunctionKey];
|
||||
[pureEscape setKeyEquivalentModifierMask:0];
|
||||
[saveMenu addItem:pureEscape];
|
||||
|
||||
[saveMenuItem setSubmenu:saveMenu];
|
||||
[menu addItem:saveMenuItem];
|
||||
|
||||
var editMenuItem = [[CPMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:nil],
|
||||
editMenu = [[CPMenu alloc] initWithTitle:@"Edit"],
|
||||
|
||||
undoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:CPUndoKeyEquivalent],
|
||||
redoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Redo" action:@selector(redo:) keyEquivalent:CPRedoKeyEquivalent];
|
||||
|
||||
[undoMenuItem setKeyEquivalentModifierMask:CPUndoKeyEquivalentModifierMask];
|
||||
[redoMenuItem setKeyEquivalentModifierMask:CPRedoKeyEquivalentModifierMask];
|
||||
|
||||
[editMenu addItem:undoMenuItem];
|
||||
[editMenu addItem:redoMenuItem];
|
||||
|
||||
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
|
||||
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
|
||||
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
|
||||
|
||||
[editMenuItem setSubmenu:editMenu];
|
||||
[editMenuItem setHidden:YES];
|
||||
|
||||
[menu addItem:editMenuItem];
|
||||
[menu addItem:[CPMenuItem separatorItem]];
|
||||
}
|
||||
|
||||
- (void)_retarget:(CPMenuItem)aMenu
|
||||
{
|
||||
if (!aMenu)
|
||||
return;
|
||||
|
||||
for(var i=0; i<[aMenu numberOfItems]; i++)
|
||||
{
|
||||
var item = [aMenu itemAtIndex:i];
|
||||
[item setTarget:self];
|
||||
[self _retarget:[item submenu]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalent
|
||||
{
|
||||
[self _retarget:menu];
|
||||
|
||||
// Don't match anything.
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPPlatformActionKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"b" charactersIgnoringModifiers:"b" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || escapeNoModifierWasCalled || openDocumentWasCalled || undoWasCalled];
|
||||
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"o" charactersIgnoringModifiers:"o" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || escapeNoModifierWasCalled || openDocumentWasCalled || undoWasCalled];
|
||||
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPPlatformActionKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:"o" charactersIgnoringModifiers:"o" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || escapeNoModifierWasCalled || undoWasCalled];
|
||||
[self assertTrue:openDocumentWasCalled message:"expect openDocumentWasCalled"];
|
||||
|
||||
openDocumentWasCalled = NO;
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPPlatformActionKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:CPUndoKeyEquivalent charactersIgnoringModifiers:CPUndoKeyEquivalent isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || escapeNoModifierWasCalled || openDocumentWasCalled];
|
||||
[self assertTrue:undoWasCalled];
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalentModifierMask
|
||||
{
|
||||
[self _retarget:menu];
|
||||
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:CPEscapeFunctionKey charactersIgnoringModifiers:CPEscapeFunctionKey isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || openDocumentWasCalled || undoWasCalled];
|
||||
[self assertTrue:escapeNoModifierWasCalled];
|
||||
|
||||
escapeNoModifierWasCalled = NO;
|
||||
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPPlatformActionKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:CPEscapeFunctionKey charactersIgnoringModifiers:CPEscapeFunctionKey isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeNoModifierWasCalled || openDocumentWasCalled || undoWasCalled];
|
||||
[self assertTrue:escapeWasCalled];
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalentWithShiftMask
|
||||
{
|
||||
[self _retarget:menu];
|
||||
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPPlatformActionKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:@"s" charactersIgnoringModifiers:@"s" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || escapeNoModifierWasCalled || openDocumentWasCalled || saveDocumentAsWasCalled || undoWasCalled];
|
||||
[self assertTrue:saveDocumentWasCalled message:"saveDocumentWasCalled"];
|
||||
|
||||
saveDocumentWasCalled = NO;
|
||||
|
||||
[menu performKeyEquivalent:[CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:CPPlatformActionKeyMask|CPShiftKeyMask
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:@"s" charactersIgnoringModifiers:@"s" isARepeat:NO keyCode:0]];
|
||||
[self assertFalse:escapeWasCalled || escapeNoModifierWasCalled || openDocumentWasCalled || saveDocumentWasCalled || undoWasCalled];
|
||||
[self assertTrue:saveDocumentAsWasCalled message:"saveDocumentAsWasCalled"];
|
||||
}
|
||||
|
||||
- (void)escape:(id)sender
|
||||
{
|
||||
escapeWasCalled = YES;
|
||||
}
|
||||
|
||||
- (void)escapeNoModifier:(id)sender
|
||||
{
|
||||
escapeNoModifierWasCalled = YES;
|
||||
}
|
||||
|
||||
- (void)openDocument:(id)sender
|
||||
{
|
||||
openDocumentWasCalled = YES;
|
||||
}
|
||||
|
||||
- (void)saveDocument:(id)sender
|
||||
{
|
||||
saveDocumentWasCalled = YES;
|
||||
}
|
||||
|
||||
- (void)saveDocumentAs:(id)sender
|
||||
{
|
||||
saveDocumentAsWasCalled = YES;
|
||||
}
|
||||
|
||||
- (void)undo:(id)sender
|
||||
{
|
||||
undoWasCalled = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,75 @@
|
||||
@import <AppKit/CPView.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPText.j>
|
||||
|
||||
@import <AppKit/CPPlatformWindow+DOMKeys.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPResponderTest : OJTestCase
|
||||
{
|
||||
CPWindow theWindow;
|
||||
CPResponder responder;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
responder = [TestResponder new];
|
||||
responder.doCommandCalls = [];
|
||||
}
|
||||
|
||||
- (void)testInterpretKeyEvents
|
||||
{
|
||||
var tests = [
|
||||
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(insertNewline:),
|
||||
0, CPNewlineCharacter, @selector(insertNewline:),
|
||||
CPKeyCodes.ESC, CPEscapeFunctionKey, @selector(cancelOperation:),
|
||||
CPKeyCodes.TAB, CPTabCharacter, @selector(insertTab:)
|
||||
];
|
||||
|
||||
for (var i=0; i<tests.length; i += 3)
|
||||
{
|
||||
var keyCode = tests[i],
|
||||
character = tests[i+1],
|
||||
selector = tests[i+2];
|
||||
|
||||
responder.doCommandCalls = [];
|
||||
keyEvent = [CPEvent keyEventWithType:CPKeyDown location:CGPointMakeZero() modifierFlags:0
|
||||
timestamp:nil windowNumber:nil context:nil
|
||||
characters:character charactersIgnoringModifiers:character isARepeat:NO keyCode:keyCode];
|
||||
[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:CPLeftArrowFunctionKey charactersIgnoringModifiers:CPLeftArrowFunctionKey isARepeat:NO keyCode:CPKeyCodes.LEFT];
|
||||
[responder interpretKeyEvents:[keyEvent]];
|
||||
[self assert:[@selector(moveLeftAndModifySelection:)] equals:responder.doCommandCalls];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TestResponder : CPResponder
|
||||
{
|
||||
CPArray doCommandCalls;
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)aSelector
|
||||
{
|
||||
doCommandCalls.push(aSelector);
|
||||
[super doCommandBySelector:aSelector];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -62,15 +62,46 @@
|
||||
|
||||
- (void)testDescription
|
||||
{
|
||||
// Unfortunately the result will be different depending on the testing machine's timezone.
|
||||
// Unfortunately the result will be different depending on the testing machine's timezone, so
|
||||
// this test turns out to be more complex than the code tested. We can't just reuse the
|
||||
// original code as then we'd have exactly the same bugs.
|
||||
var date = [CPDate dateWithTimeIntervalSince1970: 1234567890],
|
||||
expectedDay = 13,
|
||||
expectedHour = 23,
|
||||
expectedMinute = 31,
|
||||
offsetPositive = date.getTimezoneOffset() >= 0,
|
||||
offsetHours = Math.floor(date.getTimezoneOffset() / 60),
|
||||
offsetMinutes = date.getTimezoneOffset() - offsetHours * 60,
|
||||
expectedString = [CPString stringWithFormat:"2009-02-13 %02d:%02d:30 +%02d%02d", expectedHour-offsetHours, expectedMinute-offsetMinutes, offsetHours, offsetMinutes];
|
||||
expectedString;
|
||||
expectedHour -= offsetHours;
|
||||
expectedMinute -= offsetMinutes;
|
||||
if (expectedMinute < 0)
|
||||
{
|
||||
expectedMinute += 60;
|
||||
expectedHour--;
|
||||
}
|
||||
else if (expectedMinute > 59)
|
||||
{
|
||||
expectedMinute -= 60;
|
||||
expectedHour++;
|
||||
}
|
||||
if (expectedHour < 0)
|
||||
{
|
||||
expectedHour += 24;
|
||||
expectedDay--;
|
||||
}
|
||||
else if (expectedHour > 23)
|
||||
{
|
||||
expectedHour -= 24;
|
||||
expectedDay++;
|
||||
}
|
||||
|
||||
[self assert:expectedString equals:[date description]];
|
||||
if (offsetPositive)
|
||||
expectedString = [CPString stringWithFormat:"2009-02-%02d %02d:%02d:30 +%02d%02d", expectedDay, expectedHour, expectedMinute, offsetHours, offsetMinutes];
|
||||
else
|
||||
expectedString = [CPString stringWithFormat:"2009-02-%02d %02d:%02d:30 -%02d%02d", expectedDay, expectedHour, expectedMinute, ABS(offsetHours), ABS(offsetMinutes)];
|
||||
|
||||
[self assert:expectedString equals: [date description]];
|
||||
}
|
||||
|
||||
- (void)testCopy
|
||||
|
||||
@@ -42,10 +42,16 @@ var base64TestStrings = [
|
||||
{
|
||||
var result = CFData.decodeBase64ToArray(base64TestStrings[i][1]),
|
||||
expected = base64TestStrings[i][0];
|
||||
|
||||
|
||||
for (var j = 0; j < expected.length || j < result.length; j++)
|
||||
[self assert:result[j] equals:expected.charCodeAt(j)];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)test_CFData_encodeUtfString
|
||||
{
|
||||
var utfTest = "\uF728"; // A common key equivalent.
|
||||
[self assert:CFData.decodeBase64ToUtf16String(CFData.encodeBase64Utf16String(utfTest)) equals:utfTest];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
- (void)sendEvent:(NSEvent *)anEvent
|
||||
{
|
||||
[WebWindow enableAllWindows];
|
||||
|
||||
NSWindow * window = [anEvent window];
|
||||
|
||||
if (!window || [window isKindOfClass:[WebWindow class]])
|
||||
|
||||
@@ -18,9 +18,6 @@ CGEventRef headTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e
|
||||
// It's dangerous to fail in this code: could disable mousedown system-wide. So just try catch it all.
|
||||
@try
|
||||
{
|
||||
[DisabledWindows makeObjectsPerformSelector:@selector(stopIgnoringMouseEvents)];
|
||||
[DisabledWindows removeAllObjects];
|
||||
|
||||
if (type == kCGEventLeftMouseDown)
|
||||
{
|
||||
CGPoint location = CGEventGetLocation(event);
|
||||
@@ -55,6 +52,12 @@ CGEventRef headTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e
|
||||
|
||||
@implementation WebWindow
|
||||
|
||||
+ (void)enableAllWindows
|
||||
{
|
||||
[DisabledWindows makeObjectsPerformSelector:@selector(stopIgnoringMouseEvents)];
|
||||
[DisabledWindows removeAllObjects];
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self != [WebWindow class])
|
||||
@@ -117,8 +120,9 @@ CGEventRef headTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e
|
||||
|
||||
[self setBackgroundColor:[NSColor clearColor]];
|
||||
[self setOpaque:NO];
|
||||
[self setIgnoresMouseEvents:NO];
|
||||
[self setReleasedWhenClosed:YES];
|
||||
[super setHasShadow:NO];
|
||||
[super setHasShadow:NO];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -121,9 +121,9 @@ ConverterConversionException = @"ConverterConversionException";
|
||||
else
|
||||
plistContents = plistContents.replace(/\<key\>\s*CF\$UID\s*\<\/key\>/g, "<key>CP$UID</key>");
|
||||
|
||||
plistContents = plistContents.replace(/\u001b/g, function(c) {
|
||||
CPLog.warn("Warning: Stripping character 0x"+c.charCodeAt(0).toString(16));
|
||||
return "";
|
||||
plistContents = plistContents.replace(/<string>[\u0000-\u0008\u000B\u000C\u000E-\u001F]<\/string>/g, function(c) {
|
||||
CPLog.warn("Warning: Converting character 0x"+c.charCodeAt(8).toString(16)+" to base64 representation");
|
||||
return "<string type=\"base64\">"+CFData.encodeBase64String(c.charAt(8))+"</string>";
|
||||
});
|
||||
|
||||
return [CPData dataWithRawString:plistContents];
|
||||
|
||||
@@ -97,6 +97,7 @@ _CPButtonBezelStyleHeights[CPHUDBezelStyle] = 20;
|
||||
{
|
||||
CPLog.info("Adjusting CPButton height from " +_frame.size.height+ " / " + _bounds.size.height+" to " + 24);
|
||||
_frame.size.height = 24.0;
|
||||
_frame.origin.y += 4.0;
|
||||
_bounds.size.height = 24.0;
|
||||
}
|
||||
}
|
||||
@@ -180,6 +181,9 @@ _CPButtonBezelStyleHeights[CPHUDBezelStyle] = 20;
|
||||
}
|
||||
}
|
||||
|
||||
[self setKeyEquivalent:[cell keyEquivalent]];
|
||||
[self setKeyEquivalentModifierMask:[cell keyEquivalentModifierMask]];
|
||||
|
||||
return [self NS_initWithCoder:aCoder];
|
||||
}
|
||||
|
||||
@@ -203,6 +207,9 @@ _CPButtonBezelStyleHeights[CPHUDBezelStyle] = 20;
|
||||
|
||||
CPString _title @accessors(readonly, getter=title);
|
||||
CPImage _alternateImage @accessors(readonly, getter=alternateImage);
|
||||
|
||||
CPString _keyEquivalent @accessors(readonly, getter=keyEquivalent);
|
||||
unsigned _keyEquivalentModifierMask @accessors(readonly, getter=keyEquivalentModifierMask);
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
@@ -223,6 +230,9 @@ _CPButtonBezelStyleHeights[CPHUDBezelStyle] = 20;
|
||||
_objectValue = [self state];
|
||||
|
||||
_alternateImage = [aCoder decodeObjectForKey:@"NSAlternateImage"];
|
||||
|
||||
_keyEquivalent = [aCoder decodeObjectForKey:@"NSKeyEquivalent"];
|
||||
_keyEquivalentModifierMask = buttonFlags2 >> 8;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
var cell = [aCoder decodeObjectForKey:@"NSCell"];
|
||||
|
||||
[self setImageScaling:[cell imageScaling]];
|
||||
[self setImageAlignment:[cell imageAlignment]];
|
||||
_isEditable = [cell isEditable];
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ NSImageScalingToCPImageScaling[NSImageScaleProportionallyUpOrDown] = CPScalePro
|
||||
@implementation NSImageCell : NSCell
|
||||
{
|
||||
BOOL _animates @accessors;
|
||||
NSImageAlignment _imageAlignment @accessors;
|
||||
NSImageAlignment _imageAlignment @accessors(readonly, getter=imageAlignment);
|
||||
NSImageScaling _imageScaling @accessors(readonly, getter=imageScaling);
|
||||
NSImageFrameStyle _frameStyle @accessors;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,9 @@
|
||||
_selectedSegment = [aCoder decodeIntForKey:"NSSelectedSegment"] || -1;
|
||||
_segmentStyle = [aCoder decodeIntForKey:"NSSegmentStyle"];
|
||||
_trackingMode = [aCoder decodeIntForKey:"NSTrackingMode"] || CPSegmentSwitchTrackingSelectOne;
|
||||
|
||||
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && _selectedSegment == -1)
|
||||
_selectedSegment = 0;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||