mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-09 20:27:13 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4091acd0ec | ||
|
|
f8114b0760 |
+4
-9
@@ -36,8 +36,8 @@
|
|||||||
@import "CPCibLoading.j"
|
@import "CPCibLoading.j"
|
||||||
@import "CPCibOutletConnector.j"
|
@import "CPCibOutletConnector.j"
|
||||||
@import "CPClipView.j"
|
@import "CPClipView.j"
|
||||||
@import "CPCollectionView.j"
|
|
||||||
@import "CPCollectionViewItem.j"
|
@import "CPCollectionViewItem.j"
|
||||||
|
@import "CPCollectionView.j"
|
||||||
@import "CPColor.j"
|
@import "CPColor.j"
|
||||||
@import "CPColorPanel.j"
|
@import "CPColorPanel.j"
|
||||||
@import "CPColorWell.j"
|
@import "CPColorWell.j"
|
||||||
@@ -53,10 +53,8 @@
|
|||||||
@import "CPFont.j"
|
@import "CPFont.j"
|
||||||
@import "CPFontManager.j"
|
@import "CPFontManager.j"
|
||||||
@import "CPGeometry.j"
|
@import "CPGeometry.j"
|
||||||
@import "CPGraphics.j"
|
|
||||||
@import "CPImage.j"
|
@import "CPImage.j"
|
||||||
@import "CPImageView.j"
|
@import "CPImageView.j"
|
||||||
@import "CPKeyBinding.j"
|
|
||||||
@import "CPMenu.j"
|
@import "CPMenu.j"
|
||||||
@import "CPMenuItem.j"
|
@import "CPMenuItem.j"
|
||||||
@import "CPOpenPanel.j"
|
@import "CPOpenPanel.j"
|
||||||
@@ -67,22 +65,20 @@
|
|||||||
@import "CPProgressIndicator.j"
|
@import "CPProgressIndicator.j"
|
||||||
@import "CPRadio.j"
|
@import "CPRadio.j"
|
||||||
@import "CPResponder.j"
|
@import "CPResponder.j"
|
||||||
@import "CPScroller.j"
|
|
||||||
@import "CPScrollView.j"
|
|
||||||
@import "CPSearchField.j"
|
@import "CPSearchField.j"
|
||||||
|
@import "CPScrollView.j"
|
||||||
|
@import "CPScroller.j"
|
||||||
@import "CPSecureTextField.j"
|
@import "CPSecureTextField.j"
|
||||||
@import "CPSegmentedControl.j"
|
@import "CPSegmentedControl.j"
|
||||||
@import "CPShadow.j"
|
@import "CPShadow.j"
|
||||||
@import "CPSlider.j"
|
@import "CPSlider.j"
|
||||||
@import "CPSplitView.j"
|
@import "CPSplitView.j"
|
||||||
|
@import "CPTabView.j"
|
||||||
@import "CPTableColumn.j"
|
@import "CPTableColumn.j"
|
||||||
@import "CPTableView.j"
|
@import "CPTableView.j"
|
||||||
@import "CPTabView.j"
|
|
||||||
@import "CPText.j"
|
|
||||||
@import "CPTextField.j"
|
@import "CPTextField.j"
|
||||||
@import "CPToolbar.j"
|
@import "CPToolbar.j"
|
||||||
@import "CPToolbarItem.j"
|
@import "CPToolbarItem.j"
|
||||||
@import "CPTokenField.j"
|
|
||||||
@import "CPTreeNode.j"
|
@import "CPTreeNode.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
@import "CPViewAnimation.j"
|
@import "CPViewAnimation.j"
|
||||||
@@ -90,4 +86,3 @@
|
|||||||
@import "CPWebView.j"
|
@import "CPWebView.j"
|
||||||
@import "CPWindow.j"
|
@import "CPWindow.j"
|
||||||
@import "CPWindowController.j"
|
@import "CPWindowController.j"
|
||||||
@import "CPArrayController.j"
|
|
||||||
|
|||||||
@@ -26,16 +26,11 @@
|
|||||||
@import <Foundation/CPIndexSet.j>
|
@import <Foundation/CPIndexSet.j>
|
||||||
@import <Foundation/CPString.j>
|
@import <Foundation/CPString.j>
|
||||||
|
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
@import "CPButton.j"
|
|
||||||
|
#import "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@ingroup appkit
|
|
||||||
@class CPAccordionViewItem
|
|
||||||
|
|
||||||
<p>A CPAccordionViewItem represents a single section of a CPAccordionView.</p>
|
|
||||||
*/
|
|
||||||
@implementation CPAccordionViewItem : CPObject
|
@implementation CPAccordionViewItem : CPObject
|
||||||
{
|
{
|
||||||
CPString _identifier @accessors(property=identifier);
|
CPString _identifier @accessors(property=identifier);
|
||||||
@@ -48,10 +43,6 @@
|
|||||||
return [self initWithIdentifier:@""];
|
return [self initWithIdentifier:@""];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Initializes a new CPAccordionViewItem with the specified identifier. This identifier may
|
|
||||||
then be used in subsequent methods to provide abstract introspection of the CPAccordionView.
|
|
||||||
*/
|
|
||||||
- (id)initWithIdentifier:(CPString)anIdentifier
|
- (id)initWithIdentifier:(CPString)anIdentifier
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
@@ -64,25 +55,6 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/*!
|
|
||||||
@ingroup appkit
|
|
||||||
@class CPAccordionView
|
|
||||||
|
|
||||||
<p>CPAccordionView provides a container for CPAccordionViewItem objects and manages layout state
|
|
||||||
for all sublayout items.</p>
|
|
||||||
|
|
||||||
<strong>Example</strong><br />
|
|
||||||
<pre>
|
|
||||||
var myAccordionView = [[CPAccordionView alloc] initWithFrame:CGRectMakeZero()];
|
|
||||||
var firstItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"firstSection"]];
|
|
||||||
[firstItem setView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
|
|
||||||
var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection"]];
|
|
||||||
[secondItem setView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
|
|
||||||
[myAccordionView addItem:firstItem];
|
|
||||||
[myAccordionView addItem:secondItem];
|
|
||||||
[myAccordionView setAutoresizingMask: CPViewWidthSizable | CPViewHeightSizable];
|
|
||||||
</pre>
|
|
||||||
*/
|
|
||||||
@implementation CPAccordionView : CPView
|
@implementation CPAccordionView : CPView
|
||||||
{
|
{
|
||||||
CPInteger _dirtyItemIndex;
|
CPInteger _dirtyItemIndex;
|
||||||
@@ -92,10 +64,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
|
|||||||
CPMutableArray _itemViews;
|
CPMutableArray _itemViews;
|
||||||
CPIndexSet _expandedItemIndexes;
|
CPIndexSet _expandedItemIndexes;
|
||||||
}
|
}
|
||||||
/*!
|
|
||||||
Initializes the receiver for usage with the specified bounding rectangle
|
|
||||||
@return the initialized view
|
|
||||||
*/
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
@@ -126,11 +95,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
|
|||||||
{
|
{
|
||||||
return _items;
|
return _items;
|
||||||
}
|
}
|
||||||
/*!
|
|
||||||
Append a CPAccordionViewItem to the receiver. Note that the CPAccordionViewItem must contain
|
|
||||||
a valid CPView derived component or a TypeError will be generated when the contents of the
|
|
||||||
ViewItem are disclosed.
|
|
||||||
*/
|
|
||||||
- (void)addItem:(CPAccordionViewItem)anItem
|
- (void)addItem:(CPAccordionViewItem)anItem
|
||||||
{
|
{
|
||||||
[self insertItem:anItem atIndex:_items.length];
|
[self insertItem:anItem atIndex:_items.length];
|
||||||
|
|||||||
+95
-249
@@ -26,30 +26,35 @@
|
|||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
@import <Foundation/CPString.j>
|
@import <Foundation/CPString.j>
|
||||||
|
|
||||||
@import "CPApplication.j"
|
@import <AppKit/CPApplication.j>
|
||||||
@import "CPButton.j"
|
@import <AppKit/CPButton.j>
|
||||||
@import "CPColor.j"
|
@import <AppKit/CPColor.j>
|
||||||
@import "CPFont.j"
|
@import <AppKit/CPFont.j>
|
||||||
@import "CPImage.j"
|
@import <AppKit/CPImage.j>
|
||||||
@import "CPImageView.j"
|
@import <AppKit/CPImageView.j>
|
||||||
@import "CPPanel.j"
|
@import <AppKit/CPPanel.j>
|
||||||
@import "CPTextField.j"
|
@import <AppKit/CPTextField.j>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@global
|
@global
|
||||||
@group CPAlertStyle
|
@group CPAlertStyle
|
||||||
*/
|
*/
|
||||||
CPWarningAlertStyle = 0;
|
CPWarningAlertStyle = 0;
|
||||||
/*
|
/*
|
||||||
@global
|
@global
|
||||||
@group CPAlertStyle
|
@group CPAlertStyle
|
||||||
*/
|
*/
|
||||||
CPInformationalAlertStyle = 1;
|
CPInformationalAlertStyle = 1;
|
||||||
/*
|
/*
|
||||||
@global
|
@global
|
||||||
@group CPAlertStyle
|
@group CPAlertStyle
|
||||||
*/
|
*/
|
||||||
CPCriticalAlertStyle = 2;
|
CPCriticalAlertStyle = 2;
|
||||||
|
|
||||||
|
|
||||||
|
var CPAlertWarningImage,
|
||||||
|
CPAlertInformationImage,
|
||||||
|
CPAlertErrorImage;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -73,47 +78,37 @@ CPCriticalAlertStyle = 2;
|
|||||||
representing the first button added to the alert which appears on the
|
representing the first button added to the alert which appears on the
|
||||||
right, 1 representing the next button to the left and so on)
|
right, 1 representing the next button to the left and so on)
|
||||||
*/
|
*/
|
||||||
@implementation CPAlert : CPView
|
@implementation CPAlert : CPObject
|
||||||
{
|
{
|
||||||
CPPanel _alertPanel;
|
CPPanel _alertPanel;
|
||||||
|
|
||||||
CPTextField _messageLabel;
|
CPTextField _messageLabel;
|
||||||
CPTextField _informativeLabel;
|
|
||||||
CPImageView _alertImageView;
|
CPImageView _alertImageView;
|
||||||
|
|
||||||
CPAlertStyle _alertStyle;
|
CPAlertStyle _alertStyle;
|
||||||
CPString _windowTitle;
|
CPString _windowTitle;
|
||||||
int _windowStyle;
|
int _windowStyle;
|
||||||
|
int _buttonCount;
|
||||||
CPArray _buttons;
|
CPArray _buttons;
|
||||||
|
|
||||||
id _delegate;
|
id _delegate;
|
||||||
SEL _didEndSelector;
|
|
||||||
id _modalDelegate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (void)initialize
|
||||||
{
|
{
|
||||||
return @"alert";
|
if (self != CPAlert)
|
||||||
}
|
return;
|
||||||
|
|
||||||
+ (id)themeAttributes
|
var bundle = [CPBundle bundleForClass:[self class]];
|
||||||
{
|
|
||||||
return [CPDictionary dictionaryWithObjects:[CGSizeMake(400.0, 110.0), CGInsetMake(15, 15, 15, 50), 6, 10,
|
CPAlertWarningImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPAlert/dialog-warning.png"]
|
||||||
CPJustifiedTextAlignment, [CPColor blackColor], [CPFont boldSystemFontOfSize:13.0], [CPNull null], CGSizeMakeZero(),
|
size:CGSizeMake(32.0, 32.0)];
|
||||||
CPJustifiedTextAlignment, [CPColor blackColor], [CPFont systemFontOfSize:12.0], [CPNull null], CGSizeMakeZero(),
|
|
||||||
CGPointMake(15, 12),
|
CPAlertInformationImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPAlert/dialog-information.png"]
|
||||||
[CPNull null],
|
size:CGSizeMake(32.0, 32.0)];
|
||||||
[CPNull null],
|
|
||||||
[CPNull null]
|
CPAlertErrorImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPAlert/dialog-error.png"]
|
||||||
]
|
size:CGSizeMake(32.0, 32.0)];
|
||||||
forKeys:[@"size", @"content-inset", @"informative-offset", @"button-offset",
|
|
||||||
@"message-text-alignment", @"message-text-color", @"message-text-font", @"message-text-shadow-color", @"message-text-shadow-offset",
|
|
||||||
@"informative-text-alignment", @"informative-text-color", @"informative-text-font", @"informative-text-shadow-color", @"informative-text-shadow-offset",
|
|
||||||
@"image-offset",
|
|
||||||
@"information-image",
|
|
||||||
@"warning-image",
|
|
||||||
@"error-image"
|
|
||||||
]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -123,56 +118,57 @@ CPCriticalAlertStyle = 2;
|
|||||||
{
|
{
|
||||||
if (self = [super init])
|
if (self = [super init])
|
||||||
{
|
{
|
||||||
|
_buttonCount = 0;
|
||||||
_buttons = [CPArray array];
|
_buttons = [CPArray array];
|
||||||
_alertStyle = CPWarningAlertStyle;
|
_alertStyle = CPWarningAlertStyle;
|
||||||
_alertPanel = nil;
|
|
||||||
_windowStyle = nil;
|
|
||||||
_didEndSelector = nil;
|
|
||||||
|
|
||||||
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
|
[self setWindowStyle:nil];
|
||||||
_alertImageView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
|
||||||
_informativeLabel = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the window appearance. If CPHUDBackgroundWindowMask is set, the default HUD theme
|
Sets the window appearance.
|
||||||
will be activated.
|
|
||||||
|
|
||||||
@param styleMask - Either CPHUDBackgroundWindowMask or nil for standard.
|
@param styleMask - Either CPHUDBackgroundWindowMask or nil for standard.
|
||||||
*/
|
*/
|
||||||
- (void)setWindowStyle:(int)styleMask
|
- (void)setWindowStyle:(int)styleMask
|
||||||
{
|
{
|
||||||
_windowStyle = styleMask;
|
_windowStyle = styleMask;
|
||||||
|
|
||||||
[self setTheme:(_windowStyle & CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
|
_alertPanel = [[CPPanel alloc] initWithContentRect:CGRectMake(0.0, 0.0, 400.0, 110.0) styleMask:styleMask ? styleMask | CPTitledWindowMask : CPTitledWindowMask];
|
||||||
|
[_alertPanel setFloatingPanel:YES];
|
||||||
|
[_alertPanel center];
|
||||||
|
|
||||||
// We'll need to recreate the panel to get the new window style.
|
[_messageLabel setTextColor:(styleMask & CPHUDBackgroundWindowMask) ? [CPColor whiteColor] : [CPColor blackColor]];
|
||||||
_alertPanel = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_createPanel
|
var count = [_buttons count];
|
||||||
{
|
for(var i=0; i < count; i++)
|
||||||
var frame = CGRectMakeZero();
|
|
||||||
frame.size = [self currentValueForThemeAttribute:@"size"];
|
|
||||||
_alertPanel = [[CPPanel alloc] initWithContentRect:frame styleMask:_windowStyle ? _windowStyle | CPTitledWindowMask : CPTitledWindowMask];
|
|
||||||
|
|
||||||
var contentView = [_alertPanel contentView],
|
|
||||||
count = [_buttons count];
|
|
||||||
|
|
||||||
if (count)
|
|
||||||
{
|
{
|
||||||
while (count--)
|
var button = _buttons[i];
|
||||||
[contentView addSubview:_buttons[count]];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
[self addButtonWithTitle:@"OK"];
|
|
||||||
|
|
||||||
[contentView addSubview:_messageLabel];
|
[button setFrameSize:CGSizeMake([button frame].size.width, (styleMask == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
|
||||||
[contentView addSubview:_alertImageView];
|
|
||||||
[contentView addSubview:_informativeLabel];
|
[button setTheme:(_windowStyle === CPHUDBackgroundWindowMask) ? [CPTheme themeNamed:"Aristo-HUD"] : [CPTheme defaultTheme]];
|
||||||
|
|
||||||
|
[[_alertPanel contentView] addSubview:button];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_messageLabel)
|
||||||
|
{
|
||||||
|
var bounds = [[_alertPanel contentView] bounds];
|
||||||
|
|
||||||
|
_messageLabel = [[CPTextField alloc] initWithFrame:CGRectMake(57.0, 10.0, CGRectGetWidth(bounds) - 73.0, 62.0)];
|
||||||
|
[_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)];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[_alertPanel contentView] addSubview:_messageLabel];
|
||||||
|
[[_alertPanel contentView] addSubview:_alertImageView];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -235,7 +231,7 @@ CPCriticalAlertStyle = 2;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the receiver’s message text, or title, to a given text.
|
Set’s the receiver’s message text, or title, to a given text.
|
||||||
@param messageText - Message text for the alert.
|
@param messageText - Message text for the alert.
|
||||||
*/
|
*/
|
||||||
- (void)setMessageText:(CPString)messageText
|
- (void)setMessageText:(CPString)messageText
|
||||||
@@ -244,156 +240,40 @@ CPCriticalAlertStyle = 2;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the receiver's message text body.
|
Return's the receiver's message text body.
|
||||||
*/
|
*/
|
||||||
- (CPString)messageText
|
- (CPString)messageText
|
||||||
{
|
{
|
||||||
return [_messageLabel stringValue];
|
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the receiver's informative text.
|
|
||||||
*/
|
|
||||||
- (CPString)informativeText
|
|
||||||
{
|
|
||||||
return [_informativeLabel stringValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Adds a button with a given title to the receiver.
|
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.
|
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 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.
|
You really shouldn't need more than 3 buttons.
|
||||||
*/
|
*/
|
||||||
- (void)addButtonWithTitle:(CPString)title
|
- (void)addButtonWithTitle:(CPString)title
|
||||||
{
|
{
|
||||||
var bounds = [[_alertPanel contentView] bounds],
|
var bounds = [[_alertPanel contentView] bounds],
|
||||||
button = [[CPButton alloc] initWithFrame:CGRectMakeZero()],
|
button = [[CPButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(bounds) - ((_buttonCount + 1) * 90.0), CGRectGetHeight(bounds) - 34.0, 80.0, (_windowStyle == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
|
||||||
_buttonCount = [_buttons count];
|
|
||||||
|
|
||||||
[button setTitle:title];
|
[button setTitle:title];
|
||||||
[button setTarget:self];
|
[button setTarget:self];
|
||||||
[button setTag:_buttonCount];
|
[button setTag:_buttonCount];
|
||||||
[button setAction:@selector(_dismissAlert:)];
|
[button setAction:@selector(_notifyDelegate:)];
|
||||||
|
|
||||||
|
[button setTheme:(_windowStyle === CPHUDBackgroundWindowMask) ? [CPTheme themeNamed:"Aristo-HUD"] : [CPTheme defaultTheme]];
|
||||||
|
[button setAutoresizingMask:CPViewMinXMargin | CPViewMinYMargin];
|
||||||
|
|
||||||
[[_alertPanel contentView] addSubview:button];
|
[[_alertPanel contentView] addSubview:button];
|
||||||
|
|
||||||
if (_buttonCount == 0)
|
if (_buttonCount == 0)
|
||||||
[button setKeyEquivalent:CPCarriageReturnCharacter];
|
[_alertPanel setDefaultButton:button];
|
||||||
else if ([title lowercaseString] === "cancel")
|
|
||||||
[button setKeyEquivalent:CPEscapeFunctionKey];
|
|
||||||
else
|
|
||||||
[button setKeyEquivalent:nil];
|
|
||||||
|
|
||||||
[_buttons insertObject:button atIndex:0];
|
_buttonCount++;
|
||||||
}
|
[_buttons addObject:button];
|
||||||
|
|
||||||
- (void)layoutPanel
|
|
||||||
{
|
|
||||||
if (!_alertPanel)
|
|
||||||
[self _createPanel];
|
|
||||||
|
|
||||||
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
|
||||||
iconOffset = [self currentValueForThemeAttribute:@"image-offset"],
|
|
||||||
theTitle,
|
|
||||||
theImage;
|
|
||||||
|
|
||||||
switch (_alertStyle)
|
|
||||||
{
|
|
||||||
case CPWarningAlertStyle: theImage = [self currentValueForThemeAttribute:@"warning-image"];
|
|
||||||
theTitle = @"Warning";
|
|
||||||
break;
|
|
||||||
case CPInformationalAlertStyle: theImage = [self currentValueForThemeAttribute:@"information-image"];
|
|
||||||
theTitle = @"Information";
|
|
||||||
break;
|
|
||||||
case CPCriticalAlertStyle: theImage = [self currentValueForThemeAttribute:@"error-image"];
|
|
||||||
theTitle = @"Error";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
[_alertImageView setImage:theImage];
|
|
||||||
|
|
||||||
var imageSize = theImage ? [theImage size] : CGSizeMakeZero();
|
|
||||||
[_alertImageView setFrame:CGRectMake(iconOffset.x, iconOffset.y, imageSize.width, imageSize.height)];
|
|
||||||
|
|
||||||
[_alertPanel setTitle:_windowTitle ? _windowTitle : theTitle];
|
|
||||||
[_alertPanel setFloatingPanel:YES];
|
|
||||||
[_alertPanel center];
|
|
||||||
|
|
||||||
[_messageLabel setTextColor:[self currentValueForThemeAttribute:@"message-text-color"]];
|
|
||||||
[_messageLabel setFont:[self currentValueForThemeAttribute:@"message-text-font"]];
|
|
||||||
[_messageLabel setTextShadowColor:[self currentValueForThemeAttribute:@"message-text-shadow-color"]];
|
|
||||||
[_messageLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"message-text-shadow-offset"]];
|
|
||||||
[_messageLabel setAlignment:[self currentValueForThemeAttribute:@"message-text-alignment"]];
|
|
||||||
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
|
|
||||||
|
|
||||||
[_informativeLabel setTextColor:[self currentValueForThemeAttribute:@"informative-text-color"]];
|
|
||||||
[_informativeLabel setFont:[self currentValueForThemeAttribute:@"informative-text-font"]];
|
|
||||||
[_informativeLabel setTextShadowColor:[self currentValueForThemeAttribute:@"informative-text-shadow-color"]];
|
|
||||||
[_informativeLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
|
|
||||||
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
|
|
||||||
|
|
||||||
// FIXME sizeWithFontCorrection shouldn't be needed.
|
|
||||||
var bounds = [[_alertPanel contentView] bounds],
|
|
||||||
offsetX = CGRectGetWidth(bounds) - inset.right,
|
|
||||||
informativeOffset = [self currentValueForThemeAttribute:@"informative-offset"],
|
|
||||||
buttonOffset = [self currentValueForThemeAttribute:@"button-offset"],
|
|
||||||
|
|
||||||
textWidth = offsetX - inset.left,
|
|
||||||
messageSize = [([_messageLabel stringValue] || " ") sizeWithFont:[_messageLabel font] inWidth:textWidth],
|
|
||||||
informationString = [_informativeLabel stringValue],
|
|
||||||
informativeSize = [(informationString || " ") sizeWithFont:[_informativeLabel font] inWidth:textWidth],
|
|
||||||
sizeWithFontCorrection = 6.0;
|
|
||||||
|
|
||||||
[_messageLabel setFrame:CGRectMake(inset.left, inset.top, textWidth, messageSize.height + sizeWithFontCorrection)];
|
|
||||||
[_informativeLabel setFrame:CGRectMake(inset.left, CGRectGetMaxY([_messageLabel frame]) + informativeOffset, textWidth, informativeSize.height + sizeWithFontCorrection)];
|
|
||||||
// Don't let an empty informative label partially cover the buttons.
|
|
||||||
[_informativeLabel setHidden:!informationString];
|
|
||||||
|
|
||||||
var aRepresentativeButton = _buttons[0],
|
|
||||||
buttonY = MAX(CGRectGetMaxY([_alertImageView frame]), CGRectGetMaxY(informationString ? [_informativeLabel frame] : [_messageLabel frame])) + buttonOffset; // the lower of the bottom of the text and the bottom of the icon.
|
|
||||||
|
|
||||||
[aRepresentativeButton setTheme:[self theme]];
|
|
||||||
[aRepresentativeButton sizeToFit];
|
|
||||||
|
|
||||||
// Make the window just tall enough to fit everything. Bit of a hack really.
|
|
||||||
var minimumSize = [self currentValueForThemeAttribute:@"size"],
|
|
||||||
desiredHeight = MAX(minimumSize.height, buttonY + CGRectGetHeight([aRepresentativeButton bounds]) + inset.bottom),
|
|
||||||
deltaY = desiredHeight - CGRectGetHeight(bounds),
|
|
||||||
frameSize = CGSizeMakeCopy([_alertPanel frame].size);
|
|
||||||
|
|
||||||
frameSize.height += deltaY;
|
|
||||||
[_alertPanel setFrameSize:frameSize];
|
|
||||||
|
|
||||||
var count = [_buttons count];
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
{
|
|
||||||
var button = _buttons[count];
|
|
||||||
[button setTheme:[self theme]];
|
|
||||||
[button sizeToFit];
|
|
||||||
|
|
||||||
var buttonBounds = [button bounds],
|
|
||||||
width = MAX(80.0, CGRectGetWidth(buttonBounds)),
|
|
||||||
height = CGRectGetHeight(buttonBounds);
|
|
||||||
|
|
||||||
offsetX -= width;
|
|
||||||
[button setFrame:CGRectMake(offsetX, buttonY, width, height)];
|
|
||||||
offsetX -= 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -403,68 +283,34 @@ CPCriticalAlertStyle = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)runModal
|
- (void)runModal
|
||||||
{
|
{
|
||||||
[self layoutPanel];
|
var theTitle;
|
||||||
|
|
||||||
|
switch (_alertStyle)
|
||||||
|
{
|
||||||
|
case CPWarningAlertStyle: [_alertImageView setImage:CPAlertWarningImage];
|
||||||
|
theTitle = @"Warning";
|
||||||
|
break;
|
||||||
|
case CPInformationalAlertStyle: [_alertImageView setImage:CPAlertInformationImage];
|
||||||
|
theTitle = @"Information";
|
||||||
|
break;
|
||||||
|
case CPCriticalAlertStyle: [_alertImageView setImage:CPAlertErrorImage];
|
||||||
|
theTitle = @"Error";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[_alertPanel setTitle:_windowTitle ? _windowTitle : theTitle];
|
||||||
|
|
||||||
[CPApp runModalForWindow:_alertPanel];
|
[CPApp runModalForWindow:_alertPanel];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Runs the receiver modally as an alert sheet attached to a specified window.
|
|
||||||
|
|
||||||
@param window The parent window for the sheet.
|
|
||||||
@param modalDelegate The delegate for the modal-dialog session.
|
|
||||||
@param alertDidEndSelector Message the alert sends to modalDelegate after the sheet is dismissed.
|
|
||||||
@param contextInfo Contextual data passed to modalDelegate in didEndSelector message.
|
|
||||||
*/
|
|
||||||
- (void)beginSheetModalForWindow:(CPWindow)window modalDelegate:(id)modalDelegate didEndSelector:(SEL)alertDidEndSelector contextInfo:(void)contextInfo
|
|
||||||
{
|
|
||||||
if (!(_windowStyle & CPDocModalWindowMask))
|
|
||||||
[self setWindowStyle:CPDocModalWindowMask];
|
|
||||||
[self layoutPanel];
|
|
||||||
|
|
||||||
_didEndSelector = alertDidEndSelector;
|
|
||||||
_modalDelegate = modalDelegate;
|
|
||||||
|
|
||||||
[CPApp beginSheet:_alertPanel modalForWindow:window modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Runs the receiver modally as an alert sheet attached to a specified window.
|
|
||||||
|
|
||||||
@param window The parent window for the sheet.
|
|
||||||
*/
|
|
||||||
- (void)beginSheetModalForWindow:(CPWindow)window
|
|
||||||
{
|
|
||||||
if (!(_windowStyle & CPDocModalWindowMask))
|
|
||||||
[self setWindowStyle:CPDocModalWindowMask];
|
|
||||||
[self layoutPanel];
|
|
||||||
|
|
||||||
[CPApp beginSheet:_alertPanel modalForWindow:window modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_alertDidEnd:(CPWindow)aSheet returnCode:(CPInteger)returnCode contextInfo:(id)contextInfo
|
|
||||||
{
|
|
||||||
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
|
|
||||||
[_delegate alertDidEnd:self returnCode:returnCode];
|
|
||||||
|
|
||||||
if (_didEndSelector)
|
|
||||||
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
|
|
||||||
|
|
||||||
_didEndSelector = nil;
|
|
||||||
_modalDelegate = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @ignore */
|
/* @ignore */
|
||||||
- (void)_dismissAlert:(CPButton)button
|
- (void)_notifyDelegate:(id)button
|
||||||
{
|
{
|
||||||
if ([_alertPanel isSheet])
|
[CPApp abortModal];
|
||||||
[CPApp endSheet:_alertPanel returnCode:[button tag]];
|
[_alertPanel close];
|
||||||
else
|
|
||||||
{
|
|
||||||
[CPApp abortModal];
|
|
||||||
[_alertPanel close];
|
|
||||||
|
|
||||||
[self _alertDidEnd:nil returnCode:[button tag] contextInfo:nil];
|
if (_delegate && [_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
|
||||||
}
|
[_delegate alertDidEnd:self returnCode:[button tag]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+71
-96
@@ -31,6 +31,7 @@
|
|||||||
@import "CPCibLoading.j"
|
@import "CPCibLoading.j"
|
||||||
@import "CPPlatform.j"
|
@import "CPPlatform.j"
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
var CPMainCibFile = @"CPMainCibFile",
|
var CPMainCibFile = @"CPMainCibFile",
|
||||||
CPMainCibFileHumanFriendly = @"Main cib file base name";
|
CPMainCibFileHumanFriendly = @"Main cib file base name";
|
||||||
@@ -107,8 +108,6 @@ CPRunContinuesResponse = -1002;
|
|||||||
CPImage _applicationIconImage;
|
CPImage _applicationIconImage;
|
||||||
|
|
||||||
CPPanel _aboutPanel;
|
CPPanel _aboutPanel;
|
||||||
|
|
||||||
CPThemeBlend _themeBlend @accessors(property=themeBlend);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -133,8 +132,6 @@ CPRunContinuesResponse = -1002;
|
|||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
CPApp = self;
|
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_eventListeners = [];
|
_eventListeners = [];
|
||||||
@@ -142,6 +139,63 @@ CPRunContinuesResponse = -1002;
|
|||||||
_windows = [];
|
_windows = [];
|
||||||
|
|
||||||
[_windows addObject:nil];
|
[_windows addObject:nil];
|
||||||
|
|
||||||
|
// FIXME: This should be read from the cib.
|
||||||
|
_mainMenu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
|
||||||
|
|
||||||
|
// FIXME: We should implement autoenabling.
|
||||||
|
[_mainMenu setAutoenablesItems:NO];
|
||||||
|
|
||||||
|
var bundle = [CPBundle bundleForClass:[CPApplication class]],
|
||||||
|
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
|
||||||
|
|
||||||
|
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
|
||||||
|
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
|
||||||
|
|
||||||
|
[_mainMenu addItem:newMenuItem];
|
||||||
|
|
||||||
|
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
|
||||||
|
|
||||||
|
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
|
||||||
|
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
|
||||||
|
|
||||||
|
[_mainMenu addItem:openMenuItem];
|
||||||
|
|
||||||
|
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
|
||||||
|
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
|
||||||
|
|
||||||
|
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
|
||||||
|
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
|
||||||
|
|
||||||
|
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
|
||||||
|
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
|
||||||
|
|
||||||
|
[saveMenuItem setSubmenu:saveMenu];
|
||||||
|
|
||||||
|
[_mainMenu 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];
|
||||||
|
|
||||||
|
[_mainMenu addItem:editMenuItem];
|
||||||
|
|
||||||
|
[_mainMenu addItem:[CPMenuItem separatorItem]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -326,9 +380,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
applicationVersion = [options objectForKey:@"ApplicationVersion"] || [mainInfo objectForKey:@"CPBundleShortVersionString"],
|
applicationVersion = [options objectForKey:@"ApplicationVersion"] || [mainInfo objectForKey:@"CPBundleShortVersionString"],
|
||||||
copyright = [options objectForKey:@"Copyright"] || [mainInfo objectForKey:@"CPHumanReadableCopyright"];
|
copyright = [options objectForKey:@"Copyright"] || [mainInfo objectForKey:@"CPHumanReadableCopyright"];
|
||||||
|
|
||||||
var aboutPanelPath = [[CPBundle bundleForClass:[CPWindowController class]] pathForResource:@"AboutPanel.cib"],
|
var aboutPanelController = [[CPWindowController alloc] initWithWindowCibName:@"AboutPanel"],
|
||||||
aboutPanelController = [CPWindowController alloc],
|
|
||||||
aboutPanelController = [aboutPanelController initWithWindowCibPath:aboutPanelPath owner:aboutPanelController],
|
|
||||||
aboutPanel = [aboutPanelController window],
|
aboutPanel = [aboutPanelController window],
|
||||||
contentView = [aboutPanel contentView],
|
contentView = [aboutPanel contentView],
|
||||||
imageView = [contentView viewWithTag:1],
|
imageView = [contentView viewWithTag:1],
|
||||||
@@ -506,8 +558,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
var theWindow = aModalSession._window;
|
var theWindow = aModalSession._window;
|
||||||
|
|
||||||
[theWindow center];
|
[theWindow center];
|
||||||
[theWindow makeKeyWindow];
|
[theWindow makeKeyAndOrderFront:self];
|
||||||
[theWindow orderFront:self];
|
|
||||||
|
|
||||||
// [theWindow._bridge _obscureWindowsBelowModalWindow];
|
// [theWindow._bridge _obscureWindowsBelowModalWindow];
|
||||||
|
|
||||||
@@ -619,11 +670,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
*/
|
*/
|
||||||
- (CPArray)orderedWindows
|
- (CPArray)orderedWindows
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
|
||||||
return CPWindowObjectList();
|
return CPWindowObjectList();
|
||||||
#else
|
|
||||||
return [];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)hide:(id)aSender
|
- (void)hide:(id)aSender
|
||||||
@@ -683,7 +730,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
if ([super tryToPerform:anAction with:anObject])
|
if ([super tryToPerform:anAction with:anObject])
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:anAction])
|
if([_delegate respondsToSelector:anAction])
|
||||||
{
|
{
|
||||||
[_delegate performSelector:anAction withObject:anObject];
|
[_delegate performSelector:anAction withObject:anObject];
|
||||||
|
|
||||||
@@ -863,7 +910,6 @@ CPRunContinuesResponse = -1002;
|
|||||||
}
|
}
|
||||||
|
|
||||||
[aWindow orderFront:self];
|
[aWindow orderFront:self];
|
||||||
[aSheet setPlatformWindow:[aWindow platformWindow]];
|
|
||||||
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
|
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,8 +919,8 @@ CPRunContinuesResponse = -1002;
|
|||||||
|
|
||||||
while (--count >= 0)
|
while (--count >= 0)
|
||||||
{
|
{
|
||||||
var aWindow = [_windows objectAtIndex:count],
|
var aWindow = [_windows objectAtIndex:count];
|
||||||
context = aWindow._sheetContext;
|
var context = aWindow._sheetContext;
|
||||||
|
|
||||||
if (context != nil && context["sheet"] === sheet)
|
if (context != nil && context["sheet"] === sheet)
|
||||||
{
|
{
|
||||||
@@ -892,7 +938,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
|
|
||||||
- (CPArray)arguments
|
- (CPArray)arguments
|
||||||
{
|
{
|
||||||
if (_fullArgsString !== window.location.hash)
|
if(_fullArgsString !== window.location.hash)
|
||||||
[self _reloadArguments];
|
[self _reloadArguments];
|
||||||
|
|
||||||
return _args;
|
return _args;
|
||||||
@@ -900,7 +946,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
|
|
||||||
- (void)setArguments:(CPArray)args
|
- (void)setArguments:(CPArray)args
|
||||||
{
|
{
|
||||||
if (!args || args.length == 0)
|
if(!args || args.length == 0)
|
||||||
{
|
{
|
||||||
_args = [];
|
_args = [];
|
||||||
window.location.hash = @"#";
|
window.location.hash = @"#";
|
||||||
@@ -908,13 +954,13 @@ CPRunContinuesResponse = -1002;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([args class] != CPArray)
|
if([args class] != CPArray)
|
||||||
args = [CPArray arrayWithObject:args];
|
args = [CPArray arrayWithObject:args];
|
||||||
|
|
||||||
_args = args;
|
_args = args;
|
||||||
|
|
||||||
var toEncode = [_args copy];
|
var toEncode = [_args copy];
|
||||||
for (var i = 0, count = toEncode.length; i < count; i++)
|
for(var i=0, count = toEncode.length; i<count; i++)
|
||||||
toEncode[i] = encodeURIComponent(toEncode[i]);
|
toEncode[i] = encodeURIComponent(toEncode[i]);
|
||||||
|
|
||||||
var hash = [toEncode componentsJoinedByString:@"/"];
|
var hash = [toEncode componentsJoinedByString:@"/"];
|
||||||
@@ -1021,6 +1067,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
|
|
||||||
+ (CPString)defaultThemeName
|
+ (CPString)defaultThemeName
|
||||||
{
|
{
|
||||||
|
// FIXME: don't hardcode
|
||||||
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
|
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,8 +1083,7 @@ var _CPEventListenerMake = function(anEventMask, aCallback)
|
|||||||
return { _mask:anEventMask, _callback:aCallback };
|
return { _mask:anEventMask, _callback:aCallback };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make this a global for use in CPPlatformWindow+DOM.j.
|
var _CPRunModalLoop = function(anEvent)
|
||||||
_CPRunModalLoop = function(anEvent)
|
|
||||||
{
|
{
|
||||||
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
|
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
|
||||||
|
|
||||||
@@ -1115,15 +1161,8 @@ var _CPAppBootstrapperActions = nil;
|
|||||||
|
|
||||||
+ (BOOL)loadDefaultTheme
|
+ (BOOL)loadDefaultTheme
|
||||||
{
|
{
|
||||||
var defaultThemeName = [CPApplication defaultThemeName],
|
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:[CPApplication defaultThemeName] + ".blend"]];
|
||||||
themeURL = nil;
|
|
||||||
|
|
||||||
if (defaultThemeName === @"Aristo")
|
|
||||||
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:defaultThemeName + @".blend"];
|
|
||||||
else
|
|
||||||
themeURL = [[CPBundle mainBundle] pathForResource:defaultThemeName + @".blend"];
|
|
||||||
|
|
||||||
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:themeURL];
|
|
||||||
[blend loadWithDelegate:self];
|
[blend loadWithDelegate:self];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
@@ -1131,7 +1170,6 @@ var _CPAppBootstrapperActions = nil;
|
|||||||
|
|
||||||
+ (void)blendDidFinishLoading:(CPThemeBlend)aThemeBlend
|
+ (void)blendDidFinishLoading:(CPThemeBlend)aThemeBlend
|
||||||
{
|
{
|
||||||
[[CPApplication sharedApplication] setThemeBlend:aThemeBlend];
|
|
||||||
[CPTheme setDefaultTheme:[CPTheme themeNamed:[CPApplication defaultThemeName]]];
|
[CPTheme setDefaultTheme:[CPTheme themeNamed:[CPApplication defaultThemeName]]];
|
||||||
|
|
||||||
[self performActions];
|
[self performActions];
|
||||||
@@ -1150,73 +1188,10 @@ var _CPAppBootstrapperActions = nil;
|
|||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
[self loadCiblessBrowserMainMenu];
|
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)loadCiblessBrowserMainMenu
|
|
||||||
{
|
|
||||||
var mainMenu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
|
|
||||||
|
|
||||||
// FIXME: We should implement autoenabling.
|
|
||||||
[mainMenu setAutoenablesItems:NO];
|
|
||||||
|
|
||||||
var bundle = [CPBundle bundleForClass:[CPApplication class]],
|
|
||||||
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
|
|
||||||
|
|
||||||
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
|
|
||||||
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
|
|
||||||
|
|
||||||
[mainMenu addItem:newMenuItem];
|
|
||||||
|
|
||||||
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
|
|
||||||
|
|
||||||
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
|
|
||||||
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
|
|
||||||
|
|
||||||
[mainMenu addItem:openMenuItem];
|
|
||||||
|
|
||||||
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
|
|
||||||
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
|
|
||||||
|
|
||||||
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
|
|
||||||
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
|
|
||||||
|
|
||||||
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
|
|
||||||
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
|
|
||||||
|
|
||||||
[saveMenuItem setSubmenu:saveMenu];
|
|
||||||
|
|
||||||
[mainMenu 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];
|
|
||||||
|
|
||||||
[mainMenu addItem:editMenuItem];
|
|
||||||
|
|
||||||
[mainMenu addItem:[CPMenuItem separatorItem]];
|
|
||||||
|
|
||||||
[CPApp setMainMenu:mainMenu];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)cibDidFinishLoading:(CPCib)aCib
|
+ (void)cibDidFinishLoading:(CPCib)aCib
|
||||||
{
|
{
|
||||||
[self performActions];
|
[self performActions];
|
||||||
@@ -1229,7 +1204,7 @@ var _CPAppBootstrapperActions = nil;
|
|||||||
|
|
||||||
+ (void)reset
|
+ (void)reset
|
||||||
{
|
{
|
||||||
_CPAppBootstrapperActions = nil;
|
_CPAppBootstrapperActions = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,675 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CPArrayController.j
|
|
||||||
* AppKit
|
|
||||||
*
|
|
||||||
* Adapted from Cocotron, by Johannes Fortmann
|
|
||||||
*
|
|
||||||
* Created by Ross Boucher.
|
|
||||||
* Copyright 2009, 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/CPIndexSet.j>
|
|
||||||
|
|
||||||
@import "CPObjectController.j"
|
|
||||||
@import "CPKeyValueBinding.j"
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CPArrayController : CPObjectController
|
|
||||||
{
|
|
||||||
BOOL _avoidsEmptySelection;
|
|
||||||
BOOL _clearsFilterPredicateOnInsertion;
|
|
||||||
BOOL _filterRestrictsInsertion;
|
|
||||||
BOOL _preservesSelection;
|
|
||||||
BOOL _selectsInsertedObjects;
|
|
||||||
BOOL _alwaysUsesMultipleValuesMarker;
|
|
||||||
|
|
||||||
id _selectionIndexes;
|
|
||||||
id _sortDescriptors;
|
|
||||||
id _filterPredicate;
|
|
||||||
id _arrangedObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initialize
|
|
||||||
{
|
|
||||||
if (self !== [CPArrayController class])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self exposeBinding:@"contentArray"];
|
|
||||||
[self exposeBinding:@"contentSet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingContentArray
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"content"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingArrangedObjects
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"content", "filterPredicate", "sortDescriptors"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingSelection
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"selectionIndexes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingSelectionIndex
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"selectionIndexes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingSelectionIndexes
|
|
||||||
{
|
|
||||||
// When the arranged objects change, selection preservation may cause the indexes
|
|
||||||
// to change.
|
|
||||||
return [CPSet setWithObjects:"arrangedObjects"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingSelectedObjects
|
|
||||||
{
|
|
||||||
// Don't need to depend on arrangedObjects here because selectionIndexes already does.
|
|
||||||
return [CPSet setWithObjects:"selectionIndexes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingCanRemove
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"selectionIndexes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingCanSelectNext
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"selectionIndexes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingCanSelectPrevious
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"selectionIndexes"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)init
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_selectionIndexes = [CPIndexSet indexSet];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)prepareContent
|
|
||||||
{
|
|
||||||
[self _setContentArray:[[self newObject]]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)preservesSelection
|
|
||||||
{
|
|
||||||
return _preservesSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setPreservesSelection:(BOOL)value
|
|
||||||
{
|
|
||||||
_preservesSelection = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)selectsInsertedObjects
|
|
||||||
{
|
|
||||||
return _selectsInsertedObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setSelectsInsertedObjects:(BOOL)value
|
|
||||||
{
|
|
||||||
_selectsInsertedObjects = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)avoidsEmptySelection
|
|
||||||
{
|
|
||||||
return _avoidsEmptySelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setAvoidsEmptySelection:(BOOL)value
|
|
||||||
{
|
|
||||||
_avoidsEmptySelection = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setContent:(id)value
|
|
||||||
{
|
|
||||||
if (value === nil)
|
|
||||||
value = [];
|
|
||||||
|
|
||||||
if (![value isKindOfClass:[CPArray class]])
|
|
||||||
value = [value];
|
|
||||||
|
|
||||||
var oldSelectedObjects = nil,
|
|
||||||
oldSelectionIndexes = nil;
|
|
||||||
|
|
||||||
if ([self preservesSelection])
|
|
||||||
oldSelectedObjects = [self selectedObjects];
|
|
||||||
else
|
|
||||||
oldSelectionIndexes = [self selectionIndexes];
|
|
||||||
|
|
||||||
/*
|
|
||||||
When the contents are changed, the selected indexes may no longer refer to the
|
|
||||||
same items. This would cause problems when setSelectedObjects is called below.
|
|
||||||
Any KVO observation would try to retrieve the 'before' value which could be
|
|
||||||
wrong or even throw an exception for no longer existing indexes.
|
|
||||||
|
|
||||||
To avoid that, use the internal __setSelectedObjects which fires no notifications.
|
|
||||||
The selectionIndexes notifications will fire later since they depend on the
|
|
||||||
content key. This pattern is also applied for many other methods throughout this
|
|
||||||
class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self willChangeValueForKey:@"filterPredicate"];
|
|
||||||
|
|
||||||
// Don't use [super setContent:] as that would fire the contentObject change.
|
|
||||||
// We need to be in control of when notifications fire.
|
|
||||||
_contentObject = value;
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self __setFilterPredicate:nil]; // Causes a _rearrangeObjects.
|
|
||||||
else
|
|
||||||
[self _rearrangeObjects];
|
|
||||||
|
|
||||||
if ([self preservesSelection])
|
|
||||||
[self __setSelectedObjects:oldSelectedObjects];
|
|
||||||
else
|
|
||||||
[self __setSelectionIndexes:oldSelectionIndexes];
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self didChangeValueForKey:@"filterPredicate"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_setContentArray:(id)anArray
|
|
||||||
{
|
|
||||||
[self setContent:anArray];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_setContentSet:(id)aSet
|
|
||||||
{
|
|
||||||
[self setContent:aSet];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)contentArray
|
|
||||||
{
|
|
||||||
return [self content];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)contentSet
|
|
||||||
{
|
|
||||||
return [self content];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPArray)arrangeObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
var filterPredicate = [self filterPredicate],
|
|
||||||
sortDescriptors = [self sortDescriptors];
|
|
||||||
|
|
||||||
if (filterPredicate && sortDescriptors)
|
|
||||||
{
|
|
||||||
var sortedObjects = [objects filteredArrayUsingPredicate:filterPredicate];
|
|
||||||
[sortedObjects sortUsingDescriptors:sortDescriptors];
|
|
||||||
return sortedObjects;
|
|
||||||
}
|
|
||||||
else if (filterPredicate)
|
|
||||||
return [objects filteredArrayUsingPredicate:filterPredicate];
|
|
||||||
else if (sortDescriptors)
|
|
||||||
return [objects sortedArrayUsingDescriptors:sortDescriptors];
|
|
||||||
|
|
||||||
return [objects copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)rearrangeObjects
|
|
||||||
{
|
|
||||||
[self willChangeValueForKey:@"arrangedObjects"];
|
|
||||||
[self _rearrangeObjects];
|
|
||||||
[self didChangeValueForKey:@"arrangedObjects"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Like rearrangeObjects but don't fire any change notifications.
|
|
||||||
@ignore
|
|
||||||
*/
|
|
||||||
- (void)_rearrangeObjects
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Rearranging reapplies the selection criteria and may cause objects to disappear,
|
|
||||||
so take care of the selection.
|
|
||||||
*/
|
|
||||||
var oldSelectedObjects = nil,
|
|
||||||
oldSelectionIndexes = nil;
|
|
||||||
|
|
||||||
if ([self preservesSelection])
|
|
||||||
oldSelectedObjects = [self selectedObjects];
|
|
||||||
else
|
|
||||||
oldSelectionIndexes = [self selectionIndexes];
|
|
||||||
|
|
||||||
[self __setArrangedObjects:[self arrangeObjects:[self contentArray]]];
|
|
||||||
|
|
||||||
if ([self preservesSelection])
|
|
||||||
[self __setSelectedObjects:oldSelectedObjects];
|
|
||||||
else
|
|
||||||
[self __setSelectionIndexes:oldSelectionIndexes];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)__setArrangedObjects:(id)value
|
|
||||||
{
|
|
||||||
if (_arrangedObjects === value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_arrangedObjects = [[_CPObservableArray alloc] initWithArray:value];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)arrangedObjects
|
|
||||||
{
|
|
||||||
return _arrangedObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPArray)sortDescriptors
|
|
||||||
{
|
|
||||||
return _sortDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setSortDescriptors:(CPArray)value
|
|
||||||
{
|
|
||||||
if (_sortDescriptors === value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_sortDescriptors = [value copy];
|
|
||||||
// Use the non-notification version since arrangedObjects already depends
|
|
||||||
// on sortDescriptors.
|
|
||||||
[self _rearrangeObjects];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPPredicate)filterPredicate
|
|
||||||
{
|
|
||||||
return _filterPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setFilterPredicate:(CPPredicate)value
|
|
||||||
{
|
|
||||||
[self __setFilterPredicate:value];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Like setFilterPredicate but don't fire any change notifications.
|
|
||||||
@ignore
|
|
||||||
*/
|
|
||||||
- (void)__setFilterPredicate:(CPPredicate)value
|
|
||||||
{
|
|
||||||
if (_filterPredicate === value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_filterPredicate = value;
|
|
||||||
// Use the non-notification version since arrangedObjects already depends
|
|
||||||
// on filterPredicate.
|
|
||||||
[self _rearrangeObjects];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)alwaysUsesMultipleValuesMarker
|
|
||||||
{
|
|
||||||
return _alwaysUsesMultipleValuesMarker;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Selection
|
|
||||||
|
|
||||||
- (unsigned)selectionIndex
|
|
||||||
{
|
|
||||||
return [_selectionIndexes firstIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setSelectionIndex:(unsigned)index
|
|
||||||
{
|
|
||||||
return [self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPIndexSet)selectionIndexes
|
|
||||||
{
|
|
||||||
return _selectionIndexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
|
|
||||||
{
|
|
||||||
[self _selectionWillChange]
|
|
||||||
[self __setSelectionIndexes:indexes];
|
|
||||||
[self _selectionDidChange];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Like setSelectionIndex but don't fire any change notifications.
|
|
||||||
@ignore
|
|
||||||
*/
|
|
||||||
- (BOOL)__setSelectionIndex:(int)theIndex
|
|
||||||
{
|
|
||||||
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Like setSelectionIndexes but don't fire any change notifications.
|
|
||||||
@ignore
|
|
||||||
*/
|
|
||||||
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
|
|
||||||
{
|
|
||||||
if (!indexes)
|
|
||||||
indexes = [CPIndexSet indexSet];
|
|
||||||
|
|
||||||
if (![indexes count])
|
|
||||||
{
|
|
||||||
if (_avoidsEmptySelection && [[self arrangedObjects] count])
|
|
||||||
indexes = [CPIndexSet indexSetWithIndex:0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var objectsCount = [[self arrangedObjects] count];
|
|
||||||
// Remove out of bounds indexes.
|
|
||||||
[indexes removeIndexesInRange:CPMakeRange(objectsCount, [indexes lastIndex] + 1)];
|
|
||||||
// When avoiding empty selection and the deleted selection was at the bottom, select the last item.
|
|
||||||
if (![indexes count] && _avoidsEmptySelection && objectsCount)
|
|
||||||
indexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([_selectionIndexes isEqualToIndexSet:indexes])
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
_selectionIndexes = [indexes copy];
|
|
||||||
|
|
||||||
// Push back the new selection to the model for selectionIndexes if we have one.
|
|
||||||
// There won't be an infinite loop because of the equality check above.
|
|
||||||
[[CPKeyValueBinding getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPArray)selectedObjects
|
|
||||||
{
|
|
||||||
var objects = [[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]];
|
|
||||||
|
|
||||||
return [_CPObservableArray arrayWithArray:(objects || [])];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setSelectedObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
[self willChangeValueForKey:@"selectionIndexes"];
|
|
||||||
[self _selectionWillChange];
|
|
||||||
|
|
||||||
[self __setSelectedObjects:objects];
|
|
||||||
|
|
||||||
[self didChangeValueForKey:@"selectionIndexes"];
|
|
||||||
[self _selectionDidChange];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Like setSelectedObjects but don't fire any change notifications.
|
|
||||||
@ignore
|
|
||||||
*/
|
|
||||||
- (BOOL)__setSelectedObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
var set = [CPIndexSet indexSet],
|
|
||||||
count = [objects count],
|
|
||||||
arrangedObjects = [self arrangedObjects];
|
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
var index = [arrangedObjects indexOfObject:[objects objectAtIndex:i]];
|
|
||||||
|
|
||||||
if (index !== CPNotFound)
|
|
||||||
[set addIndex:index];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self __setSelectionIndexes:set];
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Moving selection
|
|
||||||
|
|
||||||
- (BOOL)canSelectPrevious
|
|
||||||
{
|
|
||||||
return [[self selectionIndexes] firstIndex] > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)selectPrevious:(id)sender
|
|
||||||
{
|
|
||||||
var index = [[self selectionIndexes] firstIndex] - 1;
|
|
||||||
|
|
||||||
if (index >= 0)
|
|
||||||
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)canSelectNext
|
|
||||||
{
|
|
||||||
return [[self selectionIndexes] firstIndex] < [[self arrangedObjects] count] - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)selectNext:(id)sender
|
|
||||||
{
|
|
||||||
var index = [[self selectionIndexes] firstIndex] + 1;
|
|
||||||
|
|
||||||
if (index < [[self arrangedObjects] count])
|
|
||||||
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add/Remove
|
|
||||||
|
|
||||||
- (void)addObject:(id)object
|
|
||||||
{
|
|
||||||
if (![self canAdd])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self willChangeValueForKey:@"filterPredicate"];
|
|
||||||
|
|
||||||
[self willChangeValueForKey:@"content"];
|
|
||||||
[_contentObject addObject:object];
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self __setFilterPredicate:nil];
|
|
||||||
|
|
||||||
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
|
|
||||||
{
|
|
||||||
var pos = [_arrangedObjects insertObject:object inArraySortedByDescriptors:_sortDescriptors];
|
|
||||||
|
|
||||||
// selectionIndexes change notification will be fired as a result of the
|
|
||||||
// content change. Don't fire manually.
|
|
||||||
if (_selectsInsertedObjects)
|
|
||||||
[self __setSelectionIndex:pos];
|
|
||||||
else
|
|
||||||
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
[self _rearrangeObjects];
|
|
||||||
|
|
||||||
[self didChangeValueForKey:@"content"];
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self didChangeValueForKey:@"filterPredicate"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)insertObject:(id)anObject atArrangedObjectIndex:(int)anIndex
|
|
||||||
{
|
|
||||||
if (![self canAdd])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self willChangeValueForKey:@"filterPredicate"];
|
|
||||||
|
|
||||||
[self willChangeValueForKey:@"content"];
|
|
||||||
[_contentObject insertObject:anObject atIndex:anIndex];
|
|
||||||
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self __setFilterPredicate:nil];
|
|
||||||
|
|
||||||
[[self arrangedObjects] insertObject:anObject atIndex:anIndex];
|
|
||||||
|
|
||||||
// selectionIndexes change notification will be fired as a result of the
|
|
||||||
// content change. Don't fire manually.
|
|
||||||
if ([self selectsInsertedObjects])
|
|
||||||
[self __setSelectionIndex:anIndex];
|
|
||||||
else
|
|
||||||
[[self selectionIndexes] shiftIndexesStartingAtIndex:anIndex by:1];
|
|
||||||
|
|
||||||
if ([self avoidsEmptySelection] && [[self selectionIndexes] count] <= 0 && [_contentObject count] > 0)
|
|
||||||
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]];
|
|
||||||
|
|
||||||
[self didChangeValueForKey:@"content"];
|
|
||||||
if (_clearsFilterPredicateOnInsertion)
|
|
||||||
[self didChangeValueForKey:@"filterPredicate"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObject:(id)object
|
|
||||||
{
|
|
||||||
if (![self canRemove])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self willChangeValueForKey:@"content"];
|
|
||||||
[_contentObject removeObject:object];
|
|
||||||
|
|
||||||
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
|
|
||||||
{
|
|
||||||
// selectionIndexes change notification will be fired as a result of the
|
|
||||||
// content change. Don't fire manually.
|
|
||||||
var pos = [_arrangedObjects indexOfObject:object];
|
|
||||||
|
|
||||||
[_arrangedObjects removeObjectAtIndex:pos];
|
|
||||||
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self didChangeValueForKey:@"content"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)add:(id)sender
|
|
||||||
{
|
|
||||||
if (![self canAdd])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self insert:sender];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)insert:(id)sender
|
|
||||||
{
|
|
||||||
if (![self canInsert])
|
|
||||||
return;
|
|
||||||
|
|
||||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
|
|
||||||
|
|
||||||
[self addObject:newObject];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)remove:(id)sender
|
|
||||||
{
|
|
||||||
[self removeObjects:[[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObjectsAtArrangedObjectIndexes:(CPIndexSet)indexes
|
|
||||||
{
|
|
||||||
[self _removeObjects:[[self arrangedObjects] objectsAtIndexes:indexes]];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (void)addObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
if (![self canAdd])
|
|
||||||
return;
|
|
||||||
|
|
||||||
var contentArray = [self contentArray],
|
|
||||||
count = [objects count];
|
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
[contentArray addObject:[objects objectAtIndex:i]];
|
|
||||||
|
|
||||||
[self setContent:contentArray];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
if (![self canRemove])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self _removeObjects:objects];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_removeObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
[self willChangeValueForKey:@"content"];
|
|
||||||
[_contentObject removeObjectsInArray:objects];
|
|
||||||
|
|
||||||
var arrangedObjects = [self arrangedObjects],
|
|
||||||
position = [arrangedObjects indexOfObject:[objects objectAtIndex:0]];
|
|
||||||
|
|
||||||
[arrangedObjects removeObjectsInArray:objects];
|
|
||||||
|
|
||||||
var objectsCount = [arrangedObjects count],
|
|
||||||
selectionIndexes = [CPIndexSet indexSet];
|
|
||||||
|
|
||||||
if ([self preservesSelection] || [self avoidsEmptySelection])
|
|
||||||
{
|
|
||||||
selectionIndexes = [CPIndexSet indexSetWithIndex:position];
|
|
||||||
|
|
||||||
// Remove the selection if there are no objects
|
|
||||||
if (objectsCount <= 0)
|
|
||||||
selectionIndexes = [CPIndexSet indexSet];
|
|
||||||
|
|
||||||
// Shift selection to last object if position is out of bounds
|
|
||||||
else if (position >= objectsCount)
|
|
||||||
selectionIndexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
_selectionIndexes = selectionIndexes;
|
|
||||||
|
|
||||||
[self didChangeValueForKey:@"content"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)canInsert
|
|
||||||
{
|
|
||||||
return [self isEditable];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation CPArrayController (CPCoding)
|
|
||||||
|
|
||||||
- (id)initWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
self = [super initWithCoder:coder];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_avoidsEmptySelection = [coder decodeBoolForKey:@"CPArrayControllerAvoidsEmptySelection"];
|
|
||||||
_clearsFilterPredicateOnInsertion = [coder decodeBoolForKey:@"CPClearsFilterPredicateOnInsertion"];
|
|
||||||
_filterRestrictsInsertion = [coder decodeBoolForKey:@"CPArrayControllerFilterRestrictsInsertion"];
|
|
||||||
_preservesSelection = [coder decodeBoolForKey:@"CPArrayControllerPreservesSelection"];
|
|
||||||
_selectsInsertedObjects = [coder decodeBoolForKey:@"CPArrayControllerSelectsInsertedObjects"];
|
|
||||||
_alwaysUsesMultipleValuesMarker = [coder decodeBoolForKey:@"CPArrayControllerAlwaysUsesMultipleValuesMarker"];
|
|
||||||
|
|
||||||
if ([self automaticallyPreparesContent])
|
|
||||||
[self prepareContent];
|
|
||||||
else
|
|
||||||
[self _setContentArray:[]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)awakeFromCib
|
|
||||||
{
|
|
||||||
[self _selectionWillChange];
|
|
||||||
[self _selectionDidChange];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -23,10 +23,9 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@import <AppKit/CPGraphicsContext.j>
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
@import "CPGraphicsContext.j"
|
|
||||||
|
|
||||||
|
|
||||||
// Class defaults
|
// Class defaults
|
||||||
|
|
||||||
|
|||||||
+39
-163
@@ -22,13 +22,6 @@
|
|||||||
|
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
// CPBoxType
|
|
||||||
CPBoxPrimary = 0;
|
|
||||||
CPBoxSecondary = 1;
|
|
||||||
CPBoxSeperator = 2;
|
|
||||||
CPBoxOldStyle = 3;
|
|
||||||
CPBoxCustom = 4;
|
|
||||||
|
|
||||||
// CPBorderType
|
// CPBorderType
|
||||||
CPNoBorder = 0;
|
CPNoBorder = 0;
|
||||||
CPLineBorder = 1;
|
CPLineBorder = 1;
|
||||||
@@ -37,7 +30,6 @@ CPGrooveBorder = 3;
|
|||||||
|
|
||||||
@implementation CPBox : CPView
|
@implementation CPBox : CPView
|
||||||
{
|
{
|
||||||
CPBoxType _boxType;
|
|
||||||
CPBorderType _borderType;
|
CPBorderType _borderType;
|
||||||
|
|
||||||
CPColor _borderColor;
|
CPColor _borderColor;
|
||||||
@@ -70,7 +62,6 @@ CPGrooveBorder = 3;
|
|||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_borderType = CPBezelBorder;
|
|
||||||
_fillColor = [CPColor clearColor];
|
_fillColor = [CPColor clearColor];
|
||||||
_borderColor = [CPColor blackColor];
|
_borderColor = [CPColor blackColor];
|
||||||
|
|
||||||
@@ -78,9 +69,7 @@ CPGrooveBorder = 3;
|
|||||||
_contentMargin = CGSizeMake(0.0, 0.0);
|
_contentMargin = CGSizeMake(0.0, 0.0);
|
||||||
|
|
||||||
_contentView = [[CPView alloc] initWithFrame:[self bounds]];
|
_contentView = [[CPView alloc] initWithFrame:[self bounds]];
|
||||||
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
|
||||||
|
|
||||||
[self setAutoresizesSubviews:YES];
|
|
||||||
[self addSubview:_contentView];
|
[self addSubview:_contentView];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,26 +88,9 @@ CPGrooveBorder = 3;
|
|||||||
return _borderType;
|
return _borderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBorderType:(CPBorderType)aBorderType
|
- (void)setBorderType:(CPBorderType)value
|
||||||
{
|
{
|
||||||
if (_borderType === aBorderType)
|
_borderType = value;
|
||||||
return;
|
|
||||||
|
|
||||||
_borderType = aBorderType;
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPBoxType)boxType
|
|
||||||
{
|
|
||||||
return _boxType;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setBoxType:(CPBoxType)aBoxType
|
|
||||||
{
|
|
||||||
if (_boxType === aBoxType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_boxType = aBoxType;
|
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +161,6 @@ CPGrooveBorder = 3;
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
[aView setFrame:CGRectInset([self bounds], _contentMargin.width + _borderWidth, _contentMargin.height + _borderWidth)];
|
[aView setFrame:CGRectInset([self bounds], _contentMargin.width + _borderWidth, _contentMargin.height + _borderWidth)];
|
||||||
[aView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
|
||||||
[self replaceSubview:_contentView with:aView];
|
[self replaceSubview:_contentView with:aView];
|
||||||
|
|
||||||
_contentView = aView;
|
_contentView = aView;
|
||||||
@@ -202,7 +173,7 @@ CPGrooveBorder = 3;
|
|||||||
|
|
||||||
- (void)setContentViewMargins:(CPSize)size
|
- (void)setContentViewMargins:(CPSize)size
|
||||||
{
|
{
|
||||||
if (size.width < 0 || size.height < 0)
|
if(size.width < 0 || size.height < 0)
|
||||||
[CPException raise:CPGenericException reason:@"Margins must be positive"];
|
[CPException raise:CPGenericException reason:@"Margins must be positive"];
|
||||||
|
|
||||||
_contentMargin = CGSizeMakeCopy(size);
|
_contentMargin = CGSizeMakeCopy(size);
|
||||||
@@ -227,142 +198,47 @@ CPGrooveBorder = 3;
|
|||||||
|
|
||||||
- (void)drawRect:(CPRect)rect
|
- (void)drawRect:(CPRect)rect
|
||||||
{
|
{
|
||||||
if (_borderType === CPNoBorder)
|
var bounds = [self bounds],
|
||||||
return;
|
aContext = [[CPGraphicsContext currentContext] graphicsPort],
|
||||||
|
border2 = _borderWidth/2,
|
||||||
|
|
||||||
var bounds = [self bounds];
|
strokeRect = CGRectMake(bounds.origin.x + border2,
|
||||||
|
bounds.origin.y + border2,
|
||||||
|
bounds.size.width - _borderWidth,
|
||||||
|
bounds.size.height - _borderWidth),
|
||||||
|
|
||||||
switch (_boxType)
|
fillRect = CGRectMake(bounds.origin.x + border2,
|
||||||
|
bounds.origin.y + border2,
|
||||||
|
bounds.size.width - _borderWidth,
|
||||||
|
bounds.size.height - _borderWidth);
|
||||||
|
|
||||||
|
CGContextSetFillColor(aContext, [self fillColor]);
|
||||||
|
CGContextSetStrokeColor(aContext, [self borderColor]);
|
||||||
|
CGContextSetLineWidth(aContext, _borderWidth);
|
||||||
|
|
||||||
|
switch(_borderType)
|
||||||
{
|
{
|
||||||
case CPBoxSeperator:
|
case CPLineBorder: CGContextFillRoundedRectangleInRect(aContext, fillRect, _cornerRadius, YES, YES, YES, YES);
|
||||||
// NSBox does not include a horitontal flag for the seperator type. We have to determine
|
CGContextStrokeRoundedRectangleInRect(aContext, strokeRect, _cornerRadius, YES, YES, YES, YES);
|
||||||
// the type of seperator to draw by the width and height of the frame.
|
break;
|
||||||
if (CGRectGetWidth(bounds) === 5.0)
|
|
||||||
return [self _drawVerticalSeperatorInRect:bounds];
|
|
||||||
else if (CGRectGetHeight(bounds) === 5.0)
|
|
||||||
return [self _drawHorizontalSeperatorInRect:bounds];
|
|
||||||
|
|
||||||
break;
|
case CPBezelBorder: CGContextFillRoundedRectangleInRect(aContext, fillRect, _cornerRadius, YES, YES, YES, YES);
|
||||||
|
CGContextSetStrokeColor(aContext, [CPColor colorWithWhite:190.0/255.0 alpha:1.0]);
|
||||||
|
CGContextBeginPath(aContext);
|
||||||
|
CGContextMoveToPoint(aContext, strokeRect.origin.x, strokeRect.origin.y);
|
||||||
|
CGContextAddLineToPoint(aContext, CGRectGetMinX(strokeRect), CGRectGetMaxY(strokeRect)),
|
||||||
|
CGContextAddLineToPoint(aContext, CGRectGetMaxX(strokeRect), CGRectGetMaxY(strokeRect)),
|
||||||
|
CGContextAddLineToPoint(aContext, CGRectGetMaxX(strokeRect), CGRectGetMinY(strokeRect)),
|
||||||
|
CGContextStrokePath(aContext);
|
||||||
|
CGContextSetStrokeColor(aContext, [CPColor colorWithWhite:142.0/255.0 alpha:1.0]);
|
||||||
|
CGContextBeginPath(aContext);
|
||||||
|
CGContextMoveToPoint(aContext, bounds.origin.x, strokeRect.origin.y);
|
||||||
|
CGContextAddLineToPoint(aContext, CGRectGetMaxX(bounds), CGRectGetMinY(strokeRect));
|
||||||
|
CGContextStrokePath(aContext);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_borderType)
|
|
||||||
{
|
|
||||||
case CPBezelBorder:
|
|
||||||
[self _drawBezelBorderInRect:bounds];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
case CPLineBorder:
|
|
||||||
[self _drawLineBorderInRect:bounds];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_drawHorizontalSeperatorInRect:(CGRect)aRect
|
|
||||||
{
|
|
||||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
|
||||||
|
|
||||||
CGContextSetStrokeColor(context, [self borderColor]);
|
|
||||||
CGContextSetLineWidth(context, 1.0);
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect));
|
|
||||||
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMinY(aRect));
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_drawVerticalSeperatorInRect:(CGRect)aRect
|
|
||||||
{
|
|
||||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
|
||||||
|
|
||||||
CGContextSetStrokeColor(context, [self borderColor]);
|
|
||||||
CGContextSetLineWidth(context, 1.0);
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect));
|
|
||||||
CGContextAddLineToPoint(context, CGRectGetMinX(aRect), CGRectGetHeight(aRect));
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_drawBezelBorderInRect:(CGRect)aRect
|
|
||||||
{
|
|
||||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
|
||||||
sides = [CPMinYEdge, CPMaxXEdge, CPMaxYEdge, CPMinXEdge],
|
|
||||||
sideGray = 190.0 / 255.0,
|
|
||||||
grays = [142.0 / 255.0, sideGray, sideGray, sideGray],
|
|
||||||
borderWidth = _borderWidth;
|
|
||||||
|
|
||||||
while (borderWidth--)
|
|
||||||
aRect = CPDrawTiledRects(aRect, aRect, sides, grays);
|
|
||||||
|
|
||||||
CGContextSetFillColor(context, [self fillColor]);
|
|
||||||
CGContextFillRect(context, aRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_drawLineBorderInRect:(CGRect)aRect
|
|
||||||
{
|
|
||||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
|
||||||
|
|
||||||
aRect = CGRectInset(aRect, _borderWidth / 2.0, _borderWidth / 2.0);
|
|
||||||
|
|
||||||
CGContextSetFillColor(context, [self fillColor]);
|
|
||||||
CGContextSetStrokeColor(context, [self borderColor]);
|
|
||||||
|
|
||||||
CGContextSetLineWidth(context, _borderWidth);
|
|
||||||
CGContextFillRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
|
|
||||||
CGContextStrokeRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
var CPBoxTypeKey = @"CPBoxTypeKey",
|
|
||||||
CPBoxBorderTypeKey = @"CPBoxBorderTypeKey",
|
|
||||||
CPBoxBorderColorKey = @"CPBoxBorderColorKey",
|
|
||||||
CPBoxFillColorKey = @"CPBoxFillColorKey",
|
|
||||||
CPBoxCornerRadiusKey = @"CPBoxCornerRadiusKey",
|
|
||||||
CPBoxBorderWidthKey = @"CPBoxBorderWidthKey",
|
|
||||||
CPBoxContentMarginKey = @"CPBoxContentMarginKey";
|
|
||||||
|
|
||||||
@implementation CPBox (CPCoding)
|
|
||||||
|
|
||||||
- (id)initWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
self = [super initWithCoder:aCoder];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_boxType = [aCoder decodeIntForKey:CPBoxTypeKey];
|
|
||||||
_borderType = [aCoder decodeIntForKey:CPBoxBorderTypeKey];
|
|
||||||
|
|
||||||
_borderColor = [aCoder decodeObjectForKey:CPBoxBorderColorKey];
|
|
||||||
_fillColor = [aCoder decodeObjectForKey:CPBoxFillColorKey];
|
|
||||||
|
|
||||||
_cornerRadius = [aCoder decodeFloatForKey:CPBoxCornerRadiusKey];
|
|
||||||
_borderWidth = [aCoder decodeFloatForKey:CPBoxBorderWidthKey];
|
|
||||||
|
|
||||||
_contentMargin = [aCoder decodeSizeForKey:CPBoxContentMarginKey];
|
|
||||||
|
|
||||||
_contentView = [self subviews][0];
|
|
||||||
|
|
||||||
[self setAutoresizesSubviews:YES];
|
|
||||||
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
[super encodeWithCoder:aCoder];
|
|
||||||
|
|
||||||
[aCoder encodeInt:_boxType forKey:CPBoxTypeKey];
|
|
||||||
[aCoder encodeInt:_borderType forKey:CPBoxBorderTypeKey];
|
|
||||||
|
|
||||||
[aCoder encodeObject:_borderColor forKey:CPBoxBorderColorKey];
|
|
||||||
[aCoder encodeObject:_fillColor forKey:CPBoxFillColorKey];
|
|
||||||
|
|
||||||
[aCoder encodeFloat:_cornerRadius forKey:CPBoxCornerRadiusKey];
|
|
||||||
[aCoder encodeFloat:_borderWidth forKey:CPBoxBorderWidthKey];
|
|
||||||
|
|
||||||
[aCoder encodeSize:_contentMargin forKey:CPBoxContentMarginKey];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+32
-91
@@ -20,12 +20,9 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPIndexSet.j>
|
|
||||||
|
|
||||||
@import "CPControl.j"
|
@import "CPControl.j"
|
||||||
@import "CPImage.j"
|
@import "CPImage.j"
|
||||||
@import "CPTableView.j"
|
@import "CPTableView.j"
|
||||||
@import "CPTextField.j"
|
|
||||||
@import "CPScrollView.j"
|
@import "CPScrollView.j"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -67,14 +64,14 @@
|
|||||||
|
|
||||||
+ (CPImage)branchImage
|
+ (CPImage)branchImage
|
||||||
{
|
{
|
||||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
|
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]]
|
||||||
pathForResource:"browser-leaf.png"]
|
pathForResource:"browser-leaf.png"]
|
||||||
size:CGSizeMake(9,9)];
|
size:CGSizeMake(9,9)];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPImage)highlightedBranchImage
|
+ (CPImage)highlightedBranchImage
|
||||||
{
|
{
|
||||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
|
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]]
|
||||||
pathForResource:"browser-leaf-highlighted.png"]
|
pathForResource:"browser-leaf-highlighted.png"]
|
||||||
size:CGSizeMake(9,9)];
|
size:CGSizeMake(9,9)];
|
||||||
}
|
}
|
||||||
@@ -99,14 +96,14 @@
|
|||||||
|
|
||||||
_prototypeView = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
_prototypeView = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||||
[_prototypeView setVerticalAlignment:CPCenterVerticalTextAlignment];
|
[_prototypeView setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||||
[_prototypeView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateSelectedDataView];
|
[_prototypeView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateSelected];
|
||||||
[_prototypeView setLineBreakMode:CPLineBreakByTruncatingTail];
|
[_prototypeView setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||||
|
|
||||||
_horizontalScrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
|
_horizontalScrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
|
||||||
|
|
||||||
[_horizontalScrollView setHasVerticalScroller:NO];
|
[_horizontalScrollView setHasVerticalScroller:NO];
|
||||||
[_horizontalScrollView setAutohidesScrollers:YES];
|
[_horizontalScrollView setAutohidesScrollers:YES];
|
||||||
[_horizontalScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
[_horizontalScrollView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
||||||
|
|
||||||
_contentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 0, CGRectGetHeight([self bounds]))];
|
_contentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 0, CGRectGetHeight([self bounds]))];
|
||||||
[_contentView setAutoresizingMask:CPViewHeightSizable];
|
[_contentView setAutoresizingMask:CPViewHeightSizable];
|
||||||
@@ -170,8 +167,10 @@
|
|||||||
if (columnIndex >= _tableViews.length)
|
if (columnIndex >= _tableViews.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var oldValue = _tableViews.length - 1,
|
var oldValue = _tableViews.length - 1;
|
||||||
indexPlusOne = columnIndex + 1; // unloads all later columns.
|
|
||||||
|
// unloads all later columns.
|
||||||
|
var indexPlusOne = columnIndex + 1;
|
||||||
|
|
||||||
[[_tableViews.slice(indexPlusOne) valueForKey:"enclosingScrollView"]
|
[[_tableViews.slice(indexPlusOne) valueForKey:"enclosingScrollView"]
|
||||||
makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||||
@@ -200,7 +199,7 @@
|
|||||||
[CPException raise:CPInvalidArgumentException
|
[CPException raise:CPInvalidArgumentException
|
||||||
reason:"Can't add column, column "+lastIndex+" has invalid selection."];
|
reason:"Can't add column, column "+lastIndex+" has invalid selection."];
|
||||||
|
|
||||||
var index = lastIndex + 1,
|
var index = lastIndex+1,
|
||||||
item = index === 0 ? _rootItem : [_tableDelegates[lastIndex] childAtIndex:[selectionIndexes firstIndex]];
|
item = index === 0 ? _rootItem : [_tableDelegates[lastIndex] childAtIndex:[selectionIndexes firstIndex]];
|
||||||
|
|
||||||
if (index > 0 && item && [self isLeafItem:item])
|
if (index > 0 && item && [self isLeafItem:item])
|
||||||
@@ -214,6 +213,8 @@
|
|||||||
[table setAllowsEmptySelection:_allowsEmptySelection];
|
[table setAllowsEmptySelection:_allowsEmptySelection];
|
||||||
[table registerForDraggedTypes:[self registeredDraggedTypes]];
|
[table registerForDraggedTypes:[self registeredDraggedTypes]];
|
||||||
|
|
||||||
|
[self setNextResponder:table];
|
||||||
|
|
||||||
[self _addTableColumnsToTableView:table forColumnIndex:index];
|
[self _addTableColumnsToTableView:table forColumnIndex:index];
|
||||||
|
|
||||||
var delegate = [[_CPBrowserTableDelegate alloc] init];
|
var delegate = [[_CPBrowserTableDelegate alloc] init];
|
||||||
@@ -313,39 +314,6 @@
|
|||||||
[_contentView setFrameSize:CGSizeMake(xOrigin, height)];
|
[_contentView setFrameSize:CGSizeMake(xOrigin, height)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned)rowAtPoint:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
var column = [self columnAtPoint:aPoint];
|
|
||||||
if (column === -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
var tableView = _tableViews[column];
|
|
||||||
return [tableView rowAtPoint:[tableView convertPoint:aPoint fromView:self]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (unsigned)columnAtPoint:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
var adjustedPoint = [_contentView convertPoint:aPoint fromView:self];
|
|
||||||
|
|
||||||
for (var i = 0, count = _tableViews.length; i < count; i++)
|
|
||||||
{
|
|
||||||
var frame = [[_tableViews[i] enclosingScrollView] frame];
|
|
||||||
if (CGRectContainsPoint(frame, adjustedPoint))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGRect)rectOfRow:(unsigned)aRow inColumn:(unsigned)aColumn
|
|
||||||
{
|
|
||||||
var tableView = _tableViews[aColumn],
|
|
||||||
rect = [tableView rectOfRow:aRow];
|
|
||||||
|
|
||||||
rect.origin = [self convertPoint:rect.origin fromView:tableView];
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ITEMS
|
// ITEMS
|
||||||
|
|
||||||
- (id)itemAtRow:(int)row inColumn:(int)column
|
- (id)itemAtRow:(int)row inColumn:(int)column
|
||||||
@@ -389,10 +357,6 @@
|
|||||||
|
|
||||||
// CLICK EVENTS
|
// CLICK EVENTS
|
||||||
|
|
||||||
- (void)trackMouse:(CPEvent)anEvent
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_column:(unsigned)columnIndex clickedRow:(unsigned)rowIndex
|
- (void)_column:(unsigned)columnIndex clickedRow:(unsigned)rowIndex
|
||||||
{
|
{
|
||||||
[self setLastColumn:columnIndex];
|
[self setLastColumn:columnIndex];
|
||||||
@@ -418,15 +382,6 @@
|
|||||||
[self sendAction:_doubleAction to:_target];
|
[self sendAction:_doubleAction to:_target];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyDown:(CPEvent)anEvent
|
|
||||||
{
|
|
||||||
var column = [self selectedColumn];
|
|
||||||
if (column === -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
[_tableViews[column] keyDown:anEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
// SIZING
|
// SIZING
|
||||||
|
|
||||||
- (float)columnContentWidthForColumnWidth:(float)aWidth
|
- (float)columnContentWidthForColumnWidth:(float)aWidth
|
||||||
@@ -498,7 +453,7 @@
|
|||||||
[_contentView scrollRectToVisible:[[[self tableViewInColumn:columnIndex] enclosingScrollView] frame]];
|
[_contentView scrollRectToVisible:[[[self tableViewInColumn:columnIndex] enclosingScrollView] frame]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollRowToVisible:(unsigned)rowIndex inColumn:(unsigned)columnIndex
|
– (void)scrollRowToVisible:(unsigned)rowIndex inColumn:(unsigned)columnIndex
|
||||||
{
|
{
|
||||||
[self scrollColumnToVisible:columnIndex];
|
[self scrollColumnToVisible:columnIndex];
|
||||||
[[self tableViewInColumn:columnIndex] scrollRowToVisible:rowIndex];
|
[[self tableViewInColumn:columnIndex] scrollRowToVisible:rowIndex];
|
||||||
@@ -571,9 +526,6 @@
|
|||||||
|
|
||||||
- (CPIndexSet)selectedRowIndexesInColumn:(unsigned)column
|
- (CPIndexSet)selectedRowIndexesInColumn:(unsigned)column
|
||||||
{
|
{
|
||||||
if (column < 0 || column > [self lastColumn] +1)
|
|
||||||
return [CPIndexSet indexSet];
|
|
||||||
|
|
||||||
return [[self tableViewInColumn:column] selectedRowIndexes];
|
return [[self tableViewInColumn:column] selectedRowIndexes];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,6 +551,8 @@
|
|||||||
|
|
||||||
[[self tableViewInColumn:column] selectRowIndexes:indexSet byExtendingSelection:NO];
|
[[self tableViewInColumn:column] selectRowIndexes:indexSet byExtendingSelection:NO];
|
||||||
|
|
||||||
|
[self setNextResponder:[self tableViewInColumn:[self lastColumn]]];
|
||||||
|
|
||||||
[self scrollColumnToVisible:column];
|
[self scrollColumnToVisible:column];
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
|
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
|
||||||
@@ -650,8 +604,6 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var _CPBrowserResizeControlBackgroundImage = nil;
|
|
||||||
|
|
||||||
@implementation _CPBrowserResizeControl : CPView
|
@implementation _CPBrowserResizeControl : CPView
|
||||||
{
|
{
|
||||||
CGPoint _mouseDownX;
|
CGPoint _mouseDownX;
|
||||||
@@ -660,26 +612,6 @@ var _CPBrowserResizeControlBackgroundImage = nil;
|
|||||||
unsigned _width;
|
unsigned _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPImage)backgroundImage
|
|
||||||
{
|
|
||||||
if (!_CPBrowserResizeControlBackgroundImage)
|
|
||||||
{
|
|
||||||
var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
|
|
||||||
_CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
|
|
||||||
size:CGSizeMake(15, 14)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return _CPBrowserResizeControlBackgroundImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
|
||||||
{
|
|
||||||
if (self = [super initWithFrame:aFrame])
|
|
||||||
[self setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)mouseDown:(CPEvent)anEvent
|
- (void)mouseDown:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
_mouseDownX = [anEvent locationInWindow].x;
|
_mouseDownX = [anEvent locationInWindow].x;
|
||||||
@@ -694,23 +626,34 @@ var _CPBrowserResizeControlBackgroundImage = nil;
|
|||||||
[_browser setWidth:_width + deltaX ofColumn:_index];
|
[_browser setWidth:_width + deltaX ofColumn:_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseUp:(CPEvent)anEvent
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
var _CPBrowserResizeControlBackgroundImage = nil;
|
||||||
|
|
||||||
@implementation _CPBrowserScrollView : CPScrollView
|
@implementation _CPBrowserScrollView : CPScrollView
|
||||||
{
|
{
|
||||||
_CPBrowserResizeControl _resizeControl;
|
_CPBrowserResizeControl _resizeControl;
|
||||||
CPBrowser _browser @accessors;
|
CPBrowser _browser @accessors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (CPImage)backgroundImage
|
||||||
|
{
|
||||||
|
if (!_CPBrowserResizeControlBackgroundImage)
|
||||||
|
{
|
||||||
|
var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
|
||||||
|
_CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
|
||||||
|
size:CGSizeMake(15, 14)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return _CPBrowserResizeControlBackgroundImage;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)initWithFrame:(CGRect)aFrame
|
- (void)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
if (self = [super initWithFrame:aFrame])
|
if (self = [super initWithFrame:aFrame])
|
||||||
{
|
{
|
||||||
_resizeControl = [[_CPBrowserResizeControl alloc] initWithFrame:CGRectMakeZero()];
|
_resizeControl = [[_CPBrowserResizeControl alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
[_resizeControl setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
|
||||||
[self addSubview:_resizeControl];
|
[self addSubview:_resizeControl];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,8 +754,6 @@ var _CPBrowserResizeControlBackgroundImage = nil;
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
|
||||||
|
|
||||||
@implementation _CPBrowserTableDelegate : CPObject
|
@implementation _CPBrowserTableDelegate : CPObject
|
||||||
{
|
{
|
||||||
CPBrowser _browser @accessors;
|
CPBrowser _browser @accessors;
|
||||||
@@ -863,7 +804,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
|
|||||||
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(int)row proposedDropOperation:(CPTableViewDropOperation)operation
|
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(int)row proposedDropOperation:(CPTableViewDropOperation)operation
|
||||||
{
|
{
|
||||||
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
|
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
|
||||||
return [_delegate browser:_browser validateDrop:info proposedRow:row column:_index dropOperation:operation];
|
[_delegate browser:_browser validateDrop:info proposedRow:row column:_index dropOperation:operation];
|
||||||
else
|
else
|
||||||
return CPDragOperationNone;
|
return CPDragOperationNone;
|
||||||
}
|
}
|
||||||
@@ -924,9 +865,9 @@ var _CPBrowserResizeControlBackgroundImage = nil;
|
|||||||
{
|
{
|
||||||
var imageView = [self layoutEphemeralSubviewNamed:@"image-view"
|
var imageView = [self layoutEphemeralSubviewNamed:@"image-view"
|
||||||
positioned:CPWindowAbove
|
positioned:CPWindowAbove
|
||||||
relativeToEphemeralSubviewNamed:nil],
|
relativeToEphemeralSubviewNamed:nil];
|
||||||
isHighlighted = [self themeState] & CPThemeStateSelectedDataView;
|
|
||||||
|
|
||||||
|
var isHighlighted = [self themeState] & CPThemeStateSelected;
|
||||||
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
|
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
|
||||||
[imageView setImageScaling:CPScaleNone];
|
[imageView setImageScaling:CPScaleNone];
|
||||||
}
|
}
|
||||||
|
|||||||
+48
-153
@@ -26,6 +26,8 @@
|
|||||||
@import "CPControl.j"
|
@import "CPControl.j"
|
||||||
@import "CPStringDrawing.j"
|
@import "CPStringDrawing.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/* @group CPBezelStyle */
|
/* @group CPBezelStyle */
|
||||||
|
|
||||||
@@ -72,9 +74,6 @@ CPChangeBackgroundCellMask = CPBackgroundButtonMask;
|
|||||||
|
|
||||||
CPButtonStateMixed = CPThemeState("mixed");
|
CPButtonStateMixed = CPThemeState("mixed");
|
||||||
|
|
||||||
CPButtonDefaultHeight = 24.0;
|
|
||||||
CPButtonImageOffset = 3.0;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPButton
|
@class CPButton
|
||||||
@@ -90,6 +89,9 @@ CPButtonImageOffset = 3.0;
|
|||||||
CPString _title;
|
CPString _title;
|
||||||
CPString _alternateTitle;
|
CPString _alternateTitle;
|
||||||
|
|
||||||
|
CPImage _image;
|
||||||
|
CPImage _alternateImage;
|
||||||
|
|
||||||
CPInteger _showsStateBy;
|
CPInteger _showsStateBy;
|
||||||
CPInteger _highlightsBy;
|
CPInteger _highlightsBy;
|
||||||
BOOL _imageDimsWhenDisabled;
|
BOOL _imageDimsWhenDisabled;
|
||||||
@@ -97,9 +99,6 @@ CPButtonImageOffset = 3.0;
|
|||||||
// NS-style Display Properties
|
// NS-style Display Properties
|
||||||
CPBezelStyle _bezelStyle;
|
CPBezelStyle _bezelStyle;
|
||||||
CPControlSize _controlSize;
|
CPControlSize _controlSize;
|
||||||
|
|
||||||
CPString _keyEquivalent;
|
|
||||||
unsigned _keyEquivalentModifierMask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)buttonWithTitle:(CPString)aTitle
|
+ (id)buttonWithTitle:(CPString)aTitle
|
||||||
@@ -118,15 +117,15 @@ CPButtonImageOffset = 3.0;
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return @"button";
|
return @"button";
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)themeAttributes
|
+ (id)themeAttributes
|
||||||
{
|
{
|
||||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], 0.0, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null]]
|
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null]]
|
||||||
forKeys:[@"image", @"image-offset", @"bezel-inset", @"content-inset", @"bezel-color"]];
|
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -143,9 +142,6 @@ CPButtonImageOffset = 3.0;
|
|||||||
|
|
||||||
_controlSize = CPRegularControlSize;
|
_controlSize = CPRegularControlSize;
|
||||||
|
|
||||||
_keyEquivalent = @"";
|
|
||||||
_keyEquivalentModifierMask = 0;
|
|
||||||
|
|
||||||
// [self setBezelStyle:CPRoundRectBezelStyle];
|
// [self setBezelStyle:CPRoundRectBezelStyle];
|
||||||
[self setBordered:YES];
|
[self setBordered:YES];
|
||||||
}
|
}
|
||||||
@@ -282,12 +278,18 @@ CPButtonImageOffset = 3.0;
|
|||||||
|
|
||||||
- (void)setImage:(CPImage)anImage
|
- (void)setImage:(CPImage)anImage
|
||||||
{
|
{
|
||||||
[self setValue:anImage forThemeAttribute:@"image"];
|
if (_image === anImage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_image = anImage;
|
||||||
|
|
||||||
|
[self setNeedsLayout];
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPImage)image
|
- (CPImage)image
|
||||||
{
|
{
|
||||||
return [self valueForThemeAttribute:@"image" inState:CPThemeStateNormal];
|
return _image;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -296,7 +298,13 @@ CPButtonImageOffset = 3.0;
|
|||||||
*/
|
*/
|
||||||
- (void)setAlternateImage:(CPImage)anImage
|
- (void)setAlternateImage:(CPImage)anImage
|
||||||
{
|
{
|
||||||
[self setValue:anImage forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
|
if (_alternateImage === anImage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_alternateImage = anImage;
|
||||||
|
|
||||||
|
[self setNeedsLayout];
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -304,17 +312,7 @@ CPButtonImageOffset = 3.0;
|
|||||||
*/
|
*/
|
||||||
- (CPImage)alternateImage
|
- (CPImage)alternateImage
|
||||||
{
|
{
|
||||||
return [self valueForThemeAttribute:@"image" inState:CPThemeStateHighlighted];
|
return _alternateImage;
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setImageOffset:(float)theImageOffset
|
|
||||||
{
|
|
||||||
[self setValue:theImageOffset forThemeAttribute:@"image-offset"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (float)imageOffset
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"image-offset"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setShowsStateBy:(CPInteger)aMask
|
- (void)setShowsStateBy:(CPInteger)aMask
|
||||||
@@ -397,7 +395,7 @@ CPButtonImageOffset = 3.0;
|
|||||||
|
|
||||||
_imageDimsWhenDisabled = imageShouldDimWhenDisabled;
|
_imageDimsWhenDisabled = imageShouldDimWhenDisabled;
|
||||||
|
|
||||||
if ([self hasThemeState:CPThemeStateDisabled])
|
if (_imageDimsWhenDisabled)
|
||||||
{
|
{
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
@@ -433,7 +431,6 @@ CPButtonImageOffset = 3.0;
|
|||||||
if (_CGInsetIsEmpty(contentInset))
|
if (_CGInsetIsEmpty(contentInset))
|
||||||
return bounds;
|
return bounds;
|
||||||
|
|
||||||
bounds = _CGRectMakeCopy(bounds);
|
|
||||||
bounds.origin.x += contentInset.left;
|
bounds.origin.x += contentInset.left;
|
||||||
bounds.origin.y += contentInset.top;
|
bounds.origin.y += contentInset.top;
|
||||||
bounds.size.width -= contentInset.left + contentInset.right;
|
bounds.size.width -= contentInset.left + contentInset.right;
|
||||||
@@ -452,7 +449,6 @@ CPButtonImageOffset = 3.0;
|
|||||||
if (_CGInsetIsEmpty(bezelInset))
|
if (_CGInsetIsEmpty(bezelInset))
|
||||||
return bounds;
|
return bounds;
|
||||||
|
|
||||||
bounds = _CGRectMakeCopy(bounds);
|
|
||||||
bounds.origin.x += bezelInset.left;
|
bounds.origin.x += bezelInset.left;
|
||||||
bounds.origin.y += bezelInset.top;
|
bounds.origin.y += bezelInset.top;
|
||||||
bounds.size.width -= bezelInset.left + bezelInset.right;
|
bounds.size.width -= bezelInset.left + bezelInset.right;
|
||||||
@@ -466,20 +462,8 @@ CPButtonImageOffset = 3.0;
|
|||||||
*/
|
*/
|
||||||
- (void)sizeToFit
|
- (void)sizeToFit
|
||||||
{
|
{
|
||||||
[self layoutSubviews];
|
var size = [([self title] || " ") sizeWithFont:[self currentValueForThemeAttribute:@"font"]],
|
||||||
|
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
var size,
|
|
||||||
contentView = [self ephemeralSubviewNamed:@"content-view"];
|
|
||||||
|
|
||||||
if (contentView)
|
|
||||||
{
|
|
||||||
[contentView sizeToFit];
|
|
||||||
size = [contentView frameSize];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
size = [([self title] || " ") sizeWithFont:[self currentValueForThemeAttribute:@"font"]];
|
|
||||||
|
|
||||||
var contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
|
||||||
minSize = [self currentValueForThemeAttribute:@"min-size"],
|
minSize = [self currentValueForThemeAttribute:@"min-size"],
|
||||||
maxSize = [self currentValueForThemeAttribute:@"max-size"];
|
maxSize = [self currentValueForThemeAttribute:@"max-size"];
|
||||||
|
|
||||||
@@ -535,8 +519,7 @@ CPButtonImageOffset = 3.0;
|
|||||||
if (contentView)
|
if (contentView)
|
||||||
{
|
{
|
||||||
[contentView setText:([self hasThemeState:CPThemeStateHighlighted] && _alternateTitle) ? _alternateTitle : _title];
|
[contentView setText:([self hasThemeState:CPThemeStateHighlighted] && _alternateTitle) ? _alternateTitle : _title];
|
||||||
[contentView setImage:[self currentValueForThemeAttribute:@"image"]];
|
[contentView setImage:([self hasThemeState:CPThemeStateHighlighted] && _alternateImage) ? _alternateImage : _image];
|
||||||
[contentView setImageOffset:[self currentValueForThemeAttribute:@"image-offset"]];
|
|
||||||
|
|
||||||
[contentView setFont:[self currentValueForThemeAttribute:@"font"]];
|
[contentView setFont:[self currentValueForThemeAttribute:@"font"]];
|
||||||
[contentView setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
|
[contentView setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
|
||||||
@@ -547,10 +530,17 @@ CPButtonImageOffset = 3.0;
|
|||||||
[contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
|
[contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
|
||||||
[contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]];
|
[contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]];
|
||||||
[contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]];
|
[contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]];
|
||||||
[contentView setDimsImage:[self hasThemeState:CPThemeStateDisabled] && _imageDimsWhenDisabled];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setDefaultButton:(BOOL)shouldBeDefaultButton
|
||||||
|
{
|
||||||
|
if (shouldBeDefaultButton)
|
||||||
|
[self setThemeState:CPThemeStateDefault];
|
||||||
|
else
|
||||||
|
[self unsetThemeState:CPThemeStateDefault];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setBordered:(BOOL)shouldBeBordered
|
- (void)setBordered:(BOOL)shouldBeBordered
|
||||||
{
|
{
|
||||||
if (shouldBeBordered)
|
if (shouldBeBordered)
|
||||||
@@ -564,79 +554,6 @@ CPButtonImageOffset = 3.0;
|
|||||||
return [self hasThemeState:CPThemeStateBordered];
|
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
|
|
||||||
{
|
|
||||||
_keyEquivalent = 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 setThemeState:CPThemeStateDefault];
|
|
||||||
else
|
|
||||||
[self unsetThemeState:CPThemeStateDefault];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewWillMoveToWindow:(CPWindow)aWindow
|
|
||||||
{
|
|
||||||
var selfWindow = [self window];
|
|
||||||
|
|
||||||
if (selfWindow === aWindow || aWindow === nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ([selfWindow defaultButton] === self)
|
|
||||||
[selfWindow 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
|
@end
|
||||||
|
|
||||||
@implementation CPButton (NS)
|
@implementation CPButton (NS)
|
||||||
@@ -652,16 +569,11 @@ CPButtonImageOffset = 3.0;
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
var CPButtonImageKey = @"CPButtonImageKey",
|
var CPButtonImageKey = @"CPButtonImageKey",
|
||||||
CPButtonAlternateImageKey = @"CPButtonAlternateImageKey",
|
CPButtonAlternateImageKey = @"CPButtonAlternateImageKey",
|
||||||
CPButtonTitleKey = @"CPButtonTitleKey",
|
CPButtonTitleKey = @"CPButtonTitleKey",
|
||||||
CPButtonAlternateTitleKey = @"CPButtonAlternateTitleKey",
|
CPButtonAlternateTitleKey = @"CPButtonAlternateTitleKey",
|
||||||
CPButtonIsBorderedKey = @"CPButtonIsBorderedKey",
|
CPButtonIsBorderedKey = @"CPButtonIsBorderedKey";
|
||||||
CPButtonAllowsMixedStateKey = @"CPButtonAllowsMixedStateKey",
|
|
||||||
CPButtonImageDimsWhenDisabledKey = @"CPButtonImageDimsWhenDisabledKey",
|
|
||||||
CPButtonImagePositionKey = @"CPButtonImagePositionKey",
|
|
||||||
CPButtonKeyEquivalentKey = @"CPButtonKeyEquivalentKey",
|
|
||||||
CPButtonKeyEquivalentMaskKey = @"CPButtonKeyEquivalentMaskKey";
|
|
||||||
|
|
||||||
@implementation CPButton (CPCoding)
|
@implementation CPButton (CPCoding)
|
||||||
|
|
||||||
@@ -677,21 +589,11 @@ var CPButtonImageKey = @"CPButtonImageKey",
|
|||||||
{
|
{
|
||||||
_controlSize = CPRegularControlSize;
|
_controlSize = CPRegularControlSize;
|
||||||
|
|
||||||
_title = [aCoder decodeObjectForKey:CPButtonTitleKey];
|
[self setImage:[aCoder decodeObjectForKey:CPButtonImageKey]];
|
||||||
_alternateTitle = [aCoder decodeObjectForKey:CPButtonAlternateTitleKey];
|
[self setAlternateImage:[aCoder decodeObjectForKey:CPButtonAlternateImageKey]];
|
||||||
|
|
||||||
if ([aCoder containsValueForKey:CPButtonAllowsMixedStateKey])
|
[self setTitle:[aCoder decodeObjectForKey:CPButtonTitleKey]];
|
||||||
_allowsMixedState = [aCoder decodeBoolForKey:CPButtonAllowsMixedStateKey];
|
[self setAlternateTitle:[aCoder decodeObjectForKey:CPButtonAlternateTitleKey]];
|
||||||
|
|
||||||
[self setImageDimsWhenDisabled:[aCoder decodeObjectForKey:CPButtonImageDimsWhenDisabledKey]];
|
|
||||||
|
|
||||||
if ([aCoder containsValueForKey:CPButtonImagePositionKey])
|
|
||||||
[self setImagePosition:[aCoder decodeIntForKey:CPButtonImagePositionKey]];
|
|
||||||
|
|
||||||
if ([aCoder containsValueForKey:CPButtonKeyEquivalentKey])
|
|
||||||
[self setKeyEquivalent:CFData.decodeBase64ToUtf16String([aCoder decodeObjectForKey:CPButtonKeyEquivalentKey])];
|
|
||||||
|
|
||||||
_keyEquivalentModifierMask = [aCoder decodeIntForKey:CPButtonKeyEquivalentMaskKey];
|
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
@@ -708,18 +610,11 @@ var CPButtonImageKey = @"CPButtonImageKey",
|
|||||||
{
|
{
|
||||||
[super encodeWithCoder:aCoder];
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
|
[aCoder encodeObject:_image forKey:CPButtonImageKey];
|
||||||
|
[aCoder encodeObject:_alternateImage forKey:CPButtonAlternateImageKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_title forKey:CPButtonTitleKey];
|
[aCoder encodeObject:_title forKey:CPButtonTitleKey];
|
||||||
[aCoder encodeObject:_alternateTitle forKey:CPButtonAlternateTitleKey];
|
[aCoder encodeObject:_alternateTitle forKey:CPButtonAlternateTitleKey];
|
||||||
|
|
||||||
[aCoder encodeBool:_allowsMixedState forKey:CPButtonAllowsMixedStateKey];
|
|
||||||
|
|
||||||
[aCoder encodeBool:[self imageDimsWhenDisabled] forKey:CPButtonImageDimsWhenDisabledKey];
|
|
||||||
[aCoder encodeInt:[self imagePosition] forKey:CPButtonImagePositionKey];
|
|
||||||
|
|
||||||
if (_keyEquivalent)
|
|
||||||
[aCoder encodeObject:CFData.encodeBase64Utf16String(_keyEquivalent) forKey:CPButtonKeyEquivalentKey];
|
|
||||||
|
|
||||||
[aCoder encodeInt:_keyEquivalentModifierMask forKey:CPButtonKeyEquivalentMaskKey];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+28
-56
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
@implementation CPButtonBar : CPView
|
@implementation CPButtonBar : CPView
|
||||||
@@ -12,9 +14,8 @@
|
|||||||
+ (id)plusButton
|
+ (id)plusButton
|
||||||
{
|
{
|
||||||
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
|
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
|
||||||
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
|
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:self] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
|
||||||
|
|
||||||
[button setBordered:NO];
|
|
||||||
[button setImage:image];
|
[button setImage:image];
|
||||||
[button setImagePosition:CPImageOnly];
|
[button setImagePosition:CPImageOnly];
|
||||||
|
|
||||||
@@ -24,39 +25,23 @@
|
|||||||
+ (id)minusButton
|
+ (id)minusButton
|
||||||
{
|
{
|
||||||
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
|
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
|
||||||
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
|
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:self] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
|
||||||
|
|
||||||
[button setBordered:NO];
|
|
||||||
[button setImage:image];
|
[button setImage:image];
|
||||||
[button setImagePosition:CPImageOnly];
|
[button setImagePosition:CPImageOnly];
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)actionPopupButton
|
+ (CPString)themeClass
|
||||||
{
|
|
||||||
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
|
|
||||||
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
|
|
||||||
|
|
||||||
[button addItemWithTitle:nil];
|
|
||||||
[[button lastItem] setImage:image];
|
|
||||||
[button setImagePosition:CPImageOnly];
|
|
||||||
[button setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:"content-inset"];
|
|
||||||
|
|
||||||
[button setPullsDown:YES];
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
|
||||||
{
|
{
|
||||||
return @"button-bar";
|
return @"button-bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)themeAttributes
|
+ (id)themeAttributes
|
||||||
{
|
{
|
||||||
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
|
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null]]
|
||||||
forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
|
forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -97,7 +82,24 @@
|
|||||||
_buttons = [CPArray arrayWithArray:buttons];
|
_buttons = [CPArray arrayWithArray:buttons];
|
||||||
|
|
||||||
for (var i = 0, count = [_buttons count]; i < count; i++)
|
for (var i = 0, count = [_buttons count]; i < count; i++)
|
||||||
[_buttons[i] setBordered:YES];
|
{
|
||||||
|
var button = _buttons[i];
|
||||||
|
|
||||||
|
var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
|
||||||
|
highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
|
||||||
|
disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled];
|
||||||
|
|
||||||
|
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal|CPThemeStateBordered];
|
||||||
|
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted|CPThemeStateBordered];
|
||||||
|
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPThemeStateBordered];
|
||||||
|
|
||||||
|
// FIXME shouldn't need this
|
||||||
|
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
|
||||||
|
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
|
||||||
|
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
|
||||||
|
|
||||||
|
[button setBordered:YES];
|
||||||
|
}
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
}
|
}
|
||||||
@@ -174,11 +176,6 @@
|
|||||||
{
|
{
|
||||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
|
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
|
||||||
|
|
||||||
var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
|
|
||||||
highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
|
|
||||||
disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled],
|
|
||||||
textColor = [self valueForThemeAttribute:@"button-text-color" inState:CPThemeStateNormal];
|
|
||||||
|
|
||||||
var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
|
var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
|
||||||
count = [buttonsNotHidden count];
|
count = [buttonsNotHidden count];
|
||||||
|
|
||||||
@@ -187,23 +184,13 @@
|
|||||||
[buttonsNotHidden removeObject:buttonsNotHidden[count]];
|
[buttonsNotHidden removeObject:buttonsNotHidden[count]];
|
||||||
|
|
||||||
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
|
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
|
||||||
bounds = [self bounds],
|
height = CGRectGetHeight([self bounds]) - 1;
|
||||||
height = CGRectGetHeight(bounds) - 1,
|
|
||||||
frameWidth = CGRectGetWidth(bounds),
|
|
||||||
resizeRect = _hasResizeControl ? [self rectForEphemeralSubviewNamed:"resize-control-view"] : CGRectMakeZero(),
|
|
||||||
resizeWidth = CGRectGetWidth(resizeRect),
|
|
||||||
availableWidth = frameWidth - resizeWidth - 1;
|
|
||||||
|
|
||||||
for (var i = 0, count = [buttonsNotHidden count]; i < count; i++)
|
for (var i = 0, count = [buttonsNotHidden count]; i < count; i++)
|
||||||
{
|
{
|
||||||
var button = buttonsNotHidden[i],
|
var button = buttonsNotHidden[i],
|
||||||
width = CGRectGetWidth([button frame]);
|
width = CGRectGetWidth([button frame]);
|
||||||
|
|
||||||
if (availableWidth > width)
|
|
||||||
availableWidth -= width;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (_resizeControlIsLeftAligned)
|
if (_resizeControlIsLeftAligned)
|
||||||
{
|
{
|
||||||
[button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)];
|
[button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)];
|
||||||
@@ -215,16 +202,6 @@
|
|||||||
currentButtonOffset += width - 1;
|
currentButtonOffset += width - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered];
|
|
||||||
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered];
|
|
||||||
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered];
|
|
||||||
[button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
|
|
||||||
|
|
||||||
// FIXME shouldn't need this
|
|
||||||
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
|
|
||||||
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
|
|
||||||
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
|
|
||||||
|
|
||||||
[self addSubview:button];
|
[self addSubview:button];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,12 +216,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setFrameSize:(CGSize)aSize
|
|
||||||
{
|
|
||||||
[super setFrameSize:aSize];
|
|
||||||
[self setNeedsLayout];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
|
var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
|
||||||
@@ -275,3 +246,4 @@ var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
+2
-27
@@ -23,8 +23,6 @@
|
|||||||
@import "CPButton.j"
|
@import "CPButton.j"
|
||||||
|
|
||||||
|
|
||||||
CPCheckBoxImageOffset = 4.0;
|
|
||||||
|
|
||||||
@implementation CPCheckBox : CPButton
|
@implementation CPCheckBox : CPButton
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -39,7 +37,7 @@ CPCheckBoxImageOffset = 4.0;
|
|||||||
return [self buttonWithTitle:aTitle];
|
return [self buttonWithTitle:aTitle];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return @"check-box";
|
return @"check-box";
|
||||||
}
|
}
|
||||||
@@ -57,33 +55,10 @@ CPCheckBoxImageOffset = 4.0;
|
|||||||
[self setImagePosition:CPImageLeft];
|
[self setImagePosition:CPImageLeft];
|
||||||
[self setAlignment:CPLeftTextAlignment];
|
[self setAlignment:CPLeftTextAlignment];
|
||||||
|
|
||||||
[self setBordered:NO];
|
[self setBordered:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeStateFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
var count = objects.length,
|
|
||||||
value = [objects[0] valueForKeyPath:aKeyPath] ? CPOnState : CPOffState;
|
|
||||||
|
|
||||||
[self setAllowsMixedState:NO];
|
|
||||||
[self setState:value];
|
|
||||||
|
|
||||||
while (count-- > 1)
|
|
||||||
{
|
|
||||||
if (value !== ([objects[count] valueForKeyPath:aKeyPath] ? CPOnState : CPOffState))
|
|
||||||
{
|
|
||||||
[self setAllowsMixedState:YES];
|
|
||||||
[self setState:CPMixedState];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
[self takeStateFromKeyPath:aKeyPath ofObjects:objects];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+13
-33
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -67,16 +69,16 @@
|
|||||||
{
|
{
|
||||||
[self addSubview:_documentView];
|
[self addSubview:_documentView];
|
||||||
|
|
||||||
[_documentView setPostsFrameChangedNotifications:YES];
|
[_documentView setPostsFrameChangedNotifications:YES];
|
||||||
[_documentView setPostsBoundsChangedNotifications:YES];
|
[_documentView setPostsBoundsChangedNotifications:YES];
|
||||||
|
|
||||||
[defaultCenter
|
[defaultCenter
|
||||||
addObserver:self
|
addObserver:self
|
||||||
selector:@selector(viewFrameChanged:)
|
selector:@selector(viewFrameChanged:)
|
||||||
name:CPViewFrameDidChangeNotification
|
name:CPViewFrameDidChangeNotification
|
||||||
object:_documentView];
|
object:_documentView];
|
||||||
|
|
||||||
[defaultCenter
|
[defaultCenter
|
||||||
addObserver:self
|
addObserver:self
|
||||||
selector:@selector(viewBoundsChanged:)
|
selector:@selector(viewBoundsChanged:)
|
||||||
name:CPViewBoundsDidChangeNotification
|
name:CPViewBoundsDidChangeNotification
|
||||||
@@ -124,7 +126,7 @@
|
|||||||
// FIXME: Should CPScrollView be finding out about this on its own somehow?
|
// FIXME: Should CPScrollView be finding out about this on its own somehow?
|
||||||
scrollViewClass = objj_getClass("CPScrollView");
|
scrollViewClass = objj_getClass("CPScrollView");
|
||||||
|
|
||||||
if ([superview isKindOfClass:scrollViewClass])
|
if([superview isKindOfClass:scrollViewClass])
|
||||||
[superview reflectScrolledClipView:self];
|
[superview reflectScrolledClipView:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,39 +190,17 @@
|
|||||||
- (BOOL)autoscroll:(CPEvent)anEvent
|
- (BOOL)autoscroll:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var bounds = [self bounds],
|
var bounds = [self bounds],
|
||||||
eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||||
superview = [self superview],
|
|
||||||
deltaX = 0,
|
|
||||||
deltaY = 0;
|
|
||||||
|
|
||||||
if (CGRectContainsPoint(bounds, eventLocation))
|
if (CPRectContainsPoint(bounds, eventLocation))
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
if (![superview isKindOfClass:[CPScrollView class]] || [superview hasVerticalScroller])
|
var newRect = CGRectMakeZero();
|
||||||
{
|
|
||||||
if (eventLocation.y < CGRectGetMinY(bounds))
|
|
||||||
deltaY = CGRectGetMinY(bounds) - eventLocation.y;
|
|
||||||
else if (eventLocation.y > CGRectGetMaxY(bounds))
|
|
||||||
deltaY = CGRectGetMaxY(bounds) - eventLocation.y;
|
|
||||||
if (deltaY < -bounds.size.height)
|
|
||||||
deltaY = -bounds.size.height;
|
|
||||||
if (deltaY > bounds.size.height)
|
|
||||||
deltaY = bounds.size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (![superview isKindOfClass:[CPScrollView class]] || [superview hasHorizontalScroller])
|
newRect.origin = eventLocation;
|
||||||
{
|
newRect.size = CPSizeMake(10, 10);
|
||||||
if (eventLocation.x < CGRectGetMinX(bounds))
|
|
||||||
deltaX = CGRectGetMinX(bounds) - eventLocation.x;
|
|
||||||
else if (eventLocation.x > CGRectGetMaxX(bounds))
|
|
||||||
deltaX = CGRectGetMaxX(bounds) - eventLocation.x;
|
|
||||||
if (deltaX < -bounds.size.width)
|
|
||||||
deltaX = -bounds.size.width;
|
|
||||||
if (deltaX > bounds.size.width)
|
|
||||||
deltaX = bounds.size.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [self scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
|
return [_documentView scrollRectToVisible:newRect];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+26
-122
@@ -297,7 +297,7 @@
|
|||||||
*/
|
*/
|
||||||
- (void)setSelectionIndexes:(CPIndexSet)anIndexSet
|
- (void)setSelectionIndexes:(CPIndexSet)anIndexSet
|
||||||
{
|
{
|
||||||
if ([_selectionIndexes isEqual:anIndexSet] || !_isSelectable)
|
if (_selectionIndexes == anIndexSet || !_isSelectable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var index = CPNotFound;
|
var index = CPNotFound;
|
||||||
@@ -312,10 +312,8 @@
|
|||||||
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
|
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
|
||||||
[_items[index] setSelected:YES];
|
[_items[index] setSelected:YES];
|
||||||
|
|
||||||
[[CPKeyValueBinding getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
|
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
|
||||||
[_delegate collectionViewDidChangeSelection:self];
|
[_delegate collectionViewDidChangeSelection:self]
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -428,17 +426,8 @@
|
|||||||
x += itemSize.width + _horizontalMargin;
|
x += itemSize.width + _horizontalMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
var superview = [self superview],
|
|
||||||
proposedHeight = y + itemSize.height + _verticalMargin;
|
|
||||||
|
|
||||||
if ([superview isKindOfClass:[CPClipView class]])
|
|
||||||
{
|
|
||||||
var superviewSize = [superview bounds].size;
|
|
||||||
proposedHeight = MAX(superviewSize.height, proposedHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
_tileWidth = width;
|
_tileWidth = width;
|
||||||
[self setFrameSize:CGSizeMake(width, proposedHeight)];
|
[self setFrameSize:CGSizeMake(width, y + itemSize.height + _verticalMargin)];
|
||||||
_tileWidth = -1.0;
|
_tileWidth = -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,51 +582,14 @@
|
|||||||
index = row * _numberOfColumns + column;
|
index = row * _numberOfColumns + column;
|
||||||
|
|
||||||
if (index >= 0 && index < _items.length)
|
if (index >= 0 && index < _items.length)
|
||||||
{
|
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
||||||
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPCommandKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
|
|
||||||
{
|
|
||||||
if ([anEvent modifierFlags] & CPCommandKeyMask)
|
|
||||||
{
|
|
||||||
var indexes = [_selectionIndexes copy];
|
|
||||||
|
|
||||||
if ([indexes containsIndex:index])
|
|
||||||
[indexes removeIndex:index];
|
|
||||||
else
|
|
||||||
[indexes addIndex:index];
|
|
||||||
}
|
|
||||||
else if ([anEvent modifierFlags] & CPShiftKeyMask)
|
|
||||||
{
|
|
||||||
var firstSelectedIndex = [[self selectionIndexes] firstIndex],
|
|
||||||
newSelectedRange = nil;
|
|
||||||
|
|
||||||
if (index < firstSelectedIndex)
|
|
||||||
newSelectedRange = CPMakeRange(index, (firstSelectedIndex - index) + 1);
|
|
||||||
else
|
|
||||||
newSelectedRange = CPMakeRange(firstSelectedIndex, (index - firstSelectedIndex) + 1);
|
|
||||||
|
|
||||||
indexes = [[self selectionIndexes] copy];
|
|
||||||
[indexes addIndexesInRange:newSelectedRange];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
indexes = [CPIndexSet indexSetWithIndex:index];
|
|
||||||
|
|
||||||
[self setSelectionIndexes:indexes];
|
|
||||||
}
|
|
||||||
else if (_allowsEmptySelection)
|
else if (_allowsEmptySelection)
|
||||||
[self setSelectionIndexes:[CPIndexSet indexSet]];
|
[self setSelectionIndexes:[CPIndexSet indexSet]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDragged:(CPEvent)anEvent
|
- (void)mouseDragged:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var locationInWindow = [anEvent locationInWindow],
|
|
||||||
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
|
|
||||||
|
|
||||||
// FIXME: This is because Safari's drag hysteresis is 3px x 3px
|
|
||||||
if ((ABS(locationInWindow.x - mouseDownLocationInWindow.x) < 3) &&
|
|
||||||
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
|
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -654,6 +606,8 @@
|
|||||||
|
|
||||||
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
|
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
|
||||||
|
|
||||||
|
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||||
|
|
||||||
if (!_itemForDragging)
|
if (!_itemForDragging)
|
||||||
_itemForDragging = [self newItemForRepresentedObject:_content[[_selectionIndexes firstIndex]]];
|
_itemForDragging = [self newItemForRepresentedObject:_content[[_selectionIndexes firstIndex]]];
|
||||||
else
|
else
|
||||||
@@ -747,7 +701,7 @@
|
|||||||
count = [indexArray count];
|
count = [indexArray count];
|
||||||
|
|
||||||
for (; index < count; ++index)
|
for (; index < count; ++index)
|
||||||
frame = CGRectUnion(frame, [self frameForItemAtIndex:indexArray[index]]);
|
frame = CGRectUnion(frame, [self rectForItemAtIndex:indexArray[index]]);
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
@@ -756,29 +710,6 @@
|
|||||||
|
|
||||||
@implementation CPCollectionView (KeyboardInteraction)
|
@implementation CPCollectionView (KeyboardInteraction)
|
||||||
|
|
||||||
- (void)_modifySelectionWithNewIndex:(int)anIndex direction:(int)aDirection expand:(BOOL)shouldExpand
|
|
||||||
{
|
|
||||||
anIndex = MIN(MAX(anIndex, 0), [[self items] count] - 1);
|
|
||||||
|
|
||||||
if (_allowsMultipleSelection && shouldExpand)
|
|
||||||
{
|
|
||||||
var indexes = [_selectionIndexes copy],
|
|
||||||
bottomAnchor = [indexes firstIndex],
|
|
||||||
topAnchor = [indexes lastIndex];
|
|
||||||
|
|
||||||
// if the direction is backward (-1) check with the bottom anchor
|
|
||||||
if (aDirection === -1)
|
|
||||||
[indexes addIndexesInRange:CPMakeRange(anIndex, bottomAnchor - anIndex + 1)];
|
|
||||||
else
|
|
||||||
[indexes addIndexesInRange:CPMakeRange(topAnchor, anIndex - topAnchor + 1)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
indexes = [CPIndexSet indexSetWithIndex:anIndex];
|
|
||||||
|
|
||||||
[self setSelectionIndexes:indexes];
|
|
||||||
[self _scrollToSelection];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_scrollToSelection
|
- (void)_scrollToSelection
|
||||||
{
|
{
|
||||||
var frame = [self frameForItemsAtIndexes:[self selectionIndexes]];
|
var frame = [self frameForItemsAtIndexes:[self selectionIndexes]];
|
||||||
@@ -793,36 +724,26 @@
|
|||||||
if (index === CPNotFound)
|
if (index === CPNotFound)
|
||||||
index = [[self items] count];
|
index = [[self items] count];
|
||||||
|
|
||||||
[self _modifySelectionWithNewIndex:index - 1 direction:-1 expand:NO];
|
index = MAX(index - 1, 0);
|
||||||
}
|
|
||||||
|
|
||||||
- (void)moveLeftAndModifySelection:(id)sender
|
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
||||||
{
|
[self _scrollToSelection];
|
||||||
var index = [[self selectionIndexes] firstIndex];
|
|
||||||
if (index === CPNotFound)
|
|
||||||
index = [[self items] count];
|
|
||||||
|
|
||||||
[self _modifySelectionWithNewIndex:index - 1 direction:-1 expand:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)moveRight:(id)sender
|
- (void)moveRight:(id)sender
|
||||||
{
|
{
|
||||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + 1 direction:1 expand:NO];
|
var index = MIN([[self selectionIndexes] firstIndex] + 1, [[self items] count]-1);
|
||||||
}
|
|
||||||
|
|
||||||
- (void)moveRightAndModifySelection:(id)sender
|
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
||||||
{
|
[self _scrollToSelection];
|
||||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + 1 direction:1 expand:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)moveDown:(id)sender
|
- (void)moveDown:(id)sender
|
||||||
{
|
{
|
||||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + [self numberOfColumns] direction:1 expand:NO];
|
var index = MIN([[self selectionIndexes] firstIndex] + [self numberOfColumns], [[self items] count]-1);
|
||||||
}
|
|
||||||
|
|
||||||
- (void)moveDownAndModifySelection:(id)sender
|
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
||||||
{
|
[self _scrollToSelection];
|
||||||
[self _modifySelectionWithNewIndex:[[self selectionIndexes] lastIndex] + [self numberOfColumns] direction:1 expand:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)moveUp:(id)sender
|
- (void)moveUp:(id)sender
|
||||||
@@ -831,16 +752,10 @@
|
|||||||
if (index == CPNotFound)
|
if (index == CPNotFound)
|
||||||
index = [[self items] count];
|
index = [[self items] count];
|
||||||
|
|
||||||
[self _modifySelectionWithNewIndex:index - [self numberOfColumns] direction:-1 expand:NO];
|
index = MAX(0, index - [self numberOfColumns]);
|
||||||
}
|
|
||||||
|
|
||||||
- (void)moveUpAndModifySelection:(id)sender
|
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
|
||||||
{
|
[self _scrollToSelection];
|
||||||
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
|
- (void)deleteBackward:(id)sender
|
||||||
@@ -850,8 +765,8 @@
|
|||||||
[[self delegate] collectionView:self shouldDeleteItemsAtIndexes:[self selectionIndexes]];
|
[[self delegate] collectionView:self shouldDeleteItemsAtIndexes:[self selectionIndexes]];
|
||||||
|
|
||||||
var index = [[self selectionIndexes] firstIndex];
|
var index = [[self selectionIndexes] firstIndex];
|
||||||
if (index > [[self content] count] - 1)
|
if (index > [[self content] count]-1)
|
||||||
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:[[self content] count] - 1]];
|
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:[[self content] count]-1]];
|
||||||
|
|
||||||
[self _scrollToSelection];
|
[self _scrollToSelection];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
@@ -885,14 +800,11 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
|
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
|
||||||
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
|
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
|
||||||
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey",
|
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey",
|
||||||
CPCollectionViewMaxNumberOfRowsKey = @"CPCollectionViewMaxNumberOfRowsKey",
|
CPCollectionViewSelectableKey = @"CPCollectionViewSelectableKey",
|
||||||
CPCollectionViewMaxNumberOfColumnsKey = @"CPCollectionViewMaxNumberOfColumnsKey",
|
CPCollectionViewBackgroundColorsKey = @"CPCollectionViewBackgroundColorsKey";
|
||||||
CPCollectionViewSelectableKey = @"CPCollectionViewSelectableKey",
|
|
||||||
CPCollectionViewAllowsMultipleSelectionKey = @"CPCollectionViewAllowsMultipleSelectionKey",
|
|
||||||
CPCollectionViewBackgroundColorsKey = @"CPCollectionViewBackgroundColorsKey";
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CPCollectionView (CPCoding)
|
@implementation CPCollectionView (CPCoding)
|
||||||
@@ -913,13 +825,9 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
|
|||||||
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
|
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
|
||||||
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
|
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
|
||||||
|
|
||||||
_maxNumberOfRows = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfRowsKey] || 0;
|
|
||||||
_maxNumberOfColumns = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfColumnsKey] || 0;
|
|
||||||
|
|
||||||
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
|
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
|
||||||
|
|
||||||
_isSelectable = [aCoder decodeBoolForKey:CPCollectionViewSelectableKey];
|
_isSelectable = [aCoder decodeBoolForKey:CPCollectionViewSelectableKey];
|
||||||
_allowsMultipleSelection = [aCoder decodeBoolForKey:CPCollectionViewAllowsMultipleSelectionKey];
|
|
||||||
|
|
||||||
[self setBackgroundColors:[aCoder decodeObjectForKey:CPCollectionViewBackgroundColorsKey]];
|
[self setBackgroundColors:[aCoder decodeObjectForKey:CPCollectionViewBackgroundColorsKey]];
|
||||||
|
|
||||||
@@ -943,11 +851,7 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
|
|||||||
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
|
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
|
||||||
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
|
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
|
||||||
|
|
||||||
[aCoder encodeInt:_maxNumberOfRows forKey:CPCollectionViewMaxNumberOfRowsKey];
|
|
||||||
[aCoder encodeInt:_maxNumberOfColumns forKey:CPCollectionViewMaxNumberOfColumnsKey];
|
|
||||||
|
|
||||||
[aCoder encodeBool:_isSelectable forKey:CPCollectionViewSelectableKey];
|
[aCoder encodeBool:_isSelectable forKey:CPCollectionViewSelectableKey];
|
||||||
[aCoder encodeBool:_allowsMultipleSelection forKey:CPCollectionViewAllowsMultipleSelectionKey];
|
|
||||||
|
|
||||||
[aCoder encodeFloat:_verticalMargin forKey:CPCollectionViewVerticalMarginKey];
|
[aCoder encodeFloat:_verticalMargin forKey:CPCollectionViewVerticalMarginKey];
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
@import "CPViewController.j"
|
@import "CPViewController.j"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Represents an object inside a CPCollectionView.
|
Represents an object inside a CPCollectionView.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+41
-37
@@ -56,12 +56,18 @@ var cachedBlackColor,
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
|
@code CPColor
|
||||||
|
|
||||||
\c CPColor can be used to represent color
|
\c CPColor can be used to represent color
|
||||||
in an RGB or HSB model with an optional transparency value.</p>
|
in an RGB or HSB model with an optional transparency value.</p>
|
||||||
|
|
||||||
<p>It also provides some class helper methods that
|
<p>It also provides some class helper methods that
|
||||||
returns instances of commonly used colors.</p>
|
returns instances of commonly used colors.</p>
|
||||||
|
|
||||||
|
<p>The class does not have a \c -set: method
|
||||||
|
like NextStep based frameworks to change the color of
|
||||||
|
the current context. To change the color of the current
|
||||||
|
context, use CGContextSetFillColor().
|
||||||
*/
|
*/
|
||||||
@implementation CPColor : CPObject
|
@implementation CPColor : CPObject
|
||||||
{
|
{
|
||||||
@@ -156,7 +162,7 @@ var cachedBlackColor,
|
|||||||
|
|
||||||
+ (CPColor)colorWithHue:(float)hue saturation:(float)saturation brightness:(float)brightness alpha:(float)alpha
|
+ (CPColor)colorWithHue:(float)hue saturation:(float)saturation brightness:(float)brightness alpha:(float)alpha
|
||||||
{
|
{
|
||||||
if (saturation === 0.0)
|
if(saturation === 0.0)
|
||||||
return [CPColor colorWithCalibratedWhite:brightness / 100.0 alpha:alpha];
|
return [CPColor colorWithCalibratedWhite:brightness / 100.0 alpha:alpha];
|
||||||
|
|
||||||
var f = hue % 60,
|
var f = hue % 60,
|
||||||
@@ -165,7 +171,7 @@ var cachedBlackColor,
|
|||||||
t = (brightness * (6000 - saturation * (60 -f))) / 600000,
|
t = (brightness * (6000 - saturation * (60 -f))) / 600000,
|
||||||
b = brightness / 100.0;
|
b = brightness / 100.0;
|
||||||
|
|
||||||
switch (FLOOR(hue / 60))
|
switch(FLOOR(hue / 60))
|
||||||
{
|
{
|
||||||
case 0: return [CPColor colorWithCalibratedRed: b green: t blue: p alpha: alpha];
|
case 0: return [CPColor colorWithCalibratedRed: b green: t blue: p alpha: alpha];
|
||||||
case 1: return [CPColor colorWithCalibratedRed: q green: b blue: p alpha: alpha];
|
case 1: return [CPColor colorWithCalibratedRed: q green: b blue: p alpha: alpha];
|
||||||
@@ -188,8 +194,7 @@ var cachedBlackColor,
|
|||||||
*/
|
*/
|
||||||
+ (CPColor)colorWithHexString:(string)hex
|
+ (CPColor)colorWithHexString:(string)hex
|
||||||
{
|
{
|
||||||
var rgba = hexToRGB(hex);
|
return [[CPColor alloc] _initWithRGBA: hexToRGB(hex)];
|
||||||
return rgba ? [[CPColor alloc] _initWithRGBA: rgba] : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -404,20 +409,20 @@ var cachedBlackColor,
|
|||||||
/* @ignore */
|
/* @ignore */
|
||||||
- (id)_initWithCSSString:(CPString)aString
|
- (id)_initWithCSSString:(CPString)aString
|
||||||
{
|
{
|
||||||
if (aString.indexOf("rgb") == CPNotFound)
|
if(aString.indexOf("rgb") == CPNotFound)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
var startingIndex = aString.indexOf("("),
|
var startingIndex = aString.indexOf("(");
|
||||||
parts = aString.substring(startingIndex + 1).split(',');
|
var parts = aString.substring(startingIndex+1).split(',');
|
||||||
|
|
||||||
_components = [
|
_components = [
|
||||||
parseInt(parts[0], 10) / 255.0,
|
parseInt(parts[0], 10) / 255.0,
|
||||||
parseInt(parts[1], 10) / 255.0,
|
parseInt(parts[1], 10) / 255.0,
|
||||||
parseInt(parts[2], 10) / 255.0,
|
parseInt(parts[2], 10) / 255.0,
|
||||||
parts[3] ? parseInt(parts[3], 10) / 255.0 : 1.0
|
parts[3] ? parseInt(parts[3], 10) / 255.0 : 1.0
|
||||||
];
|
]
|
||||||
|
|
||||||
_cssString = aString;
|
_cssString = aString;
|
||||||
|
|
||||||
@@ -556,16 +561,13 @@ var cachedBlackColor,
|
|||||||
saturation = (max != 0) ? delta / max : 0;
|
saturation = (max != 0) ? delta / max : 0;
|
||||||
|
|
||||||
var hue;
|
var hue;
|
||||||
|
if(saturation == 0)
|
||||||
if (saturation == 0)
|
|
||||||
{
|
|
||||||
hue = 0;
|
hue = 0;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var rr = (max - red) / delta,
|
var rr = (max - red) / delta;
|
||||||
gr = (max - green) / delta,
|
var gr = (max - green) / delta;
|
||||||
br = (max - blue) / delta;
|
var br = (max - blue) / delta;
|
||||||
|
|
||||||
if (red == max)
|
if (red == max)
|
||||||
hue = br - gr;
|
hue = br - gr;
|
||||||
@@ -697,48 +699,50 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
var hexCharacters = "0123456789ABCDEF";
|
var hexCharacters = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
// HACK: prevent these from becoming globals. workaround for obj-j "function foo(){}" behavior
|
||||||
|
var hexToRGB, rgbToHex, byteToHex;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Used for the CPColor \c +colorWithHexString: implementation
|
Used for the CPColor \c +colorWithHexString: implementation
|
||||||
@ignore
|
@ignore
|
||||||
@class CPColor
|
@class CPColor
|
||||||
@return an array of rgb components
|
@return an array of rgb components
|
||||||
*/
|
*/
|
||||||
var hexToRGB = function(hex)
|
function hexToRGB(hex)
|
||||||
{
|
{
|
||||||
if (hex.length == 3)
|
if ( hex.length == 3 )
|
||||||
hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
|
hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
|
||||||
|
if(hex.length != 6)
|
||||||
if (hex.length != 6)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
hex = hex.toUpperCase();
|
hex = hex.toUpperCase();
|
||||||
|
|
||||||
for (var i = 0; i < hex.length; i++)
|
for(var i=0; i<hex.length; i++)
|
||||||
if (hexCharacters.indexOf(hex.charAt(i)) == -1)
|
if(hexCharacters.indexOf(hex.charAt(i)) == -1)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var red = (hexCharacters.indexOf(hex.charAt(0)) * 16 + hexCharacters.indexOf(hex.charAt(1))) / 255.0,
|
var red = (hexCharacters.indexOf(hex.charAt(0)) * 16 + hexCharacters.indexOf(hex.charAt(1))) / 255.0;
|
||||||
green = (hexCharacters.indexOf(hex.charAt(2)) * 16 + hexCharacters.indexOf(hex.charAt(3))) / 255.0,
|
var green = (hexCharacters.indexOf(hex.charAt(2)) * 16 + hexCharacters.indexOf(hex.charAt(3))) / 255.0;
|
||||||
blue = (hexCharacters.indexOf(hex.charAt(4)) * 16 + hexCharacters.indexOf(hex.charAt(5))) / 255.0;
|
var blue = (hexCharacters.indexOf(hex.charAt(4)) * 16 + hexCharacters.indexOf(hex.charAt(5))) / 255.0;
|
||||||
|
|
||||||
return [red, green, blue, 1.0];
|
return [red, green, blue, 1.0];
|
||||||
};
|
}
|
||||||
|
|
||||||
var rgbToHex = function(r,g,b)
|
function rgbToHex(r,g,b) {
|
||||||
{
|
|
||||||
return byteToHex(r) + byteToHex(g) + byteToHex(b);
|
return byteToHex(r) + byteToHex(g) + byteToHex(b);
|
||||||
};
|
}
|
||||||
|
|
||||||
var byteToHex = function(n)
|
function byteToHex(n) {
|
||||||
{
|
if (!n || isNaN(n)) return "00";
|
||||||
if (!n || isNaN(n))
|
n = ROUND(MIN(255,MAX(0,256*n)));
|
||||||
return "00";
|
return hexCharacters.charAt((n - n % 16) / 16) +
|
||||||
|
hexCharacters.charAt(n % 16);
|
||||||
|
}
|
||||||
|
|
||||||
n = FLOOR(MIN(255, MAX(0, 256 * n)));
|
// Toll-Free bridge CPColor to CGColor.
|
||||||
|
//CGColor.prototype.isa = CPColor;
|
||||||
|
//[CPColor initialize];
|
||||||
|
|
||||||
return hexCharacters.charAt((n - n % 16) / 16) +
|
//http://dev.mootools.net/browser/trunk/Source/Utilities/Color.js?rev=1184
|
||||||
hexCharacters.charAt(n % 16);
|
|
||||||
};
|
|
||||||
|
|||||||
+26
-29
@@ -20,13 +20,11 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPApplication.j"
|
|
||||||
@import "CPButton.j"
|
@import "CPButton.j"
|
||||||
@import "CPCookie.j"
|
@import "CPCookie.j"
|
||||||
@import "CPPanel.j"
|
@import "CPPanel.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
|
||||||
CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
|
CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
|
||||||
|
|
||||||
var PREVIEW_HEIGHT = 20.0,
|
var PREVIEW_HEIGHT = 20.0,
|
||||||
@@ -109,7 +107,7 @@ CPColorPickerViewHeight = 370;
|
|||||||
+ (void)setPickerMode:(CPColorPanelMode)mode
|
+ (void)setPickerMode:(CPColorPanelMode)mode
|
||||||
{
|
{
|
||||||
var panel = [CPColorPanel sharedColorPanel];
|
var panel = [CPColorPanel sharedColorPanel];
|
||||||
[panel setMode:mode];
|
[panel setMode: mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -245,11 +243,11 @@ CPColorPickerViewHeight = 370;
|
|||||||
[view setFrame:[_currentView frame]];
|
[view setFrame:[_currentView frame]];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var height = (TOOLBAR_HEIGHT + 10 + PREVIEW_HEIGHT + 5 + SWATCH_HEIGHT + 32),
|
var height = (TOOLBAR_HEIGHT+10+PREVIEW_HEIGHT+5+SWATCH_HEIGHT+32),
|
||||||
bounds = [[self contentView] bounds];
|
bounds = [[self contentView] bounds];
|
||||||
|
|
||||||
[view setFrameSize:CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
|
[view setFrameSize: CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
|
||||||
[view setFrameOrigin:CPPointMake(5, height)];
|
[view setFrameOrigin: CPPointMake(5, height)];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_currentView removeFromSuperview];
|
[_currentView removeFromSuperview];
|
||||||
@@ -287,7 +285,7 @@ CPColorPickerViewHeight = 370;
|
|||||||
_colorPickers = [];
|
_colorPickers = [];
|
||||||
|
|
||||||
var count = [ColorPickerClasses count];
|
var count = [ColorPickerClasses count];
|
||||||
for (var i = 0; i < count; i++)
|
for (var i=0; i<count; i++)
|
||||||
{
|
{
|
||||||
var currentPickerClass = ColorPickerClasses[i],
|
var currentPickerClass = ColorPickerClasses[i],
|
||||||
currentPicker = [[currentPickerClass alloc] initWithPickerMask:0 colorPanel:self];
|
currentPicker = [[currentPickerClass alloc] initWithPickerMask:0 colorPanel:self];
|
||||||
@@ -305,17 +303,17 @@ CPColorPickerViewHeight = 370;
|
|||||||
leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
|
leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
|
||||||
buttonForLater = nil;
|
buttonForLater = nil;
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
for (var i=0; i<count; i++)
|
||||||
{
|
{
|
||||||
var image = [_colorPickers[i] provideNewButtonImage],
|
var image = [_colorPickers[i] provideNewButtonImage],
|
||||||
highlightImage = [_colorPickers[i] provideNewAlternateButtonImage],
|
highlightImage = [_colorPickers[i] provideNewAlternateButtonImage],
|
||||||
button = [[CPButton alloc] initWithFrame:CGRectMake(leftOffset + i * (ICON_WIDTH + ICON_PADDING), 0, ICON_WIDTH, ICON_WIDTH)];
|
button = [[CPButton alloc] initWithFrame:CGRectMake(leftOffset + i*(ICON_WIDTH+ICON_PADDING), 0, ICON_WIDTH, ICON_WIDTH)];
|
||||||
|
|
||||||
[button setTag:i];
|
[button setTag:i];
|
||||||
[button setTarget:self];
|
[button setTarget:self];
|
||||||
[button setAction:@selector(_setPicker:)];
|
[button setAction:@selector(_setPicker:)];
|
||||||
[button setBordered:NO];
|
[button setBordered:NO];
|
||||||
[button setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
|
[button setAutoresizingMask:CPViewMinXMargin|CPViewMaxXMargin];
|
||||||
|
|
||||||
[button setImage:image];
|
[button setImage:image];
|
||||||
[button setAlternateImage:highlightImage];
|
[button setAlternateImage:highlightImage];
|
||||||
@@ -340,7 +338,7 @@ CPColorPickerViewHeight = 370;
|
|||||||
[previewBox addSubview:_previewView];
|
[previewBox addSubview:_previewView];
|
||||||
|
|
||||||
var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
|
var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
|
||||||
[_previewLabel setStringValue:"Preview:"];
|
[_previewLabel setStringValue: "Preview:"];
|
||||||
[_previewLabel setTextColor:[CPColor blackColor]];
|
[_previewLabel setTextColor:[CPColor blackColor]];
|
||||||
[_previewLabel setAlignment:CPRightTextAlignment];
|
[_previewLabel setAlignment:CPRightTextAlignment];
|
||||||
|
|
||||||
@@ -352,8 +350,8 @@ CPColorPickerViewHeight = 370;
|
|||||||
|
|
||||||
_swatchView = [[_CPColorPanelSwatches alloc] initWithFrame:CGRectInset([swatchBox bounds], 1.0, 1.0)];
|
_swatchView = [[_CPColorPanelSwatches alloc] initWithFrame:CGRectInset([swatchBox bounds], 1.0, 1.0)];
|
||||||
|
|
||||||
[_swatchView setColorPanel:self];
|
[_swatchView setColorPanel: self];
|
||||||
[_swatchView setAutoresizingMask:CPViewWidthSizable];
|
[_swatchView setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
[swatchBox addSubview:_swatchView];
|
[swatchBox addSubview:_swatchView];
|
||||||
|
|
||||||
@@ -417,7 +415,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
CPCookie _swatchCookie;
|
CPCookie _swatchCookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CPRect)aFrame
|
-(id)initWithFrame:(CPRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
@@ -432,10 +430,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
|
|
||||||
_swatches = [];
|
_swatches = [];
|
||||||
|
|
||||||
for (var i = 0; i < 50; i++)
|
for(var i=0; i < 50; i++)
|
||||||
{
|
{
|
||||||
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
||||||
var view = [[CPView alloc] initWithFrame: CPRectMake(13 * i + 1, 1, 12, 12)],
|
var view = [[CPView alloc] initWithFrame: CPRectMake(13*i+1, 1, 12, 12)],
|
||||||
fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
|
fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
|
||||||
|
|
||||||
[view setBackgroundColor:whiteColor];
|
[view setBackgroundColor:whiteColor];
|
||||||
@@ -459,8 +457,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
- (CPArray)startingColorList
|
- (CPArray)startingColorList
|
||||||
{
|
{
|
||||||
var cookieValue = [_swatchCookie value];
|
var cookieValue = [_swatchCookie value];
|
||||||
|
if(cookieValue == "")
|
||||||
if (cookieValue == "")
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[CPColor blackColor],
|
[CPColor blackColor],
|
||||||
@@ -475,10 +472,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
var cookieValue = eval(cookieValue),
|
var cookieValue = eval(cookieValue);
|
||||||
result = [];
|
var result = [];
|
||||||
|
|
||||||
for (var i = 0; i < cookieValue.length; i++)
|
for(var i=0; i<cookieValue.length; i++)
|
||||||
result.push([CPColor colorWithHexString: cookieValue[i]]);
|
result.push([CPColor colorWithHexString: cookieValue[i]]);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -488,7 +485,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
{
|
{
|
||||||
var result = [];
|
var result = [];
|
||||||
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
||||||
for (var i = 0; i < _swatches.length; i++)
|
for(var i=0; i<_swatches.length; i++)
|
||||||
result.push([[[_swatches[i] subviews][0] backgroundColor] hexString]);
|
result.push([[[_swatches[i] subviews][0] backgroundColor] hexString]);
|
||||||
|
|
||||||
var future = new Date();
|
var future = new Date();
|
||||||
@@ -524,7 +521,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
||||||
bounds = [self bounds];
|
bounds = [self bounds];
|
||||||
|
|
||||||
if (!CGRectContainsPoint(bounds, point) || point.x > [self bounds].size.width - 1 || point.x < 1)
|
if(!CGRectContainsPoint(bounds, point) || point.x > [self bounds].size.width - 1 || point.x < 1)
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
[_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
|
[_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
|
||||||
@@ -547,7 +544,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
var bounds = CPRectCreateCopy([swatch bounds]);
|
var bounds = CPRectCreateCopy([swatch bounds]);
|
||||||
|
|
||||||
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
||||||
var dragView = [[CPView alloc] initWithFrame: bounds],
|
var dragView = [[CPView alloc] initWithFrame: bounds];
|
||||||
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
|
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
|
||||||
|
|
||||||
[dragView setBackgroundColor:[CPColor blackColor]];
|
[dragView setBackgroundColor:[CPColor blackColor]];
|
||||||
@@ -566,7 +563,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
|
|
||||||
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
|
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
|
||||||
{
|
{
|
||||||
if (aType == CPColorDragType)
|
if(aType == CPColorDragType)
|
||||||
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:aType];
|
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:aType];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,7 +573,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
pasteboard = [aSender draggingPasteboard],
|
pasteboard = [aSender draggingPasteboard],
|
||||||
swatch = nil;
|
swatch = nil;
|
||||||
|
|
||||||
if (![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
|
if(![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex: FLOOR(location.x / 13)];
|
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex: FLOOR(location.x / 13)];
|
||||||
@@ -613,7 +610,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
{
|
{
|
||||||
var pasteboard = [aSender draggingPasteboard];
|
var pasteboard = [aSender draggingPasteboard];
|
||||||
|
|
||||||
if (![pasteboard availableTypeFromArray:[CPColorDragType]])
|
if(![pasteboard availableTypeFromArray:[CPColorDragType]])
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
var color = [CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]];
|
var color = [CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]];
|
||||||
@@ -634,7 +631,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
var bounds = CPRectMake(0, 0, 15, 15);
|
var bounds = CPRectMake(0, 0, 15, 15);
|
||||||
|
|
||||||
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
|
||||||
var dragView = [[CPView alloc] initWithFrame: bounds],
|
var dragView = [[CPView alloc] initWithFrame: bounds];
|
||||||
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
|
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
|
||||||
|
|
||||||
[dragView setBackgroundColor:[CPColor blackColor]];
|
[dragView setBackgroundColor:[CPColor blackColor]];
|
||||||
@@ -653,7 +650,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
|
|
||||||
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
|
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
|
||||||
{
|
{
|
||||||
if (aType == CPColorDragType)
|
if(aType == CPColorDragType)
|
||||||
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:[self backgroundColor]] forType:aType];
|
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:[self backgroundColor]] forType:aType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-33
@@ -21,9 +21,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
@import "CPColorPanel.j"
|
||||||
|
|
||||||
@import "CPView.j"
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -108,12 +108,12 @@
|
|||||||
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
|
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initView
|
-(id)initView
|
||||||
{
|
{
|
||||||
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
|
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
|
||||||
|
|
||||||
_pickerView = [[CPView alloc] initWithFrame:aFrame];
|
_pickerView = [[CPView alloc] initWithFrame:aFrame];
|
||||||
[_pickerView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
[_pickerView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
||||||
|
|
||||||
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
|
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
|
||||||
|
|
||||||
@@ -136,17 +136,17 @@
|
|||||||
[_pickerView addSubview:_brightnessSlider];
|
[_pickerView addSubview:_brightnessSlider];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)brightnessSliderDidChange:(id)sender
|
-(void)brightnessSliderDidChange:(id)sender
|
||||||
{
|
{
|
||||||
[self updateColor];
|
[self updateColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)colorWheelDidChange:(id)sender
|
-(void)colorWheelDidChange:(id)sender
|
||||||
{
|
{
|
||||||
[self updateColor];
|
[self updateColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateColor
|
-(void)updateColor
|
||||||
{
|
{
|
||||||
var hue = [_hueSaturationView angle],
|
var hue = [_hueSaturationView angle],
|
||||||
saturation = [_hueSaturationView distance],
|
saturation = [_hueSaturationView distance],
|
||||||
@@ -223,7 +223,7 @@
|
|||||||
float _radius;
|
float _radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CPRect)aFrame
|
-(id)initWithFrame:(CPRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
@@ -261,19 +261,19 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setWheelBrightness:(float)brightness
|
-(void)setWheelBrightness:(float)brightness
|
||||||
{
|
{
|
||||||
_blackWheelImage.style.opacity = 1.0 - brightness;
|
_blackWheelImage.style.opacity = 1.0 - brightness;
|
||||||
_blackWheelImage.style.filter = "alpha(opacity=" + (1.0 - brightness) * 100 + ")"
|
_blackWheelImage.style.filter = "alpha(opacity=" + (1.0 - brightness)*100 + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setFrameSize:(CPSize)aSize
|
-(void)setFrameSize:(CPSize)aSize
|
||||||
{
|
{
|
||||||
[super setFrameSize:aSize];
|
[super setFrameSize:aSize];
|
||||||
[self setWheelSize:aSize];
|
[self setWheelSize:aSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setWheelSize:(CPSize)aSize
|
-(void)setWheelSize:(CPSize)aSize
|
||||||
{
|
{
|
||||||
var min = MIN(aSize.width, aSize.height);
|
var min = MIN(aSize.width, aSize.height);
|
||||||
|
|
||||||
@@ -296,55 +296,57 @@
|
|||||||
[self setAngle:[self degreesToRadians:_angle] distance:(_distance / 100.0) * _radius];
|
[self setAngle:[self degreesToRadians:_angle] distance:(_distance / 100.0) * _radius];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDelegate:(id)aDelegate
|
-(void)setDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
_delegate = aDelegate;
|
_delegate = aDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)delegate
|
-(id)delegate
|
||||||
{
|
{
|
||||||
return _delegate;
|
return _delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float)angle
|
-(float)angle
|
||||||
{
|
{
|
||||||
return _angle;
|
return _angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float)distance
|
-(float)distance
|
||||||
{
|
{
|
||||||
return _distance;
|
return _distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDown:(CPEvent)anEvent
|
-(void)mouseDown:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
[self reposition:anEvent];
|
[self reposition:anEvent];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDragged:(CPEvent)anEvent
|
-(void)mouseDragged:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
[self reposition:anEvent];
|
[self reposition:anEvent];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reposition:(CPEvent)anEvent
|
-(void)reposition:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var bounds = [self bounds],
|
var bounds = [self bounds],
|
||||||
location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||||
midX = CGRectGetMidX(bounds),
|
|
||||||
midY = CGRectGetMidY(bounds),
|
var midX = CGRectGetMidX(bounds);
|
||||||
distance = MIN(SQRT((location.x - midX) * (location.x - midX) + (location.y - midY) * (location.y - midY)), _radius),
|
var midY = CGRectGetMidY(bounds);
|
||||||
angle = ATAN2(location.y - midY, location.x - midX);
|
|
||||||
|
var distance = MIN(SQRT((location.x - midX)*(location.x - midX) + (location.y - midY)*(location.y - midY)), _radius);
|
||||||
|
var angle = ATAN2(location.y - midY, location.x - midX);
|
||||||
|
|
||||||
[self setAngle:angle distance:distance];
|
[self setAngle:angle distance:distance];
|
||||||
|
|
||||||
[_delegate colorWheelDidChange:self];
|
[_delegate colorWheelDidChange:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAngle:(int)angle distance:(float)distance
|
-(void)setAngle:(int)angle distance:(float)distance
|
||||||
{
|
{
|
||||||
var bounds = [self bounds],
|
var bounds = [self bounds];
|
||||||
midX = CGRectGetMidX(bounds),
|
var midX = CGRectGetMidX(bounds);
|
||||||
midY = CGRectGetMidY(bounds);
|
var midY = CGRectGetMidY(bounds);
|
||||||
|
|
||||||
_angle = [self radiansToDegrees:angle];
|
_angle = [self radiansToDegrees:angle];
|
||||||
_distance = (distance / _radius) * 100.0;
|
_distance = (distance / _radius) * 100.0;
|
||||||
@@ -352,22 +354,23 @@
|
|||||||
[_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
|
[_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setPositionToColor:(CPColor)aColor
|
-(void)setPositionToColor:(CPColor)aColor
|
||||||
{
|
{
|
||||||
var hsb = [aColor hsbComponents],
|
var hsb = [aColor hsbComponents],
|
||||||
bounds = [self bounds],
|
bounds = [self bounds];
|
||||||
angle = [self degreesToRadians:hsb[0]],
|
|
||||||
|
var angle = [self degreesToRadians:hsb[0]],
|
||||||
distance = (hsb[1] / 100.0) * _radius;
|
distance = (hsb[1] / 100.0) * _radius;
|
||||||
|
|
||||||
[self setAngle:angle distance:distance];
|
[self setAngle:angle distance:distance];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)radiansToDegrees:(float)radians
|
-(int)radiansToDegrees:(float)radians
|
||||||
{
|
{
|
||||||
return ((-radians / PI) * 180 + 360) % 360;
|
return ((-radians / PI) * 180 + 360) % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float)degreesToRadians:(float)degrees
|
-(float)degreesToRadians:(float)degrees
|
||||||
{
|
{
|
||||||
return -(((degrees - 360) / 180) * PI);
|
return -(((degrees - 360) / 180) * PI);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,25 +231,19 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
|||||||
|
|
||||||
- (void)mouseDown:(CPEvent)anEvent
|
- (void)mouseDown:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
if (![self isEnabled])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self drawBezelWithHighlight:YES];
|
[self drawBezelWithHighlight:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDragged:(CPEvent)anEvent
|
- (void)mouseDragged:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
if (![self isEnabled])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
|
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseUp:(CPEvent)anEvent
|
-(void)mouseUp:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
[self drawBezelWithHighlight:NO];
|
[self drawBezelWithHighlight:NO];
|
||||||
|
|
||||||
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled])
|
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[self activate:YES];
|
[self activate:YES];
|
||||||
@@ -278,7 +272,7 @@ var CPColorWellColorKey = "CPColorWellColorKey",
|
|||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_active = NO;
|
_active = NO;
|
||||||
_bordered = [aCoder decodeBoolForKey:CPColorWellBorderedKey];
|
_bordered = [aCoder decodeObjectForKey:CPColorWellBorderedKey];
|
||||||
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
|
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
|
||||||
|
|
||||||
[self drawBezelWithHighlight:NO];
|
[self drawBezelWithHighlight:NO];
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
@import "CPEvent.j"
|
@import "CPEvent.j"
|
||||||
@import "CPPlatform.j"
|
@import "CPPlatform.j"
|
||||||
|
|
||||||
|
|
||||||
// Browser Engines
|
// Browser Engines
|
||||||
CPUnknownBrowserEngine = 0;
|
CPUnknownBrowserEngine = 0;
|
||||||
CPGeckoBrowserEngine = 1;
|
CPGeckoBrowserEngine = 1;
|
||||||
@@ -78,7 +77,7 @@ if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
|
|||||||
USER_AGENT = window.navigator.userAgent;
|
USER_AGENT = window.navigator.userAgent;
|
||||||
|
|
||||||
// Opera
|
// Opera
|
||||||
if (typeof window !== "undefined" && window.opera)
|
if (window.opera)
|
||||||
{
|
{
|
||||||
PLATFORM_ENGINE = CPOperaBrowserEngine;
|
PLATFORM_ENGINE = CPOperaBrowserEngine;
|
||||||
|
|
||||||
@@ -86,7 +85,7 @@ if (typeof window !== "undefined" && window.opera)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Internet Explorer
|
// Internet Explorer
|
||||||
else if (typeof window !== "undefined" && window.attachEvent) // Must follow Opera check.
|
else if (window.attachEvent) // Must follow Opera check.
|
||||||
{
|
{
|
||||||
PLATFORM_ENGINE = CPInternetExplorerBrowserEngine;
|
PLATFORM_ENGINE = CPInternetExplorerBrowserEngine;
|
||||||
|
|
||||||
@@ -123,7 +122,7 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
|
|||||||
majorVersion = parseInt(versionString.substring(0, versionDivision)),
|
majorVersion = parseInt(versionString.substring(0, versionDivision)),
|
||||||
minorVersion = parseInt(versionString.substr(versionDivision + 1));
|
minorVersion = parseInt(versionString.substr(versionDivision + 1));
|
||||||
|
|
||||||
if ((USER_AGENT.indexOf("Safari") !== CPNotFound && (majorVersion > 525 || (majorVersion === 525 && minorVersion > 14))) || USER_AGENT.indexOf("Chrome") !== CPNotFound)
|
if((USER_AGENT.indexOf("Safari") !== CPNotFound && (majorVersion > 525 || (majorVersion === 525 && minorVersion > 14))) || USER_AGENT.indexOf("Chrome") !== CPNotFound)
|
||||||
PLATFORM_FEATURES |= CPJavascriptRemedialKeySupport;
|
PLATFORM_FEATURES |= CPJavascriptRemedialKeySupport;
|
||||||
|
|
||||||
// FIXME this is a terrible hack to get around this bug:
|
// FIXME this is a terrible hack to get around this bug:
|
||||||
|
|||||||
+30
-142
@@ -23,8 +23,9 @@
|
|||||||
@import "CPFont.j"
|
@import "CPFont.j"
|
||||||
@import "CPShadow.j"
|
@import "CPShadow.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
@import "CPKeyValueBinding.j"
|
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
CPLeftTextAlignment = 0;
|
CPLeftTextAlignment = 0;
|
||||||
CPRightTextAlignment = 1;
|
CPRightTextAlignment = 1;
|
||||||
@@ -125,36 +126,6 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
@"max-size"]];
|
@"max-size"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)initialize
|
|
||||||
{
|
|
||||||
if (self === [CPControl class])
|
|
||||||
{
|
|
||||||
[self exposeBinding:@"value"];
|
|
||||||
[self exposeBinding:@"objectValue"];
|
|
||||||
[self exposeBinding:@"stringValue"];
|
|
||||||
[self exposeBinding:@"integerValue"];
|
|
||||||
[self exposeBinding:@"intValue"];
|
|
||||||
[self exposeBinding:@"doubleValue"];
|
|
||||||
[self exposeBinding:@"floatValue"];
|
|
||||||
|
|
||||||
[self exposeBinding:@"enabled"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_reverseSetBinding
|
|
||||||
{
|
|
||||||
var theBinding = [CPKeyValueBinding getBinding:CPValueBinding forObject:self];
|
|
||||||
[theBinding reverseSetValueFor:@"objectValue"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_replacementKeyPathForBinding:(CPString)aBinding
|
|
||||||
{
|
|
||||||
if (aBinding === @"value")
|
|
||||||
return @"objectValue";
|
|
||||||
|
|
||||||
return [super _replacementKeyPathForBinding:aBinding];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
@@ -209,7 +180,6 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
*/
|
*/
|
||||||
- (void)sendAction:(SEL)anAction to:(id)anObject
|
- (void)sendAction:(SEL)anAction to:(id)anObject
|
||||||
{
|
{
|
||||||
[self _reverseSetBinding];
|
|
||||||
[CPApp sendAction:anAction to:anObject from:self];
|
[CPApp sendAction:anAction to:anObject from:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +248,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
- (void)trackMouse:(CPEvent)anEvent
|
- (void)trackMouse:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var type = [anEvent type],
|
var type = [anEvent type],
|
||||||
currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||||
isWithinFrame = [self tracksMouseOutsideOfFrame] || CGRectContainsPoint([self bounds], currentLocation);
|
isWithinFrame = [self tracksMouseOutsideOfFrame] || CGRectContainsPoint([self bounds], currentLocation);
|
||||||
|
|
||||||
if (type === CPLeftMouseUp)
|
if (type === CPLeftMouseUp)
|
||||||
@@ -287,6 +257,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
|
|
||||||
_trackingMouseDownFlags = 0;
|
_trackingMouseDownFlags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (type === CPLeftMouseDown)
|
if (type === CPLeftMouseDown)
|
||||||
@@ -329,24 +300,11 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
|
|
||||||
- (void)performClick:(id)sender
|
- (void)performClick:(id)sender
|
||||||
{
|
{
|
||||||
if (![self isEnabled])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self highlight:YES];
|
[self highlight:YES];
|
||||||
[self setState:[self nextState]];
|
[self setState:[self nextState]];
|
||||||
|
[self sendAction:[self action] to:[self target]];
|
||||||
|
|
||||||
try
|
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(unhighlightButtonTimerDidFinish:) userInfo:nil repeats:NO];
|
||||||
{
|
|
||||||
[self sendAction:[self action] to:[self target]];
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(unhighlightButtonTimerDidFinish:) userInfo:nil repeats:NO];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)unhighlightButtonTimerDidFinish:(id)sender
|
- (void)unhighlightButtonTimerDidFinish:(id)sender
|
||||||
@@ -472,7 +430,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the receiver's string value
|
Returns the receiver's int value
|
||||||
*/
|
*/
|
||||||
- (CPString)stringValue
|
- (CPString)stringValue
|
||||||
{
|
{
|
||||||
@@ -480,7 +438,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Set's the receiver's string value
|
Set's the receiver's int value
|
||||||
*/
|
*/
|
||||||
- (void)setStringValue:(CPString)anObject
|
- (void)setStringValue:(CPString)anObject
|
||||||
{
|
{
|
||||||
@@ -530,7 +488,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
- (void)textDidBeginEditing:(CPNotification)note
|
- (void)textDidBeginEditing:(CPNotification)note
|
||||||
{
|
{
|
||||||
//this looks to prevent false propagation of notifications for other objects
|
//this looks to prevent false propagation of notifications for other objects
|
||||||
if ([note object] != self)
|
if([note object] != self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
||||||
@@ -539,7 +497,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
- (void)textDidChange:(CPNotification)note
|
- (void)textDidChange:(CPNotification)note
|
||||||
{
|
{
|
||||||
//this looks to prevent false propagation of notifications for other objects
|
//this looks to prevent false propagation of notifications for other objects
|
||||||
if ([note object] != self)
|
if([note object] != self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
||||||
@@ -548,103 +506,33 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
- (void)textDidEndEditing:(CPNotification)note
|
- (void)textDidEndEditing:(CPNotification)note
|
||||||
{
|
{
|
||||||
//this looks to prevent false propagation of notifications for other objects
|
//this looks to prevent false propagation of notifications for other objects
|
||||||
if ([note object] != self)
|
if([note object] != self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[self _reverseSetBinding];
|
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAlignment:(CPTextAlignment)alignment
|
#define BRIDGE(UPPERCASE, LOWERCASE, ATTRIBUTENAME) \
|
||||||
{
|
/*! Sets the value for ATTRIBUTENAME */\
|
||||||
[self setValue:alignment forThemeAttribute:@"alignment"];
|
- (void)set##UPPERCASE:(id)aValue\
|
||||||
|
{\
|
||||||
|
[self setValue:aValue forThemeAttribute:ATTRIBUTENAME];\
|
||||||
|
}\
|
||||||
|
/*! Returns the current value for ATTRIBUTENAME */\
|
||||||
|
- (id)LOWERCASE\
|
||||||
|
{\
|
||||||
|
return [self valueForThemeAttribute:ATTRIBUTENAME];\
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPTextAlignment)alignment
|
BRIDGE(Alignment, alignment, "alignment")
|
||||||
{
|
BRIDGE(VerticalAlignment, verticalAlignment, "vertical-alignment")
|
||||||
return [self valueForThemeAttribute:@"alignment"];
|
BRIDGE(LineBreakMode, lineBreakMode, "line-break-mode")
|
||||||
}
|
BRIDGE(TextColor, textColor, "text-color")
|
||||||
|
BRIDGE(Font, font, "font")
|
||||||
- (void)setVerticalAlignment:(CPTextVerticalAlignment)alignment
|
BRIDGE(TextShadowColor, textShadowColor, "text-shadow-color")
|
||||||
{
|
BRIDGE(TextShadowOffset, textShadowOffset, "text-shadow-offset")
|
||||||
[self setValue:alignment forThemeAttribute:@"vertical-alignment"];
|
BRIDGE(ImagePosition, imagePosition, "image-position")
|
||||||
}
|
BRIDGE(ImageScaling, imageScaling, "image-scaling")
|
||||||
|
|
||||||
- (CPTextVerticalAlignment)verticalAlignment
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"vertical-alignment"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setLineBreakMode:(CPLineBreakMode)mode
|
|
||||||
{
|
|
||||||
[self setValue:mode forThemeAttribute:@"line-break-mode"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPLineBreakMode)lineBreakMode
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"line-break-mode"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setTextColor:(CPColor)aColor
|
|
||||||
{
|
|
||||||
[self setValue:aColor forThemeAttribute:@"text-color"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPColor)textColor
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"text-color"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setTextShadowColor:(CPColor)aColor
|
|
||||||
{
|
|
||||||
[self setValue:aColor forThemeAttribute:@"text-shadow-color"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPColor)textShadowColor
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"text-shadow-color"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setTextShadowOffset:(float)offset
|
|
||||||
{
|
|
||||||
[self setValue:offset forThemeAttribute:@"text-shadow-offset"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (float)textShadowOffset
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"text-shadow-offset"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setFont:(CPFont)aFont
|
|
||||||
{
|
|
||||||
[self setValue:aFont forThemeAttribute:@"font"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPFont)font
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"font"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setImagePosition:(CPCellImagePosition)position
|
|
||||||
{
|
|
||||||
[self setValue:position forThemeAttribute:@"image-position"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPCellImagePosition)imagePosition
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"image-position"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setImageScaling:(CPImageScaling)scaling
|
|
||||||
{
|
|
||||||
[self setValue:scaling forThemeAttribute:@"image-scaling"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPImageScaling)imageScaling
|
|
||||||
{
|
|
||||||
return [self valueForThemeAttribute:@"image-scaling"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setEnabled:(BOOL)isEnabled
|
- (void)setEnabled:(BOOL)isEnabled
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
//
|
|
||||||
// CPController.j
|
|
||||||
// AppKit
|
|
||||||
//
|
|
||||||
// Created by Ross Boucher 1/15/09
|
|
||||||
// Copyright 280 North
|
|
||||||
//
|
|
||||||
// Adapted from GNUStep
|
|
||||||
// Copyright (C) 2007 Free Software Foundation, Inc
|
|
||||||
// Released under the LGPL.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
|
||||||
|
|
||||||
var CPControllerDeclaredKeysKey = @"CPControllerDeclaredKeysKey";
|
|
||||||
|
|
||||||
@implementation CPController : CPObject
|
|
||||||
{
|
|
||||||
CPArray _editors;
|
|
||||||
CPArray _declaredKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)init
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_editors = [];
|
|
||||||
_declaredKeys = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
if ([_declaredKeys count] > 0)
|
|
||||||
[aCoder encodeObject:_declaredKeys forKey:CPControllerDeclaredKeysKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithCoder:(CPCoder)aDecoder
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_editors = [];
|
|
||||||
_declaredKeys = [aDecoder decodeObjectForKey:CPControllerDeclaredKeysKey] || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isEditing
|
|
||||||
{
|
|
||||||
return [_editors count] > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)commitEditing
|
|
||||||
{
|
|
||||||
var index = 0,
|
|
||||||
count = _editors.length;
|
|
||||||
|
|
||||||
for (; index < count; ++index)
|
|
||||||
if (![[_editors objectAtIndex:i] commitEditing])
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)discardEditing
|
|
||||||
{
|
|
||||||
[_editors makeObjectsPerformSelector:@selector(discardEditing)];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)objectDidBeginEditing:(id)anEditor
|
|
||||||
{
|
|
||||||
[_editors addObject:anEditor];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)objectDidEndEditing:(id)anEditor
|
|
||||||
{
|
|
||||||
[_editors removeObject:anEditor];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
+13
-22
@@ -83,39 +83,30 @@
|
|||||||
*/
|
*/
|
||||||
- (void)setValue:(CPString)value expires:(CPDate)date domain:(CPString)domain
|
- (void)setValue:(CPString)value expires:(CPDate)date domain:(CPString)domain
|
||||||
{
|
{
|
||||||
if (date)
|
if(date)
|
||||||
var expires = "; expires=" + date.toGMTString();
|
var expires = "; expires="+date.toGMTString();
|
||||||
else
|
else
|
||||||
var expires = "";
|
var expires = "";
|
||||||
|
|
||||||
if (domain)
|
if(domain)
|
||||||
domain = "; domain=" + domain;
|
domain = "; domain="+domain;
|
||||||
else
|
else
|
||||||
domain = "";
|
domain = "";
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
document.cookie = _cookieName+"="+value+expires+"; path=/"+domain;
|
||||||
document.cookie = _cookieName+"="+value+expires+"; path=/"+domain;
|
|
||||||
#else
|
|
||||||
_cookieValue = value;
|
|
||||||
_expires = expires;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @ignore */
|
/* @ignore */
|
||||||
- (CPString)_readCookieValue
|
- (CPString)_readCookieValue
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
var nameEQ = _cookieName + "=";
|
||||||
var nameEQ = _cookieName + "=",
|
var ca = document.cookie.split(';');
|
||||||
ca = document.cookie.split(';');
|
for(var i=0;i < ca.length;i++) {
|
||||||
|
var c = ca[i];
|
||||||
for (var i = 0; i < ca.length; i++)
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||||
{
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||||
var c = ca[i];
|
}
|
||||||
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
|
return "";
|
||||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+5
-10
@@ -12,7 +12,7 @@ Implemented class methods:
|
|||||||
Opera : All except resizeLeftRightCursor resizeUpDownCursor operationNotAllowedCursor dragCopyCursor dragLinkCursor contextualMenuCursor openHandCursor closedHandCursor disappearingItemCursor // Opera does not support url cursors so these won't work with images
|
Opera : All except resizeLeftRightCursor resizeUpDownCursor operationNotAllowedCursor dragCopyCursor dragLinkCursor contextualMenuCursor openHandCursor closedHandCursor disappearingItemCursor // Opera does not support url cursors so these won't work with images
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
var currentCursor = nil,
|
var currentCursor = nil,
|
||||||
cursorStack = [],
|
cursorStack = [],
|
||||||
@@ -167,9 +167,7 @@ var currentCursor = nil,
|
|||||||
{
|
{
|
||||||
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
|
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
|
||||||
return [CPCursor cursorWithCSSString:@"-webkit-grab"];
|
return [CPCursor cursorWithCSSString:@"-webkit-grab"];
|
||||||
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
|
else if (CPBrowserIsEngine(CPGeckoBrowserEngine) || CPBrowserIsEngine(CPOperaBrowserEngine))
|
||||||
return [CPCursor cursorWithCSSString:@"-moz-grab"];
|
|
||||||
else if (CPBrowserIsEngine(CPOperaBrowserEngine))
|
|
||||||
return [CPCursor cursorWithCSSString:@"move"];
|
return [CPCursor cursorWithCSSString:@"move"];
|
||||||
|
|
||||||
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only. move in FFMac|Opera
|
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only. move in FFMac|Opera
|
||||||
@@ -179,10 +177,8 @@ var currentCursor = nil,
|
|||||||
{
|
{
|
||||||
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
|
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
|
||||||
return [CPCursor cursorWithCSSString:@"-webkit-grabbing"];
|
return [CPCursor cursorWithCSSString:@"-webkit-grabbing"];
|
||||||
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
|
|
||||||
return [CPCursor cursorWithCSSString:@"-moz-grabbing"];
|
|
||||||
|
|
||||||
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit || FF
|
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPCursor)disappearingItemCursor
|
+ (CPCursor)disappearingItemCursor
|
||||||
@@ -197,7 +193,7 @@ var currentCursor = nil,
|
|||||||
|
|
||||||
+ (void)unhide
|
+ (void)unhide
|
||||||
{
|
{
|
||||||
[self _setCursorCSS:[currentCursor _cssString]];
|
[self _setCursorCSS:[currentCursor _cssString]]
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)setHiddenUntilMouseMoves:(BOOL)flag
|
+ (void)setHiddenUntilMouseMoves:(BOOL)flag
|
||||||
@@ -210,10 +206,9 @@ var currentCursor = nil,
|
|||||||
|
|
||||||
- (id)initWithImage:(CPImage)image hotSpot:(CPPoint)hotSpot
|
- (id)initWithImage:(CPImage)image hotSpot:(CPPoint)hotSpot
|
||||||
{
|
{
|
||||||
return [self initWithCSSString:"url(" + [image filename] + "), auto"];
|
return [self initWithCSSString:"url(" + [image filename] + ")"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)mouseEntered:(CPEvent)event
|
- (void)mouseEntered:(CPEvent)event
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-8
@@ -23,7 +23,6 @@
|
|||||||
@import <Foundation/CPString.j>
|
@import <Foundation/CPString.j>
|
||||||
@import <Foundation/CPArray.j>
|
@import <Foundation/CPArray.j>
|
||||||
|
|
||||||
@import "CPApplication.j"
|
|
||||||
@import "CPResponder.j"
|
@import "CPResponder.j"
|
||||||
@import "CPSavePanel.j"
|
@import "CPSavePanel.j"
|
||||||
@import "CPViewController.j"
|
@import "CPViewController.j"
|
||||||
@@ -211,10 +210,10 @@ var CPDocumentUntitledCount = 0;
|
|||||||
@throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass
|
@throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass
|
||||||
@return the document data
|
@return the document data
|
||||||
*/
|
*/
|
||||||
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
|
- (CPData)dataOfType:(CPString)aType
|
||||||
{
|
{
|
||||||
[CPException raise:CPUnsupportedMethodException
|
[CPException raise:CPUnsupportedMethodException
|
||||||
reason:"dataOfType:error: must be overridden by the document subclass."];
|
reason:"dataOfType: must be overridden by the document subclass."];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -386,10 +385,10 @@ var CPDocumentUntitledCount = 0;
|
|||||||
if (!_untitledDocumentIndex)
|
if (!_untitledDocumentIndex)
|
||||||
_untitledDocumentIndex = ++CPDocumentUntitledCount;
|
_untitledDocumentIndex = ++CPDocumentUntitledCount;
|
||||||
|
|
||||||
if (_untitledDocumentIndex == 1)
|
if (_untitledDocumentIndex == 1)
|
||||||
return @"Untitled";
|
return @"Untitled";
|
||||||
|
|
||||||
return @"Untitled " + _untitledDocumentIndex;
|
return @"Untitled " + _untitledDocumentIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPString)viewCibName
|
- (CPString)viewCibName
|
||||||
@@ -474,8 +473,21 @@ var CPDocumentUntitledCount = 0;
|
|||||||
*/
|
*/
|
||||||
- (void)saveToURL:(CPURL)anAbsoluteURL ofType:(CPString)aTypeName forSaveOperation:(CPSaveOperationType)aSaveOperation delegate:(id)aDelegate didSaveSelector:(SEL)aDidSaveSelector contextInfo:(id)aContextInfo
|
- (void)saveToURL:(CPURL)anAbsoluteURL ofType:(CPString)aTypeName forSaveOperation:(CPSaveOperationType)aSaveOperation delegate:(id)aDelegate didSaveSelector:(SEL)aDidSaveSelector contextInfo:(id)aContextInfo
|
||||||
{
|
{
|
||||||
var data = [self dataOfType:[self fileType] error:nil],
|
if (anAbsoluteURL.isLocalStorageURL())
|
||||||
oldChangeCount = _changeCount;
|
[[CPDocumentController sharedDocumentController] _addLocalDocumentURL:anAbsoluteURL];
|
||||||
|
|
||||||
|
var data = nil;
|
||||||
|
|
||||||
|
if ([self respondsToSelector:@selector(dataOfType:error:)])
|
||||||
|
{
|
||||||
|
CPLog.warn("[" + CPStringFromClass([self class]) + " " + CPStringFromSelector(@selector(dataOfType:error:)) + "] is deprecated, please implement " + CPStringFromSelector(@selector(dataOfType:)) + " instead and simply throw exceptions when necessary.");
|
||||||
|
|
||||||
|
data = [self dataOfType:[self fileType] error:nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data = [self dataOfType:[self fileType]];
|
||||||
|
|
||||||
|
var oldChangeCount = _changeCount;
|
||||||
|
|
||||||
_writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL];
|
_writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL];
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ var CPSharedDocumentController = nil;
|
|||||||
{
|
{
|
||||||
CPArray _documents;
|
CPArray _documents;
|
||||||
CPArray _documentTypes;
|
CPArray _documentTypes;
|
||||||
|
CPArray _localDocumentURLs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -62,11 +63,27 @@ var CPSharedDocumentController = nil;
|
|||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_documents = [[CPArray alloc] init];
|
|
||||||
|
|
||||||
if (!CPSharedDocumentController)
|
if (!CPSharedDocumentController)
|
||||||
CPSharedDocumentController = self;
|
CPSharedDocumentController = self;
|
||||||
|
|
||||||
|
_localDocumentURLs = [CPSet set];
|
||||||
|
|
||||||
|
if (window.localStorage)
|
||||||
|
{
|
||||||
|
var localDocumentURLs = localStorage.getItem(CPDocumentControllerLocalDocumentURLsKey);
|
||||||
|
|
||||||
|
if (localDocumentURLs)
|
||||||
|
{
|
||||||
|
localDocumentURLs = JSON.parse(localDocumentURLs);
|
||||||
|
|
||||||
|
var count = [localDocumentURLs count];
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
[_localDocumentURLs addObject:new CFURL(localDocumentURLs[count])];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_documents = [];
|
||||||
_documentTypes = [[[CPBundle mainBundle] infoDictionary] objectForKey:@"CPBundleDocumentTypes"];
|
_documentTypes = [[[CPBundle mainBundle] infoDictionary] objectForKey:@"CPBundleDocumentTypes"];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -86,15 +103,15 @@ var CPSharedDocumentController = nil;
|
|||||||
var index = 0,
|
var index = 0,
|
||||||
count = [_documents count];
|
count = [_documents count];
|
||||||
|
|
||||||
for (; index < count; ++index)
|
for (; index < count; ++index)
|
||||||
{
|
{
|
||||||
var theDocument = _documents[index];
|
var theDocument = _documents[index];
|
||||||
|
|
||||||
if ([[theDocument fileURL] isEqual:aURL])
|
if ([[theDocument fileURL] isEqual:aURL])
|
||||||
return theDocument;
|
return theDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -219,12 +236,12 @@ var CPSharedDocumentController = nil;
|
|||||||
Opens a new document in the application.
|
Opens a new document in the application.
|
||||||
@param aSender the requesting object
|
@param aSender the requesting object
|
||||||
*/
|
*/
|
||||||
- (CFAction)newDocument:(id)aSender
|
- (@action)newDocument:(id)aSender
|
||||||
{
|
{
|
||||||
[self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES];
|
[self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)openDocument:(id)aSender
|
-(void)openDocument:(id)aSender
|
||||||
{
|
{
|
||||||
var openPanel = [CPOpenPanel openPanel];
|
var openPanel = [CPOpenPanel openPanel];
|
||||||
|
|
||||||
@@ -455,3 +472,41 @@ var CPSharedDocumentController = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
var CPDocumentControllerLocalDocumentURLsKey = @"Cappuccino.CPDocumentController.documentURLs";
|
||||||
|
|
||||||
|
@implementation CPDocumentController (LocalStorage)
|
||||||
|
|
||||||
|
- (void)_addLocalDocumentURL:(CPURL)aURL
|
||||||
|
{
|
||||||
|
if (!window.localStorage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
[_localDocumentURLs addObject:aURL];
|
||||||
|
|
||||||
|
var stringURLs = [],
|
||||||
|
URL = nil,
|
||||||
|
URLEnumerator = [_localDocumentURLs objectEnumerator];
|
||||||
|
|
||||||
|
while (URL = [URLEnumerator nextObject])
|
||||||
|
stringURLs.push(URL + "");
|
||||||
|
|
||||||
|
localStorage.setItem(CPDocumentControllerLocalDocumentURLsKey, JSON.stringify(stringURLs));
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_removeLocalDocumentURL:(CPURL)aURL
|
||||||
|
{
|
||||||
|
if (!window.localStorage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
[_localDocumentURLs removeObject:aURL];
|
||||||
|
|
||||||
|
localStorage.setItem(CPDocumentControllerLocalDocumentURLsKey, JSON.stringify([self allObjects]));
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPSet)localDocumentURLs
|
||||||
|
{
|
||||||
|
return [_localDocumentURLs copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|||||||
+36
-98
@@ -20,12 +20,13 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPApplication.j"
|
@import <AppKit/CPView.j>
|
||||||
@import "CPEvent.j"
|
@import <AppKit/CPEvent.j>
|
||||||
@import "CPImageView.j"
|
@import <AppKit/CPPasteboard.j>
|
||||||
@import "CPPasteboard.j"
|
@import <AppKit/CPImageView.j>
|
||||||
@import "CPView.j"
|
|
||||||
@import "CPWindow.j"
|
#import "CoreGraphics/CGGeometry.h"
|
||||||
|
#import "Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
CPDragOperationNone = 0,
|
CPDragOperationNone = 0,
|
||||||
@@ -39,10 +40,29 @@ CPDragOperationEvery = -1;
|
|||||||
|
|
||||||
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
|
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
|
||||||
|
|
||||||
var CPDragServerPreviousEvent = nil,
|
var CPDragServerPreviousEvent = nil,
|
||||||
CPDragServerPeriodicUpdateInterval = 0.05;
|
CPDragServerAutoscrollInterval = nil;
|
||||||
|
/*
|
||||||
|
var CPDragServerAutoscroll = function()
|
||||||
|
{
|
||||||
|
[CPDragServerSource autoscroll:CPDragServerPreviousEvent];
|
||||||
|
}
|
||||||
|
|
||||||
var CPSharedDragServer = nil;
|
if (CPDragServerAutoscrollInterval === nil)
|
||||||
|
{
|
||||||
|
if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)])
|
||||||
|
CPDragServerAutoscrollInterval = setInterval(CPDragServerAutoscroll, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPDragServerPreviousEvent = anEvent;
|
||||||
|
|
||||||
|
if (CPDragServerAutoscrollInterval !== nil)
|
||||||
|
clearInterval(CPDragServerAutoscrollInterval);
|
||||||
|
|
||||||
|
CPDragServerAutoscrollInterval = nil;
|
||||||
|
*/
|
||||||
|
|
||||||
|
var CPSharedDragServer = nil;
|
||||||
|
|
||||||
var CPDragServerSource = nil;
|
var CPDragServerSource = nil;
|
||||||
var CPDragServerDraggingInfo = nil;
|
var CPDragServerDraggingInfo = nil;
|
||||||
@@ -130,13 +150,10 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
|||||||
|
|
||||||
CGPoint _draggingLocation;
|
CGPoint _draggingLocation;
|
||||||
id _draggingDestination;
|
id _draggingDestination;
|
||||||
BOOL _draggingDestinationWantsPeriodicUpdates;
|
|
||||||
|
|
||||||
CGPoint _startDragLocation;
|
CGPoint _startDragLocation;
|
||||||
BOOL _shouldSlideBack;
|
BOOL _shouldSlideBack;
|
||||||
unsigned _dragOperation;
|
unsigned _dragOperation;
|
||||||
|
|
||||||
CPTimer _draggingUpdateTimer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -217,9 +234,6 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
|||||||
|
|
||||||
- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
|
- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
|
||||||
{
|
{
|
||||||
[_draggingUpdateTimer invalidate];
|
|
||||||
_draggingUpdateTimer = nil;
|
|
||||||
|
|
||||||
var dragOperation = CPDragOperationCopy;
|
var dragOperation = CPDragOperationCopy;
|
||||||
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
|
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
|
||||||
var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
|
var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
|
||||||
@@ -229,89 +243,25 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
|||||||
|
|
||||||
if(draggingDestination !== _draggingDestination)
|
if(draggingDestination !== _draggingDestination)
|
||||||
{
|
{
|
||||||
if ([_draggingDestination respondsToSelector:@selector(draggingExited:)])
|
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingExited:)])
|
||||||
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
|
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
|
||||||
|
|
||||||
_draggingDestination = draggingDestination;
|
_draggingDestination = draggingDestination;
|
||||||
|
|
||||||
if ([_draggingDestination respondsToSelector:@selector(wantsPeriodicDraggingUpdates)])
|
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingEntered:)])
|
||||||
_draggingDestinationWantsPeriodicUpdates = [_draggingDestination wantsPeriodicDraggingUpdates];
|
|
||||||
else
|
|
||||||
_draggingDestinationWantsPeriodicUpdates = YES;
|
|
||||||
|
|
||||||
if ([_draggingDestination respondsToSelector:@selector(draggingEntered:)])
|
|
||||||
dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo];
|
dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo];
|
||||||
}
|
}
|
||||||
else if ([_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
|
else if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
|
||||||
dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo];
|
dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo];
|
||||||
|
|
||||||
if (!_draggingDestination)
|
if (!_draggingDestination)
|
||||||
dragOperation = CPDragOperationNone;
|
dragOperation = CPDragOperationNone;
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_draggingDestinationWantsPeriodicUpdates)
|
|
||||||
_draggingUpdateTimer = [CPTimer scheduledTimerWithTimeInterval:CPDragServerPeriodicUpdateInterval
|
|
||||||
target:self
|
|
||||||
selector:@selector(_sendPeriodicDraggingUpdate:)
|
|
||||||
userInfo:[CPDictionary dictionaryWithJSObject:{platformWindow:aPlatformWindow, location:aLocation}]
|
|
||||||
repeats:NO];
|
|
||||||
|
|
||||||
var scrollView = [_draggingDestination isKindOfClass:[CPView class]] ? [_draggingDestination enclosingScrollView] : nil;
|
|
||||||
if (scrollView)
|
|
||||||
{
|
|
||||||
var contentView = [scrollView contentView],
|
|
||||||
bounds = [contentView bounds],
|
|
||||||
insetBounds = CGRectInset(bounds, 10, 10),
|
|
||||||
eventLocation = [contentView convertPoint:_draggingLocation fromView:nil],
|
|
||||||
deltaX = 0,
|
|
||||||
deltaY = 0;
|
|
||||||
|
|
||||||
if (!CGRectContainsPoint(insetBounds, eventLocation))
|
|
||||||
{
|
|
||||||
if ([scrollView hasVerticalScroller])
|
|
||||||
{
|
|
||||||
if (eventLocation.y < CGRectGetMinY(insetBounds))
|
|
||||||
deltaY = CGRectGetMinY(insetBounds) - eventLocation.y;
|
|
||||||
else if (eventLocation.y > CGRectGetMaxY(insetBounds))
|
|
||||||
deltaY = CGRectGetMaxY(insetBounds) - eventLocation.y;
|
|
||||||
if (deltaY < -insetBounds.size.height)
|
|
||||||
deltaY = -insetBounds.size.height;
|
|
||||||
if (deltaY > insetBounds.size.height)
|
|
||||||
deltaY = insetBounds.size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([scrollView hasHorizontalScroller])
|
|
||||||
{
|
|
||||||
if (eventLocation.x < CGRectGetMinX(insetBounds))
|
|
||||||
deltaX = CGRectGetMinX(insetBounds) - eventLocation.x;
|
|
||||||
else if (eventLocation.x > CGRectGetMaxX(insetBounds))
|
|
||||||
deltaX = CGRectGetMaxX(insetBounds) - eventLocation.x;
|
|
||||||
if (deltaX < -insetBounds.size.width)
|
|
||||||
deltaX = -insetBounds.size.width;
|
|
||||||
if (deltaX > insetBounds.size.width)
|
|
||||||
deltaX = insetBounds.size.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
[contentView scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dragOperation;
|
return dragOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_sendPeriodicDraggingUpdate:(CPTimer)aTimer
|
|
||||||
{
|
|
||||||
var userInfo = [aTimer userInfo];
|
|
||||||
_dragOperation = [self draggingUpdatedInPlatformWindow:[userInfo objectForKey:@"platformWindow"]
|
|
||||||
location:[userInfo objectForKey:@"location"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow globalLocation:(CGPoint)aLocation operation:(CPDragOperation)anOperation
|
- (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow globalLocation:(CGPoint)aLocation operation:(CPDragOperation)anOperation
|
||||||
{
|
{
|
||||||
[_draggingUpdateTimer invalidate];
|
|
||||||
_draggingUpdateTimer = nil;
|
|
||||||
|
|
||||||
[_draggedView removeFromSuperview];
|
[_draggedView removeFromSuperview];
|
||||||
|
|
||||||
if (![CPPlatform supportsDragAndDrop])
|
if (![CPPlatform supportsDragAndDrop])
|
||||||
@@ -454,25 +404,13 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
|||||||
// Stop tracking events.
|
// Stop tracking events.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (type === CPKeyDown)
|
|
||||||
{
|
[self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation];
|
||||||
var keyCode = [anEvent keyCode];
|
_dragOperation = [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
|
||||||
if (keyCode === CPEscapeKeyCode)
|
|
||||||
{
|
|
||||||
_dragOperation = CPDragOperationNone;
|
|
||||||
[self draggingEndedInPlatformWindow:platformWindow globalLocation:CGPointMakeZero() operation:_dragOperation];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation];
|
|
||||||
_dragOperation = [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're not a mouse up, then we're going to want to grab the next event.
|
// If we're not a mouse up, then we're going to want to grab the next event.
|
||||||
[CPApp setTarget:self selector:@selector(trackDragging:)
|
[CPApp setTarget:self selector:@selector(trackDragging:)
|
||||||
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
|
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
|
||||||
untilDate:nil inMode:0 dequeue:NO];
|
untilDate:nil inMode:0 dequeue:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-150
@@ -21,7 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
@import "CPText.j"
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
CPLeftMouseDown = 1;
|
CPLeftMouseDown = 1;
|
||||||
@@ -52,6 +53,7 @@ CPTouchMove = 29;
|
|||||||
CPTouchEnd = 30;
|
CPTouchEnd = 30;
|
||||||
CPTouchCancel = 31;
|
CPTouchCancel = 31;
|
||||||
|
|
||||||
|
|
||||||
CPAlphaShiftKeyMask = 1 << 16;
|
CPAlphaShiftKeyMask = 1 << 16;
|
||||||
CPShiftKeyMask = 1 << 17;
|
CPShiftKeyMask = 1 << 17;
|
||||||
CPControlKeyMask = 1 << 18;
|
CPControlKeyMask = 1 << 18;
|
||||||
@@ -85,100 +87,24 @@ CPPeriodicMask = 1 << CPPeriodic;
|
|||||||
CPScrollWheelMask = 1 << CPScrollWheel;
|
CPScrollWheelMask = 1 << CPScrollWheel;
|
||||||
CPAnyEventMask = 0xffffffff;
|
CPAnyEventMask = 0xffffffff;
|
||||||
|
|
||||||
CPUpArrowFunctionKey = "\uF700";
|
CPDOMEventDoubleClick = "dblclick",
|
||||||
CPDownArrowFunctionKey = "\uF701";
|
CPDOMEventMouseDown = "mousedown",
|
||||||
CPLeftArrowFunctionKey = "\uF702";
|
CPDOMEventMouseUp = "mouseup",
|
||||||
CPRightArrowFunctionKey = "\uF703";
|
CPDOMEventMouseMoved = "mousemove",
|
||||||
CPF1FunctionKey = "\uF704";
|
CPDOMEventMouseDragged = "mousedrag",
|
||||||
CPF2FunctionKey = "\uF705";
|
CPDOMEventKeyUp = "keyup",
|
||||||
CPF3FunctionKey = "\uF706";
|
CPDOMEventKeyDown = "keydown",
|
||||||
CPF4FunctionKey = "\uF707";
|
CPDOMEventKeyPress = "keypress";
|
||||||
CPF5FunctionKey = "\uF708";
|
CPDOMEventCopy = "copy";
|
||||||
CPF6FunctionKey = "\uF709";
|
CPDOMEventPaste = "paste";
|
||||||
CPF7FunctionKey = "\uF70A";
|
CPDOMEventScrollWheel = "mousewheel";
|
||||||
CPF8FunctionKey = "\uF70B";
|
CPDOMEventTouchStart = "touchstart";
|
||||||
CPF9FunctionKey = "\uF70C";
|
CPDOMEventTouchMove = "touchmove";
|
||||||
CPF10FunctionKey = "\uF70D";
|
CPDOMEventTouchEnd = "touchend";
|
||||||
CPF11FunctionKey = "\uF70E";
|
CPDOMEventTouchCancel = "touchcancel";
|
||||||
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,
|
var _CPEventPeriodicEventPeriod = 0,
|
||||||
_CPEventPeriodicEventTimer = nil,
|
_CPEventPeriodicEventTimer = nil;
|
||||||
_CPEventUpperCaseRegex = new RegExp("[A-Z]");
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -519,69 +445,16 @@ var _CPEventPeriodicEventPeriod = 0,
|
|||||||
return _deltaZ;
|
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
|
- (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?
|
// FIXME: More cases? Space?
|
||||||
return NO;
|
return _type === CPKeyDown &&
|
||||||
|
_modifierFlags & (CPCommandKeyMask | CPControlKeyMask) &&
|
||||||
|
[_characters length] > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Gene rates periodic events every \c aPeriod seconds.
|
Generates periodic events every \c aPeriod seconds.
|
||||||
@param aDelay the number of seconds before the first event
|
@param aDelay the number of seconds before the first event
|
||||||
@param aPeriod the length of time in seconds between successive events
|
@param aPeriod the length of time in seconds between successive events
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPFlashMovie
|
@class CPFlashMovie
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
@import "CPFlashMovie.j"
|
@import "CPFlashMovie.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
||||||
|
|
||||||
|
|||||||
+1
-66
@@ -20,12 +20,6 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
|
||||||
@import <Foundation/CPBundle.j>
|
|
||||||
|
|
||||||
@import "CPView.j"
|
|
||||||
|
|
||||||
|
|
||||||
var _CPFonts = {},
|
var _CPFonts = {},
|
||||||
_CPFontSystemFontFace = @"Arial, sans-serif",
|
_CPFontSystemFontFace = @"Arial, sans-serif",
|
||||||
_CPWrapRegExp = new RegExp("\\s*,\\s*", "g");
|
_CPWrapRegExp = new RegExp("\\s*,\\s*", "g");
|
||||||
@@ -44,22 +38,11 @@ var _CPFonts = {},
|
|||||||
{
|
{
|
||||||
CPString _name;
|
CPString _name;
|
||||||
float _size;
|
float _size;
|
||||||
float _ascender;
|
|
||||||
float _descender;
|
|
||||||
float _lineHeight;
|
|
||||||
BOOL _isBold;
|
BOOL _isBold;
|
||||||
|
|
||||||
CPString _cssString;
|
CPString _cssString;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)initialize
|
|
||||||
{
|
|
||||||
var systemFont = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:"CPSystemFontFace"];
|
|
||||||
|
|
||||||
if (systemFont)
|
|
||||||
_CPFontSystemFontFace = systemFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a font with the specified name and size.
|
Returns a font with the specified name and size.
|
||||||
@param aName the name of the font
|
@param aName the name of the font
|
||||||
@@ -113,9 +96,6 @@ var _CPFonts = {},
|
|||||||
{
|
{
|
||||||
_name = aName;
|
_name = aName;
|
||||||
_size = aSize;
|
_size = aSize;
|
||||||
_ascender = 0;
|
|
||||||
_descender = 0;
|
|
||||||
_lineHeight = 0;
|
|
||||||
_isBold = isBold;
|
_isBold = isBold;
|
||||||
|
|
||||||
_cssString = _CPCreateCSSString(_name, _size, _isBold);
|
_cssString = _CPCreateCSSString(_name, _size, _isBold);
|
||||||
@@ -127,43 +107,7 @@ var _CPFonts = {},
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the distance of the longest ascender's top y-coordinate from the baseline (in CSS px)
|
Returns the font size (in points)
|
||||||
*/
|
|
||||||
- (float)ascender
|
|
||||||
{
|
|
||||||
if (!_ascender)
|
|
||||||
[self _getMetrics];
|
|
||||||
|
|
||||||
return _ascender;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the bottom y coordinate (in CSS px), offset from the baseline, of the receiver's longest descender.
|
|
||||||
Thus, if the longest descender extends 2 points below the baseline, descender will return –2.
|
|
||||||
*/
|
|
||||||
- (float)descender
|
|
||||||
{
|
|
||||||
if (!_descender)
|
|
||||||
[self _getMetrics];
|
|
||||||
|
|
||||||
return _descender;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the default line height.
|
|
||||||
|
|
||||||
NOTE: This was moved from NSFont to NSLayoutManager in Cocoa, but since there is no CPLayoutManager, it has been kept here.
|
|
||||||
*/
|
|
||||||
- (float)defaultLineHeightForFont
|
|
||||||
{
|
|
||||||
if (!_lineHeight)
|
|
||||||
[self _getMetrics];
|
|
||||||
|
|
||||||
return _lineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the font size (in CSS px)
|
|
||||||
*/
|
*/
|
||||||
- (float)size
|
- (float)size
|
||||||
{
|
{
|
||||||
@@ -196,15 +140,6 @@ var _CPFonts = {},
|
|||||||
return [CPString stringWithFormat:@"%@ %@ %f pt.", [super description], [self familyName], [self size]];
|
return [CPString stringWithFormat:@"%@ %@ %f pt.", [super description], [self familyName], [self size]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_getMetrics
|
|
||||||
{
|
|
||||||
var metrics = [CPString metricsOfFont:self];
|
|
||||||
|
|
||||||
_ascender = [metrics objectForKey:@"ascender"];
|
|
||||||
_descender = [metrics objectForKey:@"descender"];
|
|
||||||
_lineHeight = [metrics objectForKey:@"lineHeight"];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPFontNameKey = @"CPFontNameKey",
|
var CPFontNameKey = @"CPFontNameKey",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
@import "CPFont.j"
|
@import <AppKit/CPFont.j>
|
||||||
|
|
||||||
|
|
||||||
var CPSharedFontManager = nil,
|
var CPSharedFontManager = nil,
|
||||||
|
|||||||
+2
-16
@@ -222,8 +222,8 @@ function CPRectContainsPoint(aRect, aPoint)
|
|||||||
{
|
{
|
||||||
return aPoint.x >= CPRectGetMinX(aRect) &&
|
return aPoint.x >= CPRectGetMinX(aRect) &&
|
||||||
aPoint.y >= CPRectGetMinY(aRect) &&
|
aPoint.y >= CPRectGetMinY(aRect) &&
|
||||||
aPoint.x < CPRectGetMaxX(aRect) &&
|
aPoint.x < CPRectGetMaxX(aRect) &&
|
||||||
aPoint.y < CPRectGetMaxY(aRect);
|
aPoint.y < CPRectGetMaxY(aRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -380,20 +380,6 @@ function CPRectIsNull(aRect)
|
|||||||
return aRect.size.width <= 0.0 || aRect.size.height <= 0.0;
|
return aRect.size.width <= 0.0 || aRect.size.height <= 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Creates two rectangles -- slice and rem -- from inRect, by dividing inRect
|
|
||||||
with a line that's parallel to the side of inRect specified by edge.
|
|
||||||
The size of slice is determined by amount, which specifies the distance from edge.
|
|
||||||
|
|
||||||
slice and rem must not be NULL.
|
|
||||||
|
|
||||||
@group CGRect
|
|
||||||
*/
|
|
||||||
function CPDivideRect(inRect, slice, rem, amount, edge)
|
|
||||||
{
|
|
||||||
CGRectDivide(inRect, slice, rem, amount, edge);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns \c YES if the two CGSizes are identical.
|
Returns \c YES if the two CGSizes are identical.
|
||||||
@group CGSize
|
@group CGSize
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* CPGraphics.j
|
|
||||||
* AppKit
|
|
||||||
*
|
|
||||||
* Created by Francisco Tolmasky.
|
|
||||||
* 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 "CPColor.j"
|
|
||||||
@import "CPGraphicsContext.j"
|
|
||||||
|
|
||||||
|
|
||||||
function CPDrawTiledRects(
|
|
||||||
/* CGRect */ boundsRect,
|
|
||||||
/* CGRect */ clipRect,
|
|
||||||
/* CPRectEdge[] */ sides,
|
|
||||||
/* float[] */ grays)
|
|
||||||
{
|
|
||||||
if (sides.length != grays.length)
|
|
||||||
[CPException raise:CPInvalidArgumentException reason:@"sides (length: " + sides.length + ") and grays (length: " + grays.length + ") must have the same length."];
|
|
||||||
|
|
||||||
var colors = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < grays.length; ++i)
|
|
||||||
colors.push([CPColor colorWithCalibratedWhite:grays[i] alpha:1.0]);
|
|
||||||
|
|
||||||
return CPDrawColorTiledRects(boundsRect, clipRect, sides, colors);
|
|
||||||
}
|
|
||||||
|
|
||||||
function CPDrawColorTiledRects(
|
|
||||||
/* CGRect */ boundsRect,
|
|
||||||
/* CGRect */ clipRect,
|
|
||||||
/* CPRectEdge[] */ sides,
|
|
||||||
/* CPColor[] */ colors)
|
|
||||||
{
|
|
||||||
if (sides.length != colors.length)
|
|
||||||
[CPException raise:CPInvalidArgumentException reason:@"sides (length: " + sides.length + ") and colors (length: " + colors.length + ") must have the same length."];
|
|
||||||
|
|
||||||
var resultRect = _CGRectMakeCopy(boundsRect),
|
|
||||||
slice = _CGRectMakeZero(),
|
|
||||||
remainder = _CGRectMakeZero(),
|
|
||||||
context = [[CPGraphicsContext currentContext] graphicsPort];
|
|
||||||
|
|
||||||
CGContextSaveGState(context);
|
|
||||||
CGContextSetLineWidth(context, 1.0);
|
|
||||||
|
|
||||||
for (var sideIndex = 0; sideIndex < sides.length; ++sideIndex)
|
|
||||||
{
|
|
||||||
var side = sides[sideIndex];
|
|
||||||
|
|
||||||
CGRectDivide(resultRect, slice, remainder, 1.0, side);
|
|
||||||
resultRect = remainder;
|
|
||||||
slice = CGRectIntersection(slice, clipRect);
|
|
||||||
|
|
||||||
// Cocoa docs say that only slices that are within the clipRect are actually drawn
|
|
||||||
if (_CGRectIsEmpty(slice))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var minX, maxX, minY, maxY;
|
|
||||||
|
|
||||||
if (side == CPMinXEdge || side == CPMaxXEdge)
|
|
||||||
{
|
|
||||||
// Make sure we have at least 1 pixel to draw a line
|
|
||||||
if (_CGRectGetWidth(slice) < 1.0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
minX = _CGRectGetMinX(slice) + 0.5;
|
|
||||||
maxX = minX;
|
|
||||||
minY = _CGRectGetMinY(slice);
|
|
||||||
maxY = _CGRectGetMaxY(slice);
|
|
||||||
}
|
|
||||||
else // CPMinYEdge || CPMaxYEdge
|
|
||||||
{
|
|
||||||
// Make sure we have at least 1 pixel to draw a line
|
|
||||||
if (_CGRectGetHeight(slice) < 1.0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
minX = _CGRectGetMinX(slice);
|
|
||||||
maxX = _CGRectGetMaxX(slice);
|
|
||||||
minY = _CGRectGetMinY(slice) + 0.5;
|
|
||||||
maxY = minY;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextMoveToPoint(context, minX, minY);
|
|
||||||
CGContextAddLineToPoint(context, maxX, maxY);
|
|
||||||
CGContextSetStrokeColor(context, colors[sideIndex]);
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
CGContextRestoreGState(context);
|
|
||||||
|
|
||||||
return resultRect;
|
|
||||||
}
|
|
||||||
@@ -20,11 +20,6 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
|
||||||
|
|
||||||
@import "CGContext.j"
|
|
||||||
|
|
||||||
|
|
||||||
var CPGraphicsContextCurrent = nil;
|
var CPGraphicsContextCurrent = nil;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
+6
-9
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
@import "CPGeometry.j"
|
@import "CPGeometry.j"
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
CPImageLoadStatusInitialized = 0;
|
CPImageLoadStatusInitialized = 0;
|
||||||
CPImageLoadStatusLoading = 1;
|
CPImageLoadStatusLoading = 1;
|
||||||
@@ -191,9 +193,6 @@ function CPAppKitImage(aFilename, aSize)
|
|||||||
|
|
||||||
var imageOrSize = AppKitImageForNames[aName];
|
var imageOrSize = AppKitImageForNames[aName];
|
||||||
|
|
||||||
if (!imageOrSize)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
if (!imageOrSize.isa)
|
if (!imageOrSize.isa)
|
||||||
{
|
{
|
||||||
imageOrSize = CPAppKitImage("CPImage/" + aName + ".png", imageOrSize);
|
imageOrSize = CPAppKitImage("CPImage/" + aName + ".png", imageOrSize);
|
||||||
@@ -206,19 +205,17 @@ function CPAppKitImage(aFilename, aSize)
|
|||||||
return imageOrSize;
|
return imageOrSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)setName:(CPString)aName
|
- (void)setName:(CPString)aName
|
||||||
{
|
{
|
||||||
if (_name === aName)
|
if (_name === aName)
|
||||||
return YES;
|
return;
|
||||||
|
|
||||||
if (imagesForNames[aName])
|
if (imagesForNames[aName] === self)
|
||||||
return NO;
|
imagesForNames[aName] = nil;
|
||||||
|
|
||||||
_name = aName;
|
_name = aName;
|
||||||
|
|
||||||
imagesForNames[aName] = self;
|
imagesForNames[aName] = self;
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPString)name
|
- (CPString)name
|
||||||
|
|||||||
+18
-99
@@ -26,23 +26,16 @@
|
|||||||
@import "CPImage.j"
|
@import "CPImage.j"
|
||||||
@import "CPShadowView.j"
|
@import "CPShadowView.j"
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
#include "Platform/DOM/CPDOMDisplayServer.h"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
CPScaleProportionally = 0;
|
CPScaleProportionally = 0;
|
||||||
CPScaleToFit = 1;
|
CPScaleToFit = 1;
|
||||||
CPScaleNone = 2;
|
CPScaleNone = 2;
|
||||||
|
|
||||||
CPImageAlignCenter = 0;
|
var CPImageViewShadowBackgroundColor = nil;
|
||||||
CPImageAlignTop = 1;
|
|
||||||
CPImageAlignTopLeft = 2;
|
|
||||||
CPImageAlignTopRight = 3;
|
|
||||||
CPImageAlignLeft = 4;
|
|
||||||
CPImageAlignBottom = 5;
|
|
||||||
CPImageAlignBottomLeft = 6;
|
|
||||||
CPImageAlignBottomRight = 7;
|
|
||||||
CPImageAlignRight = 8;
|
|
||||||
|
|
||||||
var CPImageViewShadowBackgroundColor = nil,
|
|
||||||
CPImageViewEmptyPlaceholderImage = nil;
|
|
||||||
|
|
||||||
var LEFT_SHADOW_INSET = 3.0,
|
var LEFT_SHADOW_INSET = 3.0,
|
||||||
RIGHT_SHADOW_INSET = 3.0,
|
RIGHT_SHADOW_INSET = 3.0,
|
||||||
@@ -59,22 +52,14 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
*/
|
*/
|
||||||
@implementation CPImageView : CPControl
|
@implementation CPImageView : CPControl
|
||||||
{
|
{
|
||||||
DOMElement _DOMImageElement;
|
DOMElement _DOMImageElement;
|
||||||
|
|
||||||
BOOL _hasShadow;
|
BOOL _hasShadow;
|
||||||
CPView _shadowView;
|
CPView _shadowView;
|
||||||
|
|
||||||
BOOL _isEditable;
|
BOOL _isEditable;
|
||||||
|
|
||||||
CGRect _imageRect;
|
CGRect _imageRect;
|
||||||
CPImageAlignment _imageAlignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initialize
|
|
||||||
{
|
|
||||||
var bundle = [CPBundle bundleForClass:[CPView class]];
|
|
||||||
|
|
||||||
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -135,7 +120,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
var newImage = [self objectValue];
|
var newImage = [self objectValue];
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
|
_DOMImageElement.src = newImage ? [newImage filename] : "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var size = [newImage size];
|
var size = [newImage size];
|
||||||
@@ -206,30 +191,6 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
[self hideOrDisplayContents];
|
[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
|
Sets the type of image scaling that should be used to
|
||||||
render the image.
|
render the image.
|
||||||
@@ -357,45 +318,8 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var x, y;
|
var x = (boundsWidth - width) / 2.0,
|
||||||
|
y = (boundsHeight - height) / 2.0;
|
||||||
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)
|
#if PLATFORM(DOM)
|
||||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
|
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
|
||||||
@@ -441,7 +365,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
return _isEditable;
|
return _isEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)performDragOperation:(CPDraggingInfo)aSender
|
- (void)performDragOperation:(CPDraggingInfo)aSender
|
||||||
{
|
{
|
||||||
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
|
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
|
||||||
|
|
||||||
@@ -450,17 +374,14 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
[self setImage:images[0]];
|
[self setImage:images[0]];
|
||||||
[self sendAction:[self action] to:[self target]];
|
[self sendAction:[self action] to:[self target]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPImageViewImageKey = @"CPImageViewImageKey",
|
var CPImageViewImageKey = @"CPImageViewImageKey",
|
||||||
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
|
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
|
||||||
CPImageViewImageAlignmentKey = @"CPImageViewImageAlignmentKey",
|
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey",
|
||||||
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey",
|
CPImageViewIsEditableKey = @"CPImageViewIsEditableKey";
|
||||||
CPImageViewIsEditableKey = @"CPImageViewIsEditableKey";
|
|
||||||
|
|
||||||
@implementation CPImageView (CPCoding)
|
@implementation CPImageView (CPCoding)
|
||||||
|
|
||||||
@@ -493,7 +414,6 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
|
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
|
||||||
[self setImageAlignment:[aCoder decodeIntForKey:CPImageViewImageAlignmentKey]];
|
|
||||||
|
|
||||||
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
|
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
|
||||||
[self setEditable:YES];
|
[self setEditable:YES];
|
||||||
@@ -528,7 +448,6 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
|||||||
_subviews = actualSubviews;
|
_subviews = actualSubviews;
|
||||||
|
|
||||||
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
|
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
|
||||||
[aCoder encodeInt:_imageAlignment forKey:CPImageViewImageAlignmentKey];
|
|
||||||
|
|
||||||
if (_isEditable)
|
if (_isEditable)
|
||||||
[aCoder encodeBool:_isEditable forKey:CPImageViewIsEditableKey];
|
[aCoder encodeBool:_isEditable forKey:CPImageViewIsEditableKey];
|
||||||
|
|||||||
@@ -1,263 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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>
|
|
||||||
|
|
||||||
@import "CPEvent.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)
|
|
||||||
[self cacheKeyBinding:[[CPKeyBinding alloc] initWithPhysicalKeyString:binding selectors:anObject[binding]]];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (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)initWithPhysicalKeyString:(CPString)binding selectors:(CPArray)selectors
|
|
||||||
{
|
|
||||||
var components = binding.split(@""),
|
|
||||||
modifierFlags = ([components containsObject:@"$"] ? CPShiftKeyMask : 0) |
|
|
||||||
([components containsObject:@"^"] ? CPControlKeyMask : 0) |
|
|
||||||
([components containsObject:@"~"] ? CPAlternateKeyMask : 0) |
|
|
||||||
([components containsObject:@"@"] ? CPCommandKeyMask : 0);
|
|
||||||
|
|
||||||
if (![selectors isKindOfClass:CPArray])
|
|
||||||
selectors = [selectors];
|
|
||||||
|
|
||||||
return [self initWithKey:[components lastObject] modifierFlags:modifierFlags selectors: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];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPString)description
|
|
||||||
{
|
|
||||||
return [CPString stringWithFormat:@"<KeyBinding string: '%@' modifierFlags: 0x%lx selectors: %@>", _key, _modifierFlags, _selectors];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,472 +0,0 @@
|
|||||||
/*
|
|
||||||
* CPKeyValueBinding.j
|
|
||||||
* AppKit
|
|
||||||
*
|
|
||||||
* Created by Ross Boucher 1/13/09
|
|
||||||
* Copyright 280 North, Inc.
|
|
||||||
*
|
|
||||||
* Adapted from GNUStep
|
|
||||||
* Released under the LGPL.
|
|
||||||
*
|
|
||||||
* 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>
|
|
||||||
@import <Foundation/CPArray.j>
|
|
||||||
@import <Foundation/CPDictionary.j>
|
|
||||||
@import <Foundation/CPValueTransformer.j>
|
|
||||||
|
|
||||||
|
|
||||||
var exposedBindingsMap = [CPDictionary new],
|
|
||||||
bindingsMap = [CPDictionary new];
|
|
||||||
|
|
||||||
var CPBindingOperationAnd = 0,
|
|
||||||
CPBindingOperationOr = 1;
|
|
||||||
|
|
||||||
@implementation CPKeyValueBinding : CPObject
|
|
||||||
{
|
|
||||||
CPDictionary _info;
|
|
||||||
id _source;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)exposeBinding:(CPString)aBinding forClass:(Class)aClass
|
|
||||||
{
|
|
||||||
var bindings = [exposedBindingsMap objectForKey:[aClass hash]];
|
|
||||||
|
|
||||||
if (!bindings)
|
|
||||||
{
|
|
||||||
bindings = [];
|
|
||||||
[exposedBindingsMap setObject:bindings forKey:[aClass hash]];
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings.push(aBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPArray)exposedBindingsForClass:(Class)aClass
|
|
||||||
{
|
|
||||||
return [[exposedBindingsMap objectForKey:[aClass hash]] copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPKeyValueBinding)getBinding:(CPString)aBinding forObject:(id)anObject
|
|
||||||
{
|
|
||||||
return [[bindingsMap objectForKey:[anObject hash]] objectForKey:aBinding];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPDictionary)infoForBinding:(CPString)aBinding forObject:(id)anObject
|
|
||||||
{
|
|
||||||
var theBinding = [self getBinding:aBinding forObject:anObject];
|
|
||||||
|
|
||||||
if (theBinding)
|
|
||||||
return theBinding._info;
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPDictionary)allBindingsForObject:(id)anObject
|
|
||||||
{
|
|
||||||
return [bindingsMap objectForKey:[anObject hash]];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)unbind:(CPString)aBinding forObject:(id)anObject
|
|
||||||
{
|
|
||||||
var bindings = [bindingsMap objectForKey:[anObject hash]];
|
|
||||||
|
|
||||||
if (!bindings)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var theBinding = [bindings objectForKey:aBinding];
|
|
||||||
|
|
||||||
if (!theBinding)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var infoDictionary = theBinding._info,
|
|
||||||
observedObject = [infoDictionary objectForKey:CPObservedObjectKey],
|
|
||||||
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey];
|
|
||||||
|
|
||||||
[observedObject removeObserver:theBinding forKeyPath:keyPath];
|
|
||||||
[bindings removeObjectForKey:aBinding];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)unbindAllForObject:(id)anObject
|
|
||||||
{
|
|
||||||
var bindings = [bindingsMap objectForKey:[anObject hash]];
|
|
||||||
if (!bindings)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var allKeys = [bindings allKeys],
|
|
||||||
count = allKeys.length;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
[anObject unbind:[bindings objectForKey:allKeys[count]]];
|
|
||||||
|
|
||||||
[bindingsMap removeObjectForKey:[anObject hash]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_source = aSource;
|
|
||||||
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
|
|
||||||
|
|
||||||
if (options)
|
|
||||||
[_info setObject:options forKey:CPOptionsKey];
|
|
||||||
|
|
||||||
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
|
|
||||||
|
|
||||||
var bindings = [bindingsMap objectForKey:[_source hash]];
|
|
||||||
if (!bindings)
|
|
||||||
{
|
|
||||||
bindings = [CPDictionary new];
|
|
||||||
[bindingsMap setObject:bindings forKey:[_source hash]];
|
|
||||||
}
|
|
||||||
|
|
||||||
[bindings setObject:self forKey:aName];
|
|
||||||
[self setValueFor:aBinding];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setValueFor:(CPString)aBinding
|
|
||||||
{
|
|
||||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
|
||||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
|
||||||
options = [_info objectForKey:CPOptionsKey],
|
|
||||||
newValue = [destination valueForKeyPath:keyPath],
|
|
||||||
isPlaceholder = CPIsControllerMarker(newValue);
|
|
||||||
|
|
||||||
if (isPlaceholder)
|
|
||||||
{
|
|
||||||
switch (newValue)
|
|
||||||
{
|
|
||||||
case CPMultipleValuesMarker:
|
|
||||||
newValue = [options objectForKey:CPMultipleValuesPlaceholderBindingOption] || @"Multiple Values";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPNoSelectionMarker:
|
|
||||||
newValue = [options objectForKey:CPNoSelectionPlaceholderBindingOption] || @"No Selection";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPNotApplicableMarker:
|
|
||||||
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
|
||||||
[CPException raise:CPGenericException reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
|
|
||||||
|
|
||||||
newValue = [options objectForKey:CPNotApplicablePlaceholderBindingOption] || @"Not Applicable";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Only transform the value if the current value is not a placeholder
|
|
||||||
newValue = [self transformValue:newValue withOptions:options];
|
|
||||||
}
|
|
||||||
|
|
||||||
[_source setValue:newValue forKey:aBinding];
|
|
||||||
|
|
||||||
if ([_source respondsToSelector:@selector(_setCurrentValueIsPlaceholder:)])
|
|
||||||
[_source _setCurrentValueIsPlaceholder:isPlaceholder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)reverseSetValueFor:(CPString)aBinding
|
|
||||||
{
|
|
||||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
|
||||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
|
||||||
options = [_info objectForKey:CPOptionsKey],
|
|
||||||
newValue = [_source valueForKeyPath:aBinding];
|
|
||||||
|
|
||||||
newValue = [self reverseTransformValue:newValue withOptions:options];
|
|
||||||
[destination setValue:newValue forKeyPath:keyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
|
|
||||||
{
|
|
||||||
if (!changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self setValueFor:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)transformValue:(id)aValue withOptions:(CPDictionary)options
|
|
||||||
{
|
|
||||||
var valueTransformerName,
|
|
||||||
valueTransformer,
|
|
||||||
placeholder;
|
|
||||||
|
|
||||||
var valueTransformerName = [options objectForKey:CPValueTransformerNameBindingOption],
|
|
||||||
valueTransformer;
|
|
||||||
|
|
||||||
if (valueTransformerName)
|
|
||||||
{
|
|
||||||
valueTransformer = [CPValueTransformer valueTransformerForName:valueTransformerName];
|
|
||||||
|
|
||||||
if (!valueTransformer)
|
|
||||||
{
|
|
||||||
var valueTransformerClass = CPClassFromString(valueTransformerName);
|
|
||||||
if (valueTransformerClass)
|
|
||||||
{
|
|
||||||
valueTransformer = [[valueTransformerClass alloc] init];
|
|
||||||
[valueTransformerClass setValueTransformer:valueTransformer forName:valueTransformerName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
valueTransformer = [options objectForKey:CPValueTransformerBindingOption];
|
|
||||||
|
|
||||||
if (valueTransformer)
|
|
||||||
aValue = [valueTransformer transformedValue:aValue];
|
|
||||||
|
|
||||||
|
|
||||||
if (aValue === undefined || aValue === nil)
|
|
||||||
aValue = [options objectForKey:CPNullPlaceholderBindingOption] || nil;
|
|
||||||
|
|
||||||
return aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)reverseTransformValue:(id)aValue withOptions: (CPDictionary)options
|
|
||||||
{
|
|
||||||
var valueTransformerName = [options objectForKey:CPValueTransformerNameBindingOption],
|
|
||||||
valueTransformer;
|
|
||||||
|
|
||||||
if (valueTransformerName)
|
|
||||||
valueTransformer = [CPValueTransformer valueTransformerForName:valueTransformerName];
|
|
||||||
else
|
|
||||||
valueTransformer = [options objectForKey:CPValueTransformerBindingOption];
|
|
||||||
|
|
||||||
if (valueTransformer && [[valueTransformer class] allowsReverseTransformation])
|
|
||||||
aValue = [valueTransformer reverseTransformedValue:aValue];
|
|
||||||
|
|
||||||
return aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation CPObject (KeyValueBindingCreation)
|
|
||||||
|
|
||||||
+ (void)exposeBinding:(CPString)aBinding
|
|
||||||
{
|
|
||||||
[CPKeyValueBinding exposeBinding:aBinding forClass:[self class]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPArray)exposedBindings
|
|
||||||
{
|
|
||||||
var exposedBindings = [],
|
|
||||||
theClass = [self class];
|
|
||||||
|
|
||||||
while (theClass)
|
|
||||||
{
|
|
||||||
var temp = [CPKeyValueBinding exposedBindingsForClass:theClass];
|
|
||||||
|
|
||||||
if (temp)
|
|
||||||
[exposedBindings addObjectsFromArray:temp];
|
|
||||||
|
|
||||||
theClass = [theClass superclass];
|
|
||||||
}
|
|
||||||
|
|
||||||
return exposedBindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (Class)valueClassForBinding:(CPString)binding
|
|
||||||
{
|
|
||||||
return [CPString class];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
|
||||||
{
|
|
||||||
if (!anObject || !aKeyPath)
|
|
||||||
return CPLog.error("Invalid object or path on "+self+" for "+aBinding);
|
|
||||||
|
|
||||||
//if (![[self exposedBindings] containsObject:aBinding])
|
|
||||||
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
|
|
||||||
|
|
||||||
[self unbind:aBinding];
|
|
||||||
[[CPKeyValueBinding alloc] initWithBinding:[self _replacementKeyPathForBinding:aBinding] name:aBinding to:anObject keyPath:aKeyPath options:options from:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPDictionary)infoForBinding:(CPString)aBinding
|
|
||||||
{
|
|
||||||
return [CPKeyValueBinding infoForBinding:aBinding forObject:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)unbind:(CPString)aBinding
|
|
||||||
{
|
|
||||||
[CPKeyValueBinding unbind:aBinding forObject:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_replacementKeyPathForBinding:(CPString)binding
|
|
||||||
{
|
|
||||||
return binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation _CPKeyValueOrBinding : CPKeyValueBinding
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setValueFor:(CPString)aBinding
|
|
||||||
{
|
|
||||||
var bindings = [bindingsMap valueForKey:[_source hash]];
|
|
||||||
|
|
||||||
if (!bindings)
|
|
||||||
return;
|
|
||||||
|
|
||||||
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationOr) forKey:aBinding];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
|
|
||||||
{
|
|
||||||
[self setValueFor:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation _CPKeyValueAndBinding : CPKeyValueBinding
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setValueFor:(CPString)aBinding
|
|
||||||
{
|
|
||||||
var bindings = [bindingsMap objectForKey:[_source hash]];
|
|
||||||
|
|
||||||
if (!bindings)
|
|
||||||
return;
|
|
||||||
|
|
||||||
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationAnd) forKey:aBinding];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObejct change:(CPDictionary)changes context:(id)context
|
|
||||||
{
|
|
||||||
[self setValueFor:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
var resolveMultipleValues = function resolveMultipleValues(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
|
|
||||||
{
|
|
||||||
var bindingName = key,
|
|
||||||
theBinding,
|
|
||||||
count = 1;
|
|
||||||
|
|
||||||
while (theBinding = [bindings objectForKey:bindingName])
|
|
||||||
{
|
|
||||||
var infoDictionary = theBinding._info,
|
|
||||||
object = [infoDictionary objectForKey:CPObservedObjectKey],
|
|
||||||
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
|
|
||||||
options = [infoDictionary objectForKey:CPOptionsKey];
|
|
||||||
|
|
||||||
var value = [theBinding transformValue:[object valueForKeyPath:keyPath] withOptions:options];
|
|
||||||
|
|
||||||
if (value == operation)
|
|
||||||
return operation;
|
|
||||||
|
|
||||||
bindingName = [CPString stringWithFormat:@"%@%i", key, ++count];
|
|
||||||
}
|
|
||||||
|
|
||||||
return !operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
var invokeAction = function invokeAction(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
|
|
||||||
{
|
|
||||||
var theBinding = [bindings objectForKey:targetKey],
|
|
||||||
infoDictionary = theBinding._info,
|
|
||||||
|
|
||||||
object = [infoDictionary objectForKey:CPObservedObjectKey],
|
|
||||||
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
|
|
||||||
options = [infoDictionary objectForKey:CPOptionsKey],
|
|
||||||
|
|
||||||
target = [object valueForKeyPath:keyPath],
|
|
||||||
selector = [options objectForKey:CPSelectorNameBindingOption];
|
|
||||||
|
|
||||||
if (!target || !selector)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
|
|
||||||
[invocation setSelector:selector];
|
|
||||||
|
|
||||||
var bindingName = argumentKey,
|
|
||||||
count = 1;
|
|
||||||
|
|
||||||
while (theBinding = [bindings objectForKey:bindingName])
|
|
||||||
{
|
|
||||||
infoDictionary = theBinding._info;
|
|
||||||
|
|
||||||
keyPath = [infoDictionary objectForKey:CPObserverKeyPathKey];
|
|
||||||
object = [[infoDictionary objectForKey:CPObservedObjectKey] valueForKeyPath:keyPath];
|
|
||||||
|
|
||||||
if (object)
|
|
||||||
[invocation setArgument:object atIndex:++count];
|
|
||||||
|
|
||||||
bindingName = [CPString stringWithFormat:@"%@%i", argumentKey, count];
|
|
||||||
}
|
|
||||||
|
|
||||||
[invocation invoke];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys in options dictionary
|
|
||||||
|
|
||||||
// Keys in dictionary returned by infoForBinding
|
|
||||||
CPObservedObjectKey = @"CPObservedObjectKey";
|
|
||||||
CPObservedKeyPathKey = @"CPObservedKeyPathKey";
|
|
||||||
CPOptionsKey = @"CPOptionsKey";
|
|
||||||
|
|
||||||
// special markers
|
|
||||||
CPMultipleValuesMarker = @"CPMultipleValuesMarker";
|
|
||||||
CPNoSelectionMarker = @"CPNoSelectionMarker";
|
|
||||||
CPNotApplicableMarker = @"CPNotApplicableMarker";
|
|
||||||
|
|
||||||
// Binding name constants
|
|
||||||
CPAlignmentBinding = @"CPAlignmentBinding";
|
|
||||||
CPEditableBinding = @"CPEditableBinding";
|
|
||||||
CPEnabledBinding = @"CPEnabledBinding";
|
|
||||||
CPFontBinding = @"CPFontBinding";
|
|
||||||
CPHiddenBinding = @"CPHiddenBinding";
|
|
||||||
CPSelectedIndexBinding = @"CPSelectedIndexBinding";
|
|
||||||
CPTextColorBinding = @"CPTextColorBinding";
|
|
||||||
CPToolTipBinding = @"CPToolTipBinding";
|
|
||||||
CPValueBinding = @"value";
|
|
||||||
|
|
||||||
//Binding options constants
|
|
||||||
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelectionBindingOption";
|
|
||||||
CPAllowsNullArgumentBindingOption = @"CPAllowsNullArgumentBindingOption";
|
|
||||||
CPConditionallySetsEditableBindingOption = @"CPConditionallySetsEditableBindingOption";
|
|
||||||
CPConditionallySetsEnabledBindingOption = @"CPConditionallySetsEnabledBindingOption";
|
|
||||||
CPConditionallySetsHiddenBindingOption = @"CPConditionallySetsHiddenBindingOption";
|
|
||||||
CPContinuouslyUpdatesValueBindingOption = @"CPContinuouslyUpdatesValueBindingOption";
|
|
||||||
CPCreatesSortDescriptorBindingOption = @"CPCreatesSortDescriptorBindingOption";
|
|
||||||
CPDeletesObjectsOnRemoveBindingsOption = @"CPDeletesObjectsOnRemoveBindingsOption";
|
|
||||||
CPDisplayNameBindingOption = @"CPDisplayNameBindingOption";
|
|
||||||
CPDisplayPatternBindingOption = @"CPDisplayPatternBindingOption";
|
|
||||||
CPHandlesContentAsCompoundValueBindingOption = @"CPHandlesContentAsCompoundValueBindingOption";
|
|
||||||
CPInsertsNullPlaceholderBindingOption = @"CPInsertsNullPlaceholderBindingOption";
|
|
||||||
CPInvokesSeparatelyWithArrayObjectsBindingOption = @"CPInvokesSeparatelyWithArrayObjectsBindingOption";
|
|
||||||
CPMultipleValuesPlaceholderBindingOption = @"CPMultipleValuesPlaceholderBindingOption";
|
|
||||||
CPNoSelectionPlaceholderBindingOption = @"CPNoSelectionPlaceholderBindingOption";
|
|
||||||
CPNotApplicablePlaceholderBindingOption = @"CPNotApplicablePlaceholderBindingOption";
|
|
||||||
CPNullPlaceholderBindingOption = @"CPNullPlaceholderBindingOption";
|
|
||||||
CPPredicateFormatBindingOption = @"CPPredicateFormatBindingOption";
|
|
||||||
CPRaisesForNotApplicableKeysBindingOption = @"CPRaisesForNotApplicableKeysBindingOption";
|
|
||||||
CPSelectorNameBindingOption = @"CPSelectorNameBindingOption";
|
|
||||||
CPSelectsAllWhenSettingContentBindingOption = @"CPSelectsAllWhenSettingContentBindingOption";
|
|
||||||
CPValidatesImmediatelyBindingOption = @"CPValidatesImmediatelyBindingOption";
|
|
||||||
CPValueTransformerNameBindingOption = @"CPValueTransformerNameBindingOption";
|
|
||||||
CPValueTransformerBindingOption = @"CPValueTransformerBindingOption";
|
|
||||||
|
|
||||||
CPIsControllerMarker = function(/*id*/anObject)
|
|
||||||
{
|
|
||||||
return anObject === CPMultipleValuesMarker || anObject === CPNoSelectionMarker || anObject === CPNotApplicableMarker;
|
|
||||||
}
|
|
||||||
+15
-8
@@ -31,6 +31,9 @@
|
|||||||
@import "CPMenuItem.j"
|
@import "CPMenuItem.j"
|
||||||
@import "CPPanel.j"
|
@import "CPPanel.j"
|
||||||
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
#include "../Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
CPMenuDidAddItemNotification = @"CPMenuDidAddItemNotification";
|
CPMenuDidAddItemNotification = @"CPMenuDidAddItemNotification";
|
||||||
CPMenuDidChangeItemNotification = @"CPMenuDidChangeItemNotification";
|
CPMenuDidChangeItemNotification = @"CPMenuDidChangeItemNotification";
|
||||||
@@ -72,7 +75,7 @@ var _CPMenuBarVisible = NO,
|
|||||||
|
|
||||||
id _delegate;
|
id _delegate;
|
||||||
|
|
||||||
int _highlightedIndex;
|
CPMenuItem _highlightedIndex;
|
||||||
_CPMenuWindow _menuWindow;
|
_CPMenuWindow _menuWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,9 +747,6 @@ var _CPMenuBarVisible = NO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show it.
|
// Show it.
|
||||||
if ([CPPlatform isBrowser])
|
|
||||||
[menuWindow setPlatformWindow:[[aView window] platformWindow]];
|
|
||||||
|
|
||||||
[menuWindow orderFront:self];
|
[menuWindow orderFront:self];
|
||||||
|
|
||||||
// Track it.
|
// Track it.
|
||||||
@@ -816,9 +816,6 @@ var _CPMenuBarVisible = NO,
|
|||||||
[menuWindow setFrameOrigin:CGRectIntersection(unconstrainedFrame, constraintRect).origin];
|
[menuWindow setFrameOrigin:CGRectIntersection(unconstrainedFrame, constraintRect).origin];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([CPPlatform isBrowser])
|
|
||||||
[menuWindow setPlatformWindow:[[aView window] platformWindow]];
|
|
||||||
|
|
||||||
[menuWindow orderFront:self];
|
[menuWindow orderFront:self];
|
||||||
|
|
||||||
[[_CPMenuManager sharedMenuManager]
|
[[_CPMenuManager sharedMenuManager]
|
||||||
@@ -935,7 +932,17 @@ var _CPMenuBarVisible = NO,
|
|||||||
var item = _items[index],
|
var item = _items[index],
|
||||||
modifierMask = [item keyEquivalentModifierMask];
|
modifierMask = [item keyEquivalentModifierMask];
|
||||||
|
|
||||||
if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[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 ([item isEnabled])
|
if ([item isEnabled])
|
||||||
[self performActionForItemAtIndex:index];
|
[self performActionForItemAtIndex:index];
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
@import "CPPanel.j"
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
#include "../Platform/Platform.h"
|
||||||
|
|
||||||
@import "_CPMenuWindow.j"
|
@import "_CPMenuWindow.j"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
|
||||||
@@ -93,7 +96,7 @@ var SharedMenuManager = nil;
|
|||||||
|
|
||||||
// Close Menu Event.
|
// Close Menu Event.
|
||||||
if (type === CPAppKitDefined)
|
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];
|
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES];
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@import "CPWindow.j"
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
var _CPMenuWindowPool = [],
|
var _CPMenuWindowPool = [],
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
@import "_CPMenuItemView.j"
|
@import "_CPMenuItemView.j"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPMenuItem
|
@class CPMenuItem
|
||||||
@@ -592,8 +591,7 @@ CPControlKeyMask
|
|||||||
return @"";
|
return @"";
|
||||||
|
|
||||||
var string = _keyEquivalent.toUpperCase(),
|
var string = _keyEquivalent.toUpperCase(),
|
||||||
needsShift = _keyEquivalentModifierMask & CPShiftKeyMask ||
|
needsShift = _keyEquivalentModifierMask & CPShiftKeyMask || string === _keyEquivalent;
|
||||||
(string === _keyEquivalent && _keyEquivalent.toLowerCase() !== _keyEquivalent.toUpperCase());
|
|
||||||
|
|
||||||
if (CPBrowserIsOperatingSystem(CPMacOperatingSystem))
|
if (CPBrowserIsOperatingSystem(CPMacOperatingSystem))
|
||||||
{
|
{
|
||||||
@@ -783,48 +781,7 @@ CPControlKeyMask
|
|||||||
return [[self menu] highlightedItem] == self;
|
return [[self menu] highlightedItem] == self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark CPObject Overrides
|
//
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a copy of the item. The copy does not belong If the item has a submenu, it is NOT copied.
|
|
||||||
*/
|
|
||||||
- (id)copy
|
|
||||||
{
|
|
||||||
var item = [[CPMenuItem alloc] init];
|
|
||||||
|
|
||||||
// No point in going through accessors and doing lots of unnecessary state checking/updating
|
|
||||||
item._isSeparator = _isSeparator;
|
|
||||||
|
|
||||||
[item setTitle:_title];
|
|
||||||
[item setFont:_font];
|
|
||||||
[item setTarget:_target];
|
|
||||||
[item setAction:_action];
|
|
||||||
[item setEnabled:_isEnabled];
|
|
||||||
[item setHidden:_isHidden]
|
|
||||||
[item setTag:_tag];
|
|
||||||
[item setState:_state];
|
|
||||||
[item setImage:_image];
|
|
||||||
[item setAlternateImage:_alternateImage];
|
|
||||||
[item setOnStateImage:_onStateImage];
|
|
||||||
[item setOffStateImage:_offStateImage];
|
|
||||||
[item setMixedStateImage:_mixedStateImage];
|
|
||||||
[item setKeyEquivalent:_keyEquivalent];
|
|
||||||
[item setKeyEquivalentModifierMask:_keyEquivalentModifierMask];
|
|
||||||
[item setMnemonicLocation:_mnemonicLocation];
|
|
||||||
[item setAlternate:_isAlternate];
|
|
||||||
[item setIndentationLevel:_indentationLevel];
|
|
||||||
[item setToolTip:_toolTip];
|
|
||||||
[item setRepresentedObject:_representedObject];
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)mutableCopy
|
|
||||||
{
|
|
||||||
return [self copy];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark Internal
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ignore
|
@ignore
|
||||||
@@ -903,6 +860,7 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
|
|||||||
_isHidden = DEFAULT_VALUE(CPMenuItemIsHiddenKey, NO);
|
_isHidden = DEFAULT_VALUE(CPMenuItemIsHiddenKey, NO);
|
||||||
_tag = DEFAULT_VALUE(CPMenuItemTagKey, 0);
|
_tag = DEFAULT_VALUE(CPMenuItemTagKey, 0);
|
||||||
_state = DEFAULT_VALUE(CPMenuItemStateKey, CPOffState);
|
_state = DEFAULT_VALUE(CPMenuItemStateKey, CPOffState);
|
||||||
|
// int _state;
|
||||||
|
|
||||||
_image = DEFAULT_VALUE(CPMenuItemImageKey, nil);
|
_image = DEFAULT_VALUE(CPMenuItemImageKey, nil);
|
||||||
_alternateImage = DEFAULT_VALUE(CPMenuItemAlternateImageKey, nil);
|
_alternateImage = DEFAULT_VALUE(CPMenuItemAlternateImageKey, nil);
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
@import "CPView.j"
|
|
||||||
|
|
||||||
|
|
||||||
var HORIZONTAL_MARGIN = 8.0,
|
var HORIZONTAL_MARGIN = 8.0,
|
||||||
SUBMENU_INDICATOR_MARGIN = 3.0,
|
SUBMENU_INDICATOR_MARGIN = 3.0,
|
||||||
VERTICAL_MARGIN = 4.0;
|
VERTICAL_MARGIN = 4.0;
|
||||||
@@ -65,7 +62,6 @@ var SelectionColor = nil,
|
|||||||
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(HORIZONTAL_MARGIN, 0.0, 0.0, 0.0)];
|
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(HORIZONTAL_MARGIN, 0.0, 0.0, 0.0)];
|
||||||
|
|
||||||
[_imageAndTextView setImagePosition:CPImageLeft];
|
[_imageAndTextView setImagePosition:CPImageLeft];
|
||||||
[_imageAndTextView setImageOffset:3.0];
|
|
||||||
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
||||||
[_imageAndTextView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
|
[_imageAndTextView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
|
|
||||||
|
|
||||||
@implementation _CPMenuItemSeparatorView : CPView
|
@implementation _CPMenuItemSeparatorView : CPView
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
@import "CPControl.j"
|
|
||||||
|
|
||||||
|
|
||||||
var LEFT_MARGIN = 3.0,
|
var LEFT_MARGIN = 3.0,
|
||||||
RIGHT_MARGIN = 14.0 + 3.0,
|
RIGHT_MARGIN = 14.0 + 3.0,
|
||||||
STATE_COLUMN_WIDTH = 14.0,
|
STATE_COLUMN_WIDTH = 14.0,
|
||||||
@@ -42,7 +39,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
|
|||||||
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
|
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];
|
_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];
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
|
|
||||||
@@ -260,13 +257,10 @@ var SUBMENU_INDICATOR_COLOR = nil,
|
|||||||
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
|
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([[_menuItem menu] showsStateColumn])
|
if (shouldHighlight)
|
||||||
{
|
[_stateView setImage:_CPMenuItemDefaultStateHighlightedImages[[_menuItem state]] || nil];
|
||||||
if (shouldHighlight)
|
else
|
||||||
[_stateView setImage:_CPMenuItemDefaultStateHighlightedImages[[_menuItem state]] || nil];
|
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
|
||||||
else
|
|
||||||
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
@import <AppKit/CPControl.j>
|
|
||||||
|
|
||||||
@import "_CPMenuItemSeparatorView.j"
|
@import "_CPMenuItemSeparatorView.j"
|
||||||
@import "_CPMenuItemStandardView.j"
|
@import "_CPMenuItemStandardView.j"
|
||||||
@import "_CPMenuItemMenuBarView.j"
|
@import "_CPMenuItemMenuBarView.j"
|
||||||
@@ -45,7 +43,7 @@ var _CPMenuItemSelectionColor = nil,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
|
_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];
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
|
|
||||||
|
|||||||
@@ -1,625 +0,0 @@
|
|||||||
|
|
||||||
@import <Foundation/CPDictionary.j>
|
|
||||||
@import <Foundation/CPCountedSet.j>
|
|
||||||
|
|
||||||
@import "CPController.j"
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CPObjectController : CPController
|
|
||||||
{
|
|
||||||
id _contentObject;
|
|
||||||
id _selection;
|
|
||||||
|
|
||||||
Class _objectClass;
|
|
||||||
|
|
||||||
BOOL _isEditable;
|
|
||||||
BOOL _automaticallyPreparesContent;
|
|
||||||
|
|
||||||
CPCountedSet _observedKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)initialize
|
|
||||||
{
|
|
||||||
[self exposeBinding:@"editable"];
|
|
||||||
[self exposeBinding:@"contentObject"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingContentObject
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"content"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)automaticallyNotifiesObserversForKey:(CPString)aKey
|
|
||||||
{
|
|
||||||
if (aKey === @"contentObject")
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingCanAdd
|
|
||||||
{
|
|
||||||
return [CPSet setWithObject:"editable"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingCanInsert
|
|
||||||
{
|
|
||||||
return [CPSet setWithObject:"editable"];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPSet)keyPathsForValuesAffectingCanRemove
|
|
||||||
{
|
|
||||||
return [CPSet setWithObjects:"editable", "selection"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)init
|
|
||||||
{
|
|
||||||
return [self initWithContent:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithContent:(id)aContent
|
|
||||||
{
|
|
||||||
if (self = [super init])
|
|
||||||
{
|
|
||||||
[self setContent:aContent];
|
|
||||||
[self setEditable:YES];
|
|
||||||
[self setObjectClass:[CPMutableDictionary class]];
|
|
||||||
|
|
||||||
_observedKeys = [[CPCountedSet alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)content
|
|
||||||
{
|
|
||||||
return _contentObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setContent:(id)aContent
|
|
||||||
{
|
|
||||||
[self willChangeValueForKey:@"contentObject"];
|
|
||||||
[self _selectionWillChange];
|
|
||||||
|
|
||||||
_contentObject = aContent;
|
|
||||||
|
|
||||||
[self didChangeValueForKey:@"contentObject"];
|
|
||||||
[self _selectionDidChange];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_setContentObject:(id)aContent
|
|
||||||
{
|
|
||||||
[self setContent:aContent];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_contentObject
|
|
||||||
{
|
|
||||||
return [self content];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setAutomaticallyPreparesContent:(BOOL)shouldAutomaticallyPrepareContent
|
|
||||||
{
|
|
||||||
_automaticallyPreparesContent = shouldAutomaticallyPrepareContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)automaticallyPreparesContent
|
|
||||||
{
|
|
||||||
return _automaticallyPreparesContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)prepareContent
|
|
||||||
{
|
|
||||||
[self setContent:[self newObject]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setObjectClass:(Class)aClass
|
|
||||||
{
|
|
||||||
_objectClass = aClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (Class)objectClass
|
|
||||||
{
|
|
||||||
return _objectClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)newObject
|
|
||||||
{
|
|
||||||
return [[[self objectClass] alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObject:(id)anObject
|
|
||||||
{
|
|
||||||
[self setContent:anObject];
|
|
||||||
|
|
||||||
[[CPKeyValueBinding getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObject:(id)anObject
|
|
||||||
{
|
|
||||||
if ([self content] === anObject)
|
|
||||||
[self setContent:nil];
|
|
||||||
|
|
||||||
[[CPKeyValueBinding getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)add:(id)aSender
|
|
||||||
{
|
|
||||||
// FIXME: This should happen on the next run loop?
|
|
||||||
[self addObject:[self newObject]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)canAdd
|
|
||||||
{
|
|
||||||
return [self isEditable];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)remove:(id)aSender
|
|
||||||
{
|
|
||||||
// FIXME: This should happen on the next run loop?
|
|
||||||
[self removeObject:[self content]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)canRemove
|
|
||||||
{
|
|
||||||
return [self isEditable] && [[self selectedObjects] count];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setEditable:(BOOL)shouldBeEditable
|
|
||||||
{
|
|
||||||
_isEditable = shouldBeEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isEditable
|
|
||||||
{
|
|
||||||
return _isEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPArray)selectedObjects
|
|
||||||
{
|
|
||||||
return [[_CPObservableArray alloc] initWithObjects:[_contentObject] count:1];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)selection
|
|
||||||
{
|
|
||||||
return _selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_selectionWillChange
|
|
||||||
{
|
|
||||||
[_selection controllerWillChange];
|
|
||||||
[self willChangeValueForKey:@"selection"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_selectionDidChange
|
|
||||||
{
|
|
||||||
if (_selection === undefined || _selection === nil)
|
|
||||||
_selection = [[CPControllerSelectionProxy alloc] initWithController:self];
|
|
||||||
|
|
||||||
[_selection controllerDidChange];
|
|
||||||
[self didChangeValueForKey:@"selection"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)observedKeys
|
|
||||||
{
|
|
||||||
return _observedKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
|
|
||||||
{
|
|
||||||
[_observedKeys addObject:aKeyPath];
|
|
||||||
[super addObserver:anObserver forKeyPath:aKeyPath options:options context:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObserver:(id)anObserver forKeyPath:(CPString)aKeyPath
|
|
||||||
{
|
|
||||||
[_observedKeys removeObject:aKeyPath];
|
|
||||||
[super removeObserver:anObserver forKeyPath:aKeyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
var CPObjectControllerObjectClassNameKey = @"CPObjectControllerObjectClassNameKey",
|
|
||||||
CPObjectControllerIsEditableKey = @"CPObjectControllerIsEditableKey",
|
|
||||||
CPObjectControllerAutomaticallyPreparesContentKey = @"CPObjectControllerAutomaticallyPreparesContentKey";
|
|
||||||
|
|
||||||
@implementation CPObjectController (CPCoding)
|
|
||||||
|
|
||||||
- (id)initWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
var objectClassName = [aCoder decodeObjectForKey:CPObjectControllerObjectClassNameKey],
|
|
||||||
objectClass = CPClassFromString(objectClassName);
|
|
||||||
|
|
||||||
// FIXME: Error if objectClass === nil
|
|
||||||
|
|
||||||
[self setObjectClass:objectClass];
|
|
||||||
[self setEditable:[aCoder decodeBoolForKey:CPObjectControllerIsEditableKey]];
|
|
||||||
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey] || NO];
|
|
||||||
|
|
||||||
_observedKeys = [[CPCountedSet alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
[aCoder encodeObject:CPStringFromClass(objectClass) forKey:CPObjectControllerObjectClassNameKey];
|
|
||||||
[aCoder encodeObject:[self isEditable] forKey:CPObjectControllerIsEditableKey];
|
|
||||||
|
|
||||||
if (![self automaticallyPreparesContent])
|
|
||||||
[aCoder encodeBOOL:YES forKey:CPObjectControllerAutomaticallyPreparesContentKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation _CPObservationProxy : CPObject
|
|
||||||
{
|
|
||||||
id _keyPath;
|
|
||||||
id _observer;
|
|
||||||
id _object;
|
|
||||||
|
|
||||||
BOOL _notifyObject;
|
|
||||||
|
|
||||||
id _context;
|
|
||||||
int _options;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithKeyPath:(id)aKeyPath observer:(id)anObserver object:(id)anObject
|
|
||||||
{
|
|
||||||
if (self=[super init])
|
|
||||||
{
|
|
||||||
_keyPath = aKeyPath;
|
|
||||||
_observer = anObserver;
|
|
||||||
_object = anObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)observer
|
|
||||||
{
|
|
||||||
return _observer;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)keyPath
|
|
||||||
{
|
|
||||||
return _keyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)context
|
|
||||||
{
|
|
||||||
return _context;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int)options
|
|
||||||
{
|
|
||||||
return _options;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setNotifyObject:(BOOL)notify
|
|
||||||
{
|
|
||||||
_notifyObject = notify;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isEqual:(id)anObject
|
|
||||||
{
|
|
||||||
if ([anObject class] === [self class])
|
|
||||||
{
|
|
||||||
if (anObject._observer === _observer && [anObject._keyPath isEqual:_keyPath] && [anObject._object isEqual:_object])
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context
|
|
||||||
{
|
|
||||||
if (_notifyObject)
|
|
||||||
[_object observeValueForKeyPath:_keyPath ofObject:_object change:change context:context];
|
|
||||||
|
|
||||||
[_observer observeValueForKeyPath:_keyPath ofObject:_object change:change context:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPString)description
|
|
||||||
{
|
|
||||||
return [super description] + [CPString stringWithFormat:@"observation proxy for %@ on key path %@", _observer, _keyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation _CPObservableArray : CPMutableArray
|
|
||||||
{
|
|
||||||
CPArray _observationProxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)alloc
|
|
||||||
{
|
|
||||||
var a = [];
|
|
||||||
a.isa = self;
|
|
||||||
|
|
||||||
var ivars = class_copyIvarList(self),
|
|
||||||
count = ivars.length;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
a[ivar_getName(ivars[count])] = nil;
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPString)description
|
|
||||||
{
|
|
||||||
return "<_CPObservableArray: "+[super description]+" >";
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithArray:(CPArray)anArray
|
|
||||||
{
|
|
||||||
if (self = [super initWithArray:anArray])
|
|
||||||
{
|
|
||||||
_observationProxies = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithObjects:(CPArray)objects count:(unsigned)count
|
|
||||||
{
|
|
||||||
if (self = [super initWithObjects:objects count:count])
|
|
||||||
{
|
|
||||||
_observationProxies = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
|
|
||||||
{
|
|
||||||
if (aKeyPath.indexOf("@") === 0)
|
|
||||||
{
|
|
||||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self];
|
|
||||||
|
|
||||||
proxy._options = options;
|
|
||||||
proxy._context = context;
|
|
||||||
|
|
||||||
[_observationProxies addObject:proxy];
|
|
||||||
|
|
||||||
var dotIndex = aKeyPath.indexOf("."),
|
|
||||||
remaining = aKeyPath.substring(dotIndex+1),
|
|
||||||
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
|
||||||
|
|
||||||
[self addObserver:proxy toObjectsAtIndexes:indexes forKeyPath:remaining options:options context:context];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
|
||||||
[self addObserver:anObserver toObjectsAtIndexes:indexes forKeyPath:aKeyPath options:options context:context];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObserver:(id)anObserver forKeyPath:(CPString)aKeyPath
|
|
||||||
{
|
|
||||||
if (aKeyPath.indexOf("@") === 0)
|
|
||||||
{
|
|
||||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self],
|
|
||||||
index = [_observationProxies indexOfObject:proxy];
|
|
||||||
|
|
||||||
proxy = [_observationProxies objectAtIndex:index];
|
|
||||||
|
|
||||||
var dotIndex = aKeyPath.indexOf("."),
|
|
||||||
remaining = aKeyPath.substring(dotIndex+1),
|
|
||||||
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
|
||||||
|
|
||||||
[self removeObserver:proxy fromObjectsAtIndexes:indexes forKeyPath:remaining];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
|
||||||
[self removeObserver:anObserver fromObjectsAtIndexes:indexes forKeyPath:aKeyPath];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)insertObject:(id)anObject atIndex:(unsigned)anIndex
|
|
||||||
{
|
|
||||||
for (var i=0, count=[_observationProxies count]; i<count; i++)
|
|
||||||
{
|
|
||||||
var proxy = [_observationProxies objectAtIndex:i],
|
|
||||||
keyPath = [proxy keyPath],
|
|
||||||
operator = keyPath.indexOf(".") === 0;
|
|
||||||
|
|
||||||
if (operator)
|
|
||||||
[self willChangeValueForKey:keyPath];
|
|
||||||
|
|
||||||
[anObject addObserver:proxy forKeyPath:keyPath options:[proxy options] context:[proxy context]];
|
|
||||||
|
|
||||||
if (operator)
|
|
||||||
[self didChangeValueForKey:keyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
[super insertObject:anObject atIndex:anIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObjectAtIndex:(unsigned)anIndex
|
|
||||||
{
|
|
||||||
for (var i=0, count=[_observationProxies count]; i<count; i++)
|
|
||||||
{
|
|
||||||
var proxy = [_observationProxies objectAtIndex:i],
|
|
||||||
keyPath = [proxy keyPath],
|
|
||||||
operator = keyPath.indexOf(".") === 0;
|
|
||||||
|
|
||||||
if (operator)
|
|
||||||
[self willChangeValueForKey:keyPath];
|
|
||||||
|
|
||||||
[anObject removeObserver:proxy forKeyPath:keyPath];
|
|
||||||
|
|
||||||
if (operator)
|
|
||||||
[self didChangeValueForKey:keyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
[super removeObjectAtIndex:anIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (_CPObservableArray)objectsAtIndexes:(CPIndexSet)theIndexes
|
|
||||||
{
|
|
||||||
return [_CPObservableArray arrayWithArray:[super objectsAtIndexes:theIndexes]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObject:(id)anObject
|
|
||||||
{
|
|
||||||
[self insertObject:anObject atIndex:[self count]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeLastObject
|
|
||||||
{
|
|
||||||
[self removeObjectAtIndex:[self count]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)replaceObjectAtIndex:(unsigned)anIndex withObject:(id)anObject
|
|
||||||
{
|
|
||||||
var currentObject = [self objectAtIndex:anIndex];
|
|
||||||
|
|
||||||
for (var i=0, count=[_observationProxies count]; i<count; i++)
|
|
||||||
{
|
|
||||||
var proxy = [_observationProxies objectAtIndex:i],
|
|
||||||
keyPath = [proxy keyPath],
|
|
||||||
operator = keyPath.indexOf(".") === 0;
|
|
||||||
|
|
||||||
if (operator)
|
|
||||||
[self willChangeValueForKey:keyPath];
|
|
||||||
|
|
||||||
[currentObject removeObserver:proxy forKeyPath:keyPath];
|
|
||||||
[anObject addObserver:proxy forKeyPath:keyPath options:[proxy options] context:[proxy context]];
|
|
||||||
|
|
||||||
if (operator)
|
|
||||||
[self didChangeValueForKey:keyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
[super replaceObjectAtIndex:anIndex withObject:anObject];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation CPControllerSelectionProxy : CPObject
|
|
||||||
{
|
|
||||||
id _controller;
|
|
||||||
id _keys;
|
|
||||||
|
|
||||||
CPDictionary _cachedValues;
|
|
||||||
CPArray _observationProxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithController:(id)aController
|
|
||||||
{
|
|
||||||
if (self = [super init])
|
|
||||||
{
|
|
||||||
_cachedValues = [CPDictionary dictionary];
|
|
||||||
_observationProxies = [CPArray array];
|
|
||||||
_controller = aController;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)valueForKey:(CPString)aKey
|
|
||||||
{
|
|
||||||
var value = [_cachedValues objectForKey:aKey];
|
|
||||||
|
|
||||||
if (value !== undefined && value !== nil)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
var allValues = [[_controller selectedObjects] valueForKeyPath:aKey],
|
|
||||||
count = [allValues count];
|
|
||||||
|
|
||||||
if (!count)
|
|
||||||
value = CPNoSelectionMarker;
|
|
||||||
else if (count === 1)
|
|
||||||
value = [allValues objectAtIndex:0];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ([_controller alwaysUsesMultipleValuesMarker])
|
|
||||||
value = CPMultipleValuesMarker;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = [allValues objectAtIndex:0];
|
|
||||||
|
|
||||||
for (var i=0, count=[allValues count]; i<count && value!=CPMultipleValuesMarker; i++)
|
|
||||||
{
|
|
||||||
if (![value isEqual:[allValues objectAtIndex:i]])
|
|
||||||
value = CPMultipleValuesMarker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[_cachedValues setValue:value forKey:aKey];
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (unsigned)count
|
|
||||||
{
|
|
||||||
return [_cachedValues count];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)keyEnumerator
|
|
||||||
{
|
|
||||||
return [_cachedValues keyEnumerator];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setValue:(id)aValue forKey:(CPString)aKey
|
|
||||||
{
|
|
||||||
[[_controller selectedObjects] setValue:aValue forKey:aKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)controllerWillChange
|
|
||||||
{
|
|
||||||
_keys = [_cachedValues allKeys];
|
|
||||||
|
|
||||||
if (!_keys)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var i=0, count=_keys.length; i<count; i++)
|
|
||||||
[self willChangeValueForKey:_keys[i]];
|
|
||||||
|
|
||||||
[_cachedValues removeAllObjects];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)controllerDidChange
|
|
||||||
{
|
|
||||||
[_cachedValues removeAllObjects];
|
|
||||||
|
|
||||||
if (!_keys)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var i=0, count=_keys.length; i<count; i++)
|
|
||||||
[self didChangeValueForKey:_keys[i]];
|
|
||||||
|
|
||||||
_keys = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context
|
|
||||||
{
|
|
||||||
[_cachedValues removeObjectForKey:aKeyPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObserver:(id)anObject forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
|
|
||||||
{
|
|
||||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self];
|
|
||||||
|
|
||||||
[proxy setNotifyObject:YES];
|
|
||||||
[_observationProxies addObject:proxy];
|
|
||||||
|
|
||||||
[[_controller selectedObjects] addObserver:proxy forKeyPath:aKeyPath options:options context:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObserver:(id)anObject forKeyPath:(CPString)aKeyPath
|
|
||||||
{
|
|
||||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self],
|
|
||||||
index = [_observationProxies indexOfObject:proxy];
|
|
||||||
|
|
||||||
[[_controller selectedObjects] removeObserver:[_observationProxies objectAtIndex:index] forKeyPath:aKeyPath];
|
|
||||||
[_observationProxies removeObjectAtIndex:index];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
@import "CPPanel.j"
|
@import <AppKit/CPPanel.j>
|
||||||
|
|
||||||
|
|
||||||
@implementation CPOpenPanel : CPPanel
|
@implementation CPOpenPanel : CPPanel
|
||||||
|
|||||||
+60
-306
@@ -23,6 +23,8 @@
|
|||||||
@import "CPTableColumn.j"
|
@import "CPTableColumn.j"
|
||||||
@import "CPTableView.j"
|
@import "CPTableView.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
CPOutlineViewColumnDidMoveNotification = @"CPOutlineViewColumnDidMoveNotification";
|
CPOutlineViewColumnDidMoveNotification = @"CPOutlineViewColumnDidMoveNotification";
|
||||||
CPOutlineViewColumnDidResizeNotification = @"CPOutlineViewColumnDidResizeNotification";
|
CPOutlineViewColumnDidResizeNotification = @"CPOutlineViewColumnDidResizeNotification";
|
||||||
@@ -48,30 +50,12 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
|
|||||||
|
|
||||||
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 10;
|
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 10;
|
||||||
|
|
||||||
|
|
||||||
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
|
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
|
||||||
CPOutlineViewDelegate_outlineView_didClickTableColumn_ = 1 << 2,
|
CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 2,
|
||||||
CPOutlineViewDelegate_outlineView_didDragTableColumn_ = 1 << 3,
|
CPOutlineViewDelegate_outlineView_heightOfRowByItem_ = 1 << 3,
|
||||||
CPOutlineViewDelegate_outlineView_heightOfRowByItem_ = 1 << 4,
|
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ = 1 << 4,
|
||||||
CPOutlineViewDelegate_outlineView_isGroupItem_ = 1 << 5,
|
CPOutlineViewDelegate_outlineView_isGroupItem_ = 1 << 5;
|
||||||
CPOutlineViewDelegate_outlineView_mouseDownInHeaderOfTableColumn_ = 1 << 6,
|
|
||||||
CPOutlineViewDelegate_outlineView_nextTypeSelectMatchFromItem_toItem_forString_ = 1 << 7,
|
|
||||||
CPOutlineViewDelegate_outlineView_selectionIndexesForProposedSelection_ = 1 << 8,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldCollapseItem_ = 1 << 9,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldEditTableColumn_item_ = 1 << 10,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldExpandItem_ = 1 << 11,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldReorderColumn_toColumn_ = 1 << 12,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 13,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_ = 1 << 14,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldShowOutlineViewForItem_ = 1 << 15,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldShowViewExpansionForTableColumn_item_ = 1 << 16,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldTrackView_forTableColumn_item_ = 1 << 17,
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldTypeSelectForEvent_withCurrentSearchString_ = 1 << 18,
|
|
||||||
CPOutlineViewDelegate_outlineView_sizeToFitWidthOfColumn_ = 1 << 19,
|
|
||||||
CPOutlineViewDelegate_outlineView_toolTipForView_rect_tableColumn_item_mouseLocation_ = 1 << 20,
|
|
||||||
CPOutlineViewDelegate_outlineView_typeSelectStringForTableColumn_item_ = 1 << 21,
|
|
||||||
CPOutlineViewDelegate_outlineView_willDisplayOutlineView_forTableColumn_item_ = 1 << 22,
|
|
||||||
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ = 1 << 23,
|
|
||||||
CPOutlineViewDelegate_selectionShouldChangeInOutlineView_ = 1 << 24;
|
|
||||||
|
|
||||||
CPOutlineViewDropOnItemIndex = -1;
|
CPOutlineViewDropOnItemIndex = -1;
|
||||||
|
|
||||||
@@ -101,8 +85,6 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
|
|
||||||
BOOL _shouldRetargetChildIndex;
|
BOOL _shouldRetargetChildIndex;
|
||||||
CPInteger _retargedChildIndex;
|
CPInteger _retargedChildIndex;
|
||||||
CPTimer _dragHoverTimer;
|
|
||||||
id _dropItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -126,7 +108,6 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
|
|
||||||
_retargedChildIndex = nil;
|
_retargedChildIndex = nil;
|
||||||
_shouldRetargetChildIndex = NO;
|
_shouldRetargetChildIndex = NO;
|
||||||
_startHoverTime = nil;
|
|
||||||
|
|
||||||
[self setIndentationPerLevel:16.0];
|
[self setIndentationPerLevel:16.0];
|
||||||
[self setIndentationMarkerFollowsDataView:YES];
|
[self setIndentationMarkerFollowsDataView:YES];
|
||||||
@@ -241,14 +222,8 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
if (!itemInfo)
|
if (!itemInfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// to prevent items which are already expanded from firing notifications
|
itemInfo.isExpanded = YES;
|
||||||
if (!itemInfo.isExpanded)
|
[self reloadItem:anItem reloadChildren:YES];
|
||||||
{
|
|
||||||
[self _noteItemWillExpand:anItem];
|
|
||||||
itemInfo.isExpanded = YES;
|
|
||||||
[self _noteItemDidExpand:anItem];
|
|
||||||
[self reloadItem:anItem reloadChildren:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldExpandChildren)
|
if (shouldExpandChildren)
|
||||||
{
|
{
|
||||||
@@ -273,9 +248,7 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
if (!itemInfo.isExpanded)
|
if (!itemInfo.isExpanded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[self _noteItemWillCollapse:anItem];
|
|
||||||
itemInfo.isExpanded = NO;
|
itemInfo.isExpanded = NO;
|
||||||
[self _noteItemDidCollapse:anItem];
|
|
||||||
|
|
||||||
[self reloadItem:anItem reloadChildren:YES];
|
[self reloadItem:anItem reloadChildren:YES];
|
||||||
}
|
}
|
||||||
@@ -409,14 +382,43 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
|
- (void)selectRowIndexes:(CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection
|
||||||
{
|
{
|
||||||
[super _performSelection:select forRow:rowIndex context:context];
|
// First un highlight the old disclosure controls
|
||||||
|
var previousSelectedRows = [];
|
||||||
|
[[self selectedRowIndexes] getIndexes:previousSelectedRows maxCount:-1 inIndexRange:nil];
|
||||||
|
|
||||||
var control = _disclosureControlsForRows[rowIndex],
|
var index = [previousSelectedRows count];
|
||||||
selector = select ? @"setThemeState:" : @"unsetThemeState:";
|
while (index--)
|
||||||
|
{
|
||||||
|
var rowIndex = previousSelectedRows[index],
|
||||||
|
item = [self itemAtRow:rowIndex];
|
||||||
|
|
||||||
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
|
if (![self isExpandable:item])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var control = _disclosureControlsForRows[rowIndex];
|
||||||
|
[control setHighlighted:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
[super selectRowIndexes:rows byExtendingSelection:shouldExtendSelection];
|
||||||
|
|
||||||
|
// Now highlight the new disclosure controls
|
||||||
|
var selectedRows = [];
|
||||||
|
[rows getIndexes:selectedRows maxCount:-1 inIndexRange:nil];
|
||||||
|
|
||||||
|
var index = [selectedRows count];
|
||||||
|
while (index--)
|
||||||
|
{
|
||||||
|
var rowIndex = selectedRows[index],
|
||||||
|
item = [self itemAtRow:rowIndex];
|
||||||
|
|
||||||
|
if (![self isExpandable:item])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var control = _disclosureControlsForRows[rowIndex];
|
||||||
|
[control setHighlighted:YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDelegate:(id)aDelegate
|
- (void)setDelegate:(id)aDelegate
|
||||||
@@ -451,76 +453,25 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
removeObserver:_outlineViewDelegate
|
removeObserver:_outlineViewDelegate
|
||||||
name:CPOutlineViewSelectionIsChangingNotification
|
name:CPOutlineViewSelectionIsChangingNotification
|
||||||
object:self];
|
object:self];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
|
|
||||||
[defaultCenter
|
|
||||||
removeObserver:_outlineViewDelegate
|
|
||||||
name:CPOutlineViewItemWillExpandNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)])
|
|
||||||
[defaultCenter
|
|
||||||
removeObserver:_outlineViewDelegate
|
|
||||||
name:CPOutlineViewItemDidExpandNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)])
|
|
||||||
[defaultCenter
|
|
||||||
removeObserver:_outlineViewDelegate
|
|
||||||
name:CPOutlineViewItemWillCollapseNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)])
|
|
||||||
[defaultCenter
|
|
||||||
removeObserver:_outlineViewDelegate
|
|
||||||
name:CPOutlineViewItemDidCollapseNotification
|
|
||||||
object:self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_outlineViewDelegate = aDelegate;
|
_outlineViewDelegate = aDelegate;
|
||||||
_implementedOutlineViewDelegateMethods = 0;
|
_implementedOutlineViewDelegateMethods = 0;
|
||||||
|
|
||||||
var delegateMethods = [
|
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:dataViewForTableColumn:item:)])
|
||||||
CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ , @selector(outlineView:dataViewForTableColumn:item:),
|
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_;
|
||||||
CPOutlineViewDelegate_outlineView_didClickTableColumn_ , @selector(outlineView:didClickTableColumn:),
|
|
||||||
CPOutlineViewDelegate_outlineView_didDragTableColumn_ , @selector(outlineView:didDragTableColumn:),
|
|
||||||
CPOutlineViewDelegate_outlineView_heightOfRowByItem_ , @selector(outlineView:heightOfRowByItem:),
|
|
||||||
CPOutlineViewDelegate_outlineView_isGroupItem_ , @selector(outlineView:isGroupItem:),
|
|
||||||
CPOutlineViewDelegate_outlineView_mouseDownInHeaderOfTableColumn_ , @selector(outlineView:mouseDownInHeaderOfTableColumn:),
|
|
||||||
CPOutlineViewDelegate_outlineView_nextTypeSelectMatchFromItem_toItem_forString_ , @selector(outlineView:nextTypeSelectMatchFromItem:toItem:forString:),
|
|
||||||
CPOutlineViewDelegate_outlineView_selectionIndexesForProposedSelection_ , @selector(outlineView:selectionIndexesForProposedSelection:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldCollapseItem_ , @selector(outlineView:shouldCollapseItem:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldEditTableColumn_item_ , @selector(outlineView:shouldEditTableColumn:item:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldExpandItem_ , @selector(outlineView:shouldExpandItem:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldReorderColumn_toColumn_ , @selector(outlineView:shouldReorderColumn:toColumn:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldSelectItem_ , @selector(outlineView:shouldSelectItem:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_ , @selector(outlineView:shouldSelectTableColumn:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldShowOutlineViewForItem_ , @selector(outlineView:shouldShowOutlineViewForItem:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldShowViewExpansionForTableColumn_item_ , @selector(outlineView:shouldShowViewExpansionForTableColumn:item:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldTrackView_forTableColumn_item_ , @selector(outlineView:shouldTrackView:forTableColumn:item:),
|
|
||||||
CPOutlineViewDelegate_outlineView_shouldTypeSelectForEvent_withCurrentSearchString_ , @selector(outlineView:shouldTypeSelectForEvent:withCurrentSearchString:),
|
|
||||||
CPOutlineViewDelegate_outlineView_sizeToFitWidthOfColumn_ , @selector(outlineView:sizeToFitWidthOfColumn:),
|
|
||||||
CPOutlineViewDelegate_outlineView_toolTipForView_rect_tableColumn_item_mouseLocation_, @selector(outlineView:toolTipForView:rect:tableColumn:item:mouseLocation:),
|
|
||||||
CPOutlineViewDelegate_outlineView_typeSelectStringForTableColumn_item_ , @selector(outlineView:typeSelectStringForTableColumn:item:),
|
|
||||||
CPOutlineViewDelegate_outlineView_willDisplayOutlineView_forTableColumn_item_ , @selector(outlineView:willDisplayOutlineView:forTableColumn:item:),
|
|
||||||
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ , @selector(outlineView:willDisplayView:forTableColumn:item:),
|
|
||||||
CPOutlineViewDelegate_selectionShouldChangeInOutlineView_ , @selector(selectionShouldChangeInOutlineView:)
|
|
||||||
],
|
|
||||||
delegateCount = [delegateMethods count];
|
|
||||||
|
|
||||||
for (var i=0; i < delegateCount; i += 2)
|
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:shouldSelectItem:)])
|
||||||
{
|
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_shouldSelectItem_;
|
||||||
var bitMask = delegateMethods[i],
|
|
||||||
selector = delegateMethods[i+1];
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:selector])
|
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:heightOfRowByItem:)])
|
||||||
_implementedOutlineViewDelegateMethods |= bitMask;
|
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_heightOfRowByItem_;
|
||||||
}
|
|
||||||
|
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:willDisplayView:forTableColumn:item:)])
|
||||||
|
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_;
|
||||||
|
|
||||||
|
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:isGroupItem:)])
|
||||||
|
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_isGroupItem_;
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewColumnDidMove:)])
|
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewColumnDidMove:)])
|
||||||
[defaultCenter
|
[defaultCenter
|
||||||
@@ -549,36 +500,6 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
selector:@selector(outlineViewSelectionIsChanging:)
|
selector:@selector(outlineViewSelectionIsChanging:)
|
||||||
name:CPOutlineViewSelectionIsChangingNotification
|
name:CPOutlineViewSelectionIsChangingNotification
|
||||||
object:self];
|
object:self];
|
||||||
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
|
|
||||||
[defaultCenter
|
|
||||||
addObserver:_outlineViewDelegate
|
|
||||||
selector:@selector(outlineViewItemWillExpand:)
|
|
||||||
name:CPOutlineViewItemWillExpandNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)])
|
|
||||||
[defaultCenter
|
|
||||||
addObserver:_outlineViewDelegate
|
|
||||||
selector:@selector(outlineViewItemDidExpand:)
|
|
||||||
name:CPOutlineViewItemDidExpandNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)])
|
|
||||||
[defaultCenter
|
|
||||||
addObserver:_outlineViewDelegate
|
|
||||||
selector:@selector(outlineViewItemWillCollapse:)
|
|
||||||
name:CPOutlineViewItemWillCollapseNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)])
|
|
||||||
[defaultCenter
|
|
||||||
addObserver:_outlineViewDelegate
|
|
||||||
selector:@selector(outlineViewItemDidCollapse:)
|
|
||||||
name:CPOutlineViewItemDidCollapseNotification
|
|
||||||
object:self];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)delegate
|
- (id)delegate
|
||||||
@@ -613,56 +534,11 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
|
|
||||||
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex
|
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex
|
||||||
{
|
{
|
||||||
if (_dropItem !== theItem && theIndex < 0 && [self isExpandable:theItem] && ![self isItemExpanded:theItem])
|
|
||||||
{
|
|
||||||
if (_dragHoverTimer)
|
|
||||||
[_dragHoverTimer invalidate];
|
|
||||||
|
|
||||||
var autoExpandCallBack = function(){
|
|
||||||
if (_dropItem)
|
|
||||||
{
|
|
||||||
[_dropOperationFeedbackView blink];
|
|
||||||
[CPTimer scheduledTimerWithTimeInterval:.3 callback:objj_msgSend(self, "expandItem:", _dropItem) repeats:NO];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_dragHoverTimer = [CPTimer scheduledTimerWithTimeInterval:.8 callback:autoExpandCallBack repeats:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theIndex >= 0)
|
|
||||||
{
|
|
||||||
[_dragHoverTimer invalidate];
|
|
||||||
_dragHoverTimer = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dropItem = theItem;
|
|
||||||
_retargetedItem = theItem;
|
_retargetedItem = theItem;
|
||||||
_shouldRetargetItem = YES;
|
_shouldRetargetItem = YES;
|
||||||
|
|
||||||
_retargedChildIndex = theIndex;
|
_retargedChildIndex = theIndex;
|
||||||
_shouldRetargetChildIndex = YES;
|
_shouldRetargetChildIndex = YES;
|
||||||
|
|
||||||
// set CPTableView's _retargetedDropRow based on retargetedItem and retargetedChildIndex
|
|
||||||
var retargetedItemInfo = (_retargetedItem !== nil) ? _itemInfosForItems[[_retargetedItem UID]] : _rootItemInfo;
|
|
||||||
|
|
||||||
if (_retargedChildIndex === [retargetedItemInfo.children count])
|
|
||||||
{
|
|
||||||
var retargetedChildItem = [retargetedItemInfo.children lastObject];
|
|
||||||
_retargetedDropRow = [self rowForItem:retargetedChildItem] + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var retargetedChildItem = (_retargedChildIndex !== CPOutlineViewDropOnItemIndex) ? retargetedItemInfo.children[_retargedChildIndex] : _retargetedItem;
|
|
||||||
_retargetedDropRow = [self rowForItem:retargetedChildItem];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_draggingEnded
|
|
||||||
{
|
|
||||||
[super _draggingEnded];
|
|
||||||
_dropItem = nil;
|
|
||||||
[_dragHoverTimer invalidate];
|
|
||||||
_dragHoverTimer = nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
|
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
|
||||||
@@ -743,8 +619,6 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
_disclosureControlsForRows[row] = control;
|
_disclosureControlsForRows[row] = control;
|
||||||
|
|
||||||
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
|
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
|
||||||
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
|
|
||||||
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
|
|
||||||
[control setFrame:frame];
|
[control setFrame:frame];
|
||||||
|
|
||||||
[self addSubview:control];
|
[self addSubview:control];
|
||||||
@@ -835,38 +709,6 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
userInfo:nil];
|
userInfo:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_noteItemWillExpand:(id)item
|
|
||||||
{
|
|
||||||
[[CPNotificationCenter defaultCenter]
|
|
||||||
postNotificationName:CPOutlineViewItemWillExpandNotification
|
|
||||||
object:self
|
|
||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_noteItemDidExpand:(id)item
|
|
||||||
{
|
|
||||||
[[CPNotificationCenter defaultCenter]
|
|
||||||
postNotificationName:CPOutlineViewItemDidExpandNotification
|
|
||||||
object:self
|
|
||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_noteItemWillCollapse:(id)item
|
|
||||||
{
|
|
||||||
[[CPNotificationCenter defaultCenter]
|
|
||||||
postNotificationName:CPOutlineViewItemWillCollapseNotification
|
|
||||||
object:self
|
|
||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_noteItemDidCollapse:(id)item
|
|
||||||
{
|
|
||||||
[[CPNotificationCenter defaultCenter]
|
|
||||||
postNotificationName:CPOutlineViewItemDidCollapseNotification
|
|
||||||
object:self
|
|
||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
|
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
|
||||||
@@ -1038,13 +880,6 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
return [_outlineView._outlineViewDataSource outlineView:_outlineView objectValueForTableColumn:aTableColumn byItem:_outlineView._itemsForRows[aRow]];
|
return [_outlineView._outlineViewDataSource outlineView:_outlineView objectValueForTableColumn:aTableColumn byItem:_outlineView._itemsForRows[aRow]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)tableView:(CPTableView)aTableView setObjectValue:(id)aValue forTableColumn:(CPTableColumn)aColumn row:(CPInteger)aRow
|
|
||||||
{
|
|
||||||
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_))
|
|
||||||
return;
|
|
||||||
[_outlineView._outlineViewDataSource outlineView:_outlineView setObjectValue:aValue forTableColumn:aColumn byItem:_outlineView._itemsForRows[aRow]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)tableView:(CPTableView)aTableColumn writeRowsWithIndexes:(CPIndexSet)theIndexes toPasteboard:(CPPasteboard)thePasteboard
|
- (BOOL)tableView:(CPTableView)aTableColumn writeRowsWithIndexes:(CPIndexSet)theIndexes toPasteboard:(CPPasteboard)thePasteboard
|
||||||
{
|
{
|
||||||
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_))
|
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_))
|
||||||
@@ -1108,7 +943,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
_outlineView._shouldRetargetChildIndex = NO;
|
_outlineView._shouldRetargetChildIndex = NO;
|
||||||
|
|
||||||
var location = [_outlineView convertPoint:[theInfo draggingLocation] fromView:nil],
|
var location = [_outlineView convertPoint:[theInfo draggingLocation] fromView:nil],
|
||||||
parentItem = [self _parentItemForDropOperation:theOperation row:theRow offset:location],
|
parentItem = [self _parentItemForDropOperation:theOperation row:theRow offset:location];
|
||||||
childIndex = [self _childIndexForDropOperation:theOperation row:theRow offset:location];
|
childIndex = [self _childIndexForDropOperation:theOperation row:theRow offset:location];
|
||||||
|
|
||||||
return [_outlineView._outlineViewDataSource outlineView:_outlineView validateDrop:theInfo proposedItem:parentItem proposedChildIndex:childIndex];
|
return [_outlineView._outlineViewDataSource outlineView:_outlineView validateDrop:theInfo proposedItem:parentItem proposedChildIndex:childIndex];
|
||||||
@@ -1172,14 +1007,6 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(int)aRow
|
|
||||||
{
|
|
||||||
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldEditTableColumn_item_))
|
|
||||||
return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldEditTableColumn:aColumn item:[_outlineView itemAtRow:aRow]];
|
|
||||||
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
|
- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
|
||||||
{
|
{
|
||||||
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
|
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
|
||||||
@@ -1197,10 +1024,10 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(int)aRow
|
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(int)row
|
||||||
{
|
{
|
||||||
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_isGroupItem_))
|
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_isGroupItem_))
|
||||||
return [_outlineView._outlineViewDelegate outlineView:_outlineView isGroupItem:[_outlineView itemAtRow:aRow]];
|
return [_outlineView._outlineViewDelegate outlineView:_outlineView isGroupItem:[_outlineView itemAtRow:theRow]];
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
@@ -1253,82 +1080,9 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
CGContextAddLineToPoint(context, 0.0, 0.0);
|
CGContextAddLineToPoint(context, 0.0, 0.0);
|
||||||
|
|
||||||
CGContextClosePath(context);
|
CGContextClosePath(context);
|
||||||
CGContextSetFillColor(context,
|
|
||||||
colorForDisclosureTriangle([self hasThemeState:CPThemeStateSelected],
|
CGContextSetFillColor(context, [self isHighlighted] ? [CPColor whiteColor] : [CPColor grayColor]);
|
||||||
[self hasThemeState:CPThemeStateHighlighted]));
|
|
||||||
CGContextFillPath(context);
|
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
|
@end
|
||||||
|
|
||||||
|
|
||||||
var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey",
|
|
||||||
CPOutlineViewOutlineTableColumnKey = @"CPOutlineViewOutlineTableColumnKey",
|
|
||||||
CPOutlineViewDataSourceKey = @"CPOutlineViewDataSourceKey",
|
|
||||||
CPOutlineViewDelegateKey = @"CPOutlineViewDelegateKey";
|
|
||||||
|
|
||||||
@implementation CPOutlineView (CPCoding)
|
|
||||||
|
|
||||||
- (id)initWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
self = [super initWithCoder:aCoder];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
// The root item has weight "0", thus represents the weight solely of its descendants.
|
|
||||||
_rootItemInfo = { isExpanded:YES, isExpandable:NO, level:-1, row:-1, children:[], weight:0 };
|
|
||||||
|
|
||||||
_itemsForRows = [];
|
|
||||||
_itemInfosForItems = { };
|
|
||||||
_disclosureControlsForRows = [];
|
|
||||||
|
|
||||||
[self setIndentationMarkerFollowsDataView:YES];
|
|
||||||
[self setDisclosureControlPrototype:[[CPDisclosureButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 10.0)]];
|
|
||||||
|
|
||||||
_outlineTableColumn = [aCoder decodeObjectForKey:CPOutlineViewOutlineTableColumnKey];
|
|
||||||
_indentationPerLevel = [aCoder decodeFloatForKey:CPOutlineViewIndentationPerLevelKey];
|
|
||||||
|
|
||||||
_outlineViewDataSource = [aCoder decodeObjectForKey:CPOutlineViewDataSourceKey];
|
|
||||||
_outlineViewDelegate = [aCoder decodeObjectForKey:CPOutlineViewDelegateKey];
|
|
||||||
|
|
||||||
[super setDataSource:[[_CPOutlineViewTableViewDataSource alloc] initWithOutlineView:self]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
|
||||||
{
|
|
||||||
[super encodeWithCoder:aCoder];
|
|
||||||
|
|
||||||
[aCoder encodeObject:_outlineTableColumn forKey:CPOutlineViewOutlineTableColumnKey];
|
|
||||||
[aCoder encodeFloat:_indentationPerLevel forKey:CPOutlineViewIndentationPerLevelKey];
|
|
||||||
|
|
||||||
[aCoder encodeObject:_outlineViewDataSource forKey:CPOutlineViewDataSourceKey];
|
|
||||||
[aCoder encodeObject:_outlineViewDelegate forKey:CPOutlineViewDelegateKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
@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]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
@import <Foundation/CPDictionary.j>
|
@import <Foundation/CPDictionary.j>
|
||||||
@import <Foundation/CPPropertyListSerialization.j>
|
@import <Foundation/CPPropertyListSerialization.j>
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
CPGeneralPboard = @"CPGeneralPboard";
|
CPGeneralPboard = @"CPGeneralPboard";
|
||||||
CPFontPboard = @"CPFontPboard";
|
CPFontPboard = @"CPFontPboard";
|
||||||
|
|||||||
+5
-29
@@ -25,6 +25,8 @@
|
|||||||
@import "CPMenu.j"
|
@import "CPMenu.j"
|
||||||
@import "CPMenuItem.j"
|
@import "CPMenuItem.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
var VISIBLE_MARGIN = 7.0;
|
var VISIBLE_MARGIN = 7.0;
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
CPMenu _menu;
|
CPMenu _menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return "popup-button";
|
return "popup-button";
|
||||||
}
|
}
|
||||||
@@ -394,13 +396,12 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
{
|
{
|
||||||
var titles = [],
|
var titles = [],
|
||||||
items = [self itemArray],
|
items = [self itemArray],
|
||||||
|
|
||||||
index = 0,
|
index = 0,
|
||||||
count = [items count];
|
count = [items count];
|
||||||
|
|
||||||
for (; index < count; ++index)
|
for (; index < count; ++index)
|
||||||
titles.push([items[index] title]);
|
items.push([items[index] title]);
|
||||||
|
|
||||||
return titles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -660,9 +661,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
location = CGPointMake(CGRectGetMinX(contentRect) - standardLeftMargin, 0.0);
|
location = CGPointMake(CGRectGetMinX(contentRect) - standardLeftMargin, 0.0);
|
||||||
|
|
||||||
minimumWidth += standardLeftMargin;
|
minimumWidth += standardLeftMargin;
|
||||||
|
|
||||||
// To ensure the selected item is highlighted correctly, unset the highlighted item
|
|
||||||
[menu _highlightItemAtIndex:CPNotFound];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[menu setMinimumWidth:minimumWidth];
|
[menu setMinimumWidth:minimumWidth];
|
||||||
@@ -700,33 +698,11 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)rightMouseDown:(CPEvent)anEvent
|
|
||||||
{
|
|
||||||
// Disable standard CPView behaviour which incorrectly displays the menu as a 'context menu'.
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_popUpItemAction:(id)aSender
|
- (void)_popUpItemAction:(id)aSender
|
||||||
{
|
{
|
||||||
[self sendAction:[self action] to:[self target]];
|
[self sendAction:[self action] to:[self target]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
var count = objects.length,
|
|
||||||
value = [objects[0] valueForKeyPath:aKeyPath];
|
|
||||||
|
|
||||||
[self selectItemWithTag:value];
|
|
||||||
[self setEnabled:YES];
|
|
||||||
|
|
||||||
while (count-- > 1)
|
|
||||||
{
|
|
||||||
if (value !== [objects[count] valueForKeyPath:aKeyPath])
|
|
||||||
{
|
|
||||||
[[self selectedItem] setState:CPOffState];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
|
var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
|
||||||
|
|||||||
@@ -20,9 +20,11 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CGGeometry.j"
|
@import <AppKit/CGGeometry.j>
|
||||||
@import "CPImageView.j"
|
@import <AppKit/CPImageView.j>
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+1
-5
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
@import "CPButton.j"
|
@import "CPButton.j"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
|
|
||||||
@@ -63,9 +62,6 @@
|
|||||||
option.
|
option.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CPRadioImageOffset = 4.0;
|
|
||||||
|
|
||||||
@implementation CPRadio : CPButton
|
@implementation CPRadio : CPButton
|
||||||
{
|
{
|
||||||
CPRadioGroup _radioGroup;
|
CPRadioGroup _radioGroup;
|
||||||
@@ -90,7 +86,7 @@ CPRadioImageOffset = 4.0;
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return @"radio";
|
return @"radio";
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-43
@@ -23,18 +23,17 @@
|
|||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
|
||||||
CPDeleteKeyCode = 8;
|
CPDeleteKeyCode = 8;
|
||||||
CPTabKeyCode = 9;
|
CPTabKeyCode = 9;
|
||||||
CPReturnKeyCode = 13;
|
CPReturnKeyCode = 13;
|
||||||
CPEscapeKeyCode = 27;
|
CPEscapeKeyCode = 27;
|
||||||
CPSpaceKeyCode = 32;
|
CPSpaceKeyCode = 32;
|
||||||
CPPageUpKeyCode = 33;
|
CPPageUpKeyCode = 33;
|
||||||
CPPageDownKeyCode = 34;
|
CPPageDownKeyCode = 34;
|
||||||
CPLeftArrowKeyCode = 37;
|
CPLeftArrowKeyCode = 37;
|
||||||
CPUpArrowKeyCode = 38;
|
CPUpArrowKeyCode = 38;
|
||||||
CPRightArrowKeyCode = 39;
|
CPRightArrowKeyCode = 39;
|
||||||
CPDownArrowKeyCode = 40;
|
CPDownArrowKeyCode = 40;
|
||||||
CPDeleteForwardKeyCode = 46;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -105,24 +104,42 @@ CPDeleteForwardKeyCode = 46;
|
|||||||
|
|
||||||
for (; index < count; ++index)
|
for (; index < count; ++index)
|
||||||
{
|
{
|
||||||
var event = events[index],
|
var event = events[index];
|
||||||
modifierFlags = [event modifierFlags],
|
|
||||||
character = [event charactersIgnoringModifiers],
|
|
||||||
selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags];
|
|
||||||
|
|
||||||
if (selectorNames)
|
switch([event keyCode])
|
||||||
{
|
{
|
||||||
for (var s = 0, scount = selectorNames.length; s < scount; s++)
|
case CPPageUpKeyCode: [self doCommandBySelector:@selector(pageUp:)];
|
||||||
{
|
break;
|
||||||
var selector = selectorNames[s];
|
case CPPageDownKeyCode: [self doCommandBySelector:@selector(pageDown:)];
|
||||||
if (!selector)
|
break;
|
||||||
continue;
|
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;
|
||||||
|
|
||||||
[self doCommandBySelector:CPSelectorFromString(selector)];
|
case CPEscapeKeyCode: [self doCommandBySelector:@selector(cancel:)];
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case CPTabKeyCode: var shift = [event modifierFlags] & CPShiftKeyMask;
|
||||||
|
|
||||||
|
if (!shift)
|
||||||
|
[self doCommandBySelector:@selector(insertTab:)];
|
||||||
|
else
|
||||||
|
[self doCommandBySelector:@selector(insertBackTab:)];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: [self insertText:[event characters]];
|
||||||
}
|
}
|
||||||
else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)) && [self respondsToSelector:@selector(insertText:)])
|
|
||||||
[self insertText:[event characters]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,15 +239,6 @@ CPDeleteForwardKeyCode = 46;
|
|||||||
[_nextResponder performSelector:_cmd withObject:anEvent];
|
[_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.
|
FIXME This description is bad.
|
||||||
Based on \c anEvent, the receiver should simulate the event.
|
Based on \c anEvent, the receiver should simulate the event.
|
||||||
@@ -261,6 +269,10 @@ CPDeleteForwardKeyCode = 46;
|
|||||||
[[self nextResponder] insertNewline:aSender];
|
[[self nextResponder] insertNewline:aSender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)cancel:(id)sender
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
- (void)insertTab:(id)sender
|
- (void)insertTab:(id)sender
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -300,7 +312,7 @@ CPDeleteForwardKeyCode = 46;
|
|||||||
*/
|
*/
|
||||||
- (BOOL)tryToPerform:(SEL)aSelector with:(id)anObject
|
- (BOOL)tryToPerform:(SEL)aSelector with:(id)anObject
|
||||||
{
|
{
|
||||||
if ([self respondsToSelector:aSelector])
|
if([self respondsToSelector:aSelector])
|
||||||
{
|
{
|
||||||
[self performSelector:aSelector withObject:anObject];
|
[self performSelector:aSelector withObject:anObject];
|
||||||
|
|
||||||
@@ -342,8 +354,7 @@ CPDeleteForwardKeyCode = 46;
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
|
var CPResponderNextResponderKey = @"CPResponderNextResponderKey";
|
||||||
CPResponderMenuKey = @"CPResponderMenuKey";
|
|
||||||
|
|
||||||
@implementation CPResponder (CPCoding)
|
@implementation CPResponder (CPCoding)
|
||||||
|
|
||||||
@@ -357,10 +368,7 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
|
||||||
_nextResponder = [aCoder decodeObjectForKey:CPResponderNextResponderKey];
|
_nextResponder = [aCoder decodeObjectForKey:CPResponderNextResponderKey];
|
||||||
_menu = [aCoder decodeObjectForKey:CPResponderMenuKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -374,8 +382,6 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
|
|||||||
// This will come out nil on the other side with decodeObjectForKey:
|
// This will come out nil on the other side with decodeObjectForKey:
|
||||||
if (_nextResponder !== nil)
|
if (_nextResponder !== nil)
|
||||||
[aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey];
|
[aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_menu forKey:CPResponderMenuKey];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
@import "CPPanel.j"
|
@import <AppKit/CPPanel.j>
|
||||||
|
|
||||||
|
|
||||||
@implementation CPSavePanel : CPPanel
|
@implementation CPSavePanel : CPPanel
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
#import "CoreGraphics/CGGeometry.h"
|
||||||
|
#import "Platform/Platform.h"
|
||||||
|
|
||||||
@implementation CPScreen : CPObject
|
@implementation CPScreen : CPObject
|
||||||
{
|
{
|
||||||
|
|||||||
+66
-356
@@ -20,10 +20,11 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPBox.j"
|
@import "CPView.j"
|
||||||
@import "CPClipView.j"
|
@import "CPClipView.j"
|
||||||
@import "CPScroller.j"
|
@import "CPScroller.j"
|
||||||
@import "CPView.j"
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -36,39 +37,23 @@
|
|||||||
*/
|
*/
|
||||||
@implementation CPScrollView : CPView
|
@implementation CPScrollView : CPView
|
||||||
{
|
{
|
||||||
CPClipView _contentView;
|
CPClipView _contentView;
|
||||||
CPClipView _headerClipView;
|
CPClipView _headerClipView;
|
||||||
CPView _cornerView;
|
CPView _cornerView;
|
||||||
CPView _bottomCornerView;
|
|
||||||
|
|
||||||
BOOL _hasVerticalScroller;
|
BOOL _hasVerticalScroller;
|
||||||
BOOL _hasHorizontalScroller;
|
BOOL _hasHorizontalScroller;
|
||||||
BOOL _autohidesScrollers;
|
BOOL _autohidesScrollers;
|
||||||
|
|
||||||
CPScroller _verticalScroller;
|
CPScroller _verticalScroller;
|
||||||
CPScroller _horizontalScroller;
|
CPScroller _horizontalScroller;
|
||||||
|
|
||||||
int _recursionCount;
|
int _recursionCount;
|
||||||
|
|
||||||
float _verticalLineScroll;
|
float _verticalLineScroll;
|
||||||
float _verticalPageScroll;
|
float _verticalPageScroll;
|
||||||
float _horizontalLineScroll;
|
float _horizontalLineScroll;
|
||||||
float _horizontalPageScroll;
|
float _horizontalPageScroll;
|
||||||
|
|
||||||
CPBorderType _borderType;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
|
||||||
{
|
|
||||||
return @"scrollview"
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPDictionary)themeAttributes
|
|
||||||
{
|
|
||||||
return [CPDictionary dictionaryWithJSObject:{
|
|
||||||
@"bottom-corner-color": [CPColor whiteColor],
|
|
||||||
@"border-color": [CPColor blackColor]
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -83,17 +68,13 @@
|
|||||||
_horizontalLineScroll = 10.0;
|
_horizontalLineScroll = 10.0;
|
||||||
_horizontalPageScroll = 10.0;
|
_horizontalPageScroll = 10.0;
|
||||||
|
|
||||||
_borderType = CPNoBorder;
|
_contentView = [[CPClipView alloc] initWithFrame:[self bounds]];
|
||||||
|
|
||||||
_contentView = [[CPClipView alloc] initWithFrame:[self _insetBounds]];
|
|
||||||
|
|
||||||
[self addSubview:_contentView];
|
[self addSubview:_contentView];
|
||||||
|
|
||||||
_headerClipView = [[CPClipView alloc] init];
|
_headerClipView = [[CPClipView alloc] init];
|
||||||
[self addSubview:_headerClipView];
|
|
||||||
|
|
||||||
_bottomCornerView = [[CPView alloc] init];
|
[self addSubview:_headerClipView];
|
||||||
[self addSubview:_bottomCornerView];
|
|
||||||
|
|
||||||
[self setHasVerticalScroller:YES];
|
[self setHasVerticalScroller:YES];
|
||||||
[self setHasHorizontalScroller:YES];
|
[self setHasHorizontalScroller:YES];
|
||||||
@@ -102,70 +83,11 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculating Layout
|
|
||||||
|
|
||||||
+ (CGSize)contentSizeForFrameSize:(CGSize)frameSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType
|
|
||||||
{
|
|
||||||
var bounds = [self _insetBounds:_CGRectMake(0.0, 0.0, frameSize.width, frameSize.height) borderType:borderType],
|
|
||||||
scrollerWidth = [CPScroller scrollerWidth];
|
|
||||||
|
|
||||||
if (hFlag)
|
|
||||||
bounds.size.height -= scrollerWidth;
|
|
||||||
|
|
||||||
if (vFlag)
|
|
||||||
bounds.size.width -= scrollerWidth;
|
|
||||||
|
|
||||||
return bounds.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CGSize)frameSizeForContentSize:(CGSize)contentSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType
|
|
||||||
{
|
|
||||||
var bounds = [self _insetBounds:_CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) borderType:borderType],
|
|
||||||
widthInset = contentSize.width - bounds.size.width,
|
|
||||||
heightInset = contentSize.height - bounds.size.height,
|
|
||||||
frameSize = _CGSizeMake(contentSize.width + widthInset, contentSize.height + heightInset),
|
|
||||||
scrollerWidth = [CPScroller scrollerWidth];
|
|
||||||
|
|
||||||
if (hFlag)
|
|
||||||
frameSize.height -= scrollerWidth;
|
|
||||||
|
|
||||||
if (vFlag)
|
|
||||||
frameSize.width -= scrollerWidth;
|
|
||||||
|
|
||||||
return frameSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CGRect)_insetBounds:(CGRect)bounds borderType:(CPBorderType)borderType
|
|
||||||
{
|
|
||||||
switch (borderType)
|
|
||||||
{
|
|
||||||
case CPLineBorder:
|
|
||||||
case CPBezelBorder:
|
|
||||||
return _CGRectInset(bounds, 1.0, 1.0);
|
|
||||||
|
|
||||||
case CPGrooveBorder:
|
|
||||||
bounds = _CGRectInset(bounds, 2.0, 2.0);
|
|
||||||
++bounds.origin.y;
|
|
||||||
--bounds.size.height;
|
|
||||||
|
|
||||||
return bounds;
|
|
||||||
|
|
||||||
case CPNoBorder:
|
|
||||||
default:
|
|
||||||
return bounds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGRect)_insetBounds
|
|
||||||
{
|
|
||||||
return [[self class] _insetBounds:[self bounds] borderType:_borderType];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determining component sizes
|
// Determining component sizes
|
||||||
/*!
|
/*!
|
||||||
Returns the size of the scroll view's content view.
|
Returns the size of the scroll view's content view.
|
||||||
*/
|
*/
|
||||||
- (CGSize)contentSize
|
- (CGRect)contentSize
|
||||||
{
|
{
|
||||||
return [_contentView frame].size;
|
return [_contentView frame].size;
|
||||||
}
|
}
|
||||||
@@ -184,7 +106,7 @@
|
|||||||
*/
|
*/
|
||||||
- (void)setContentView:(CPClipView)aContentView
|
- (void)setContentView:(CPClipView)aContentView
|
||||||
{
|
{
|
||||||
if (_contentView === aContentView || !aContentView)
|
if (_contentView !== aContentView || !aContentView)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var documentView = [aContentView documentView];
|
var documentView = [aContentView documentView];
|
||||||
@@ -231,7 +153,7 @@
|
|||||||
*/
|
*/
|
||||||
- (void)reflectScrolledClipView:(CPClipView)aClipView
|
- (void)reflectScrolledClipView:(CPClipView)aClipView
|
||||||
{
|
{
|
||||||
if (_contentView !== aClipView)
|
if(_contentView !== aClipView)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_recursionCount > 5)
|
if (_recursionCount > 5)
|
||||||
@@ -254,7 +176,7 @@
|
|||||||
// [_horizontalScroller setEnabled:NO];
|
// [_horizontalScroller setEnabled:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_contentView setFrame:[self _insetBounds]];
|
[_contentView setFrame:[self bounds]];
|
||||||
[_headerClipView setFrame:_CGRectMakeZero()];
|
[_headerClipView setFrame:_CGRectMakeZero()];
|
||||||
|
|
||||||
--_recursionCount;
|
--_recursionCount;
|
||||||
@@ -263,7 +185,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var documentFrame = [documentView frame], // the size of the whole document
|
var documentFrame = [documentView frame], // the size of the whole document
|
||||||
contentFrame = [self _insetBounds], // assume it takes up the entire size of the scrollview (no scrollers)
|
contentFrame = [self bounds], // assume it takes up the entire size of the scrollview (no scrollers)
|
||||||
headerClipViewFrame = [self _headerClipViewFrame],
|
headerClipViewFrame = [self _headerClipViewFrame],
|
||||||
headerClipViewHeight = _CGRectGetHeight(headerClipViewFrame);
|
headerClipViewHeight = _CGRectGetHeight(headerClipViewFrame);
|
||||||
|
|
||||||
@@ -313,10 +235,11 @@
|
|||||||
|
|
||||||
if (shouldShowVerticalScroller)
|
if (shouldShowVerticalScroller)
|
||||||
{
|
{
|
||||||
var verticalScrollerY =
|
var verticalScrollerY = MAX(_CGRectGetHeight([self _cornerViewFrame]), headerClipViewHeight),
|
||||||
MAX(_CGRectGetMinY(contentFrame), MAX(_CGRectGetMaxY([self _cornerViewFrame]), _CGRectGetMaxY(headerClipViewFrame)));
|
verticalScrollerHeight = _CGRectGetHeight([self bounds]) - verticalScrollerY;
|
||||||
|
|
||||||
var verticalScrollerHeight = _CGRectGetMaxY(contentFrame) - verticalScrollerY;
|
if (shouldShowHorizontalScroller)
|
||||||
|
verticalScrollerHeight -= horizontalScrollerHeight;
|
||||||
|
|
||||||
[_verticalScroller setFloatValue:(difference.height <= 0.0) ? 0.0 : scrollPoint.y / difference.height];
|
[_verticalScroller setFloatValue:(difference.height <= 0.0) ? 0.0 : scrollPoint.y / difference.height];
|
||||||
[_verticalScroller setKnobProportion:_CGRectGetHeight(contentFrame) / _CGRectGetHeight(documentFrame)];
|
[_verticalScroller setKnobProportion:_CGRectGetHeight(contentFrame) / _CGRectGetHeight(documentFrame)];
|
||||||
@@ -332,7 +255,7 @@
|
|||||||
{
|
{
|
||||||
[_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width];
|
[_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width];
|
||||||
[_horizontalScroller setKnobProportion:_CGRectGetWidth(contentFrame) / _CGRectGetWidth(documentFrame)];
|
[_horizontalScroller setKnobProportion:_CGRectGetWidth(contentFrame) / _CGRectGetWidth(documentFrame)];
|
||||||
[_horizontalScroller setFrame:_CGRectMake(_CGRectGetMinX(contentFrame), _CGRectGetMaxY(contentFrame), _CGRectGetWidth(contentFrame), horizontalScrollerHeight)];
|
[_horizontalScroller setFrame:_CGRectMake(0.0, _CGRectGetMaxY(contentFrame), _CGRectGetWidth(contentFrame), horizontalScrollerHeight)];
|
||||||
}
|
}
|
||||||
else if (wasShowingHorizontalScroller)
|
else if (wasShowingHorizontalScroller)
|
||||||
{
|
{
|
||||||
@@ -344,36 +267,9 @@
|
|||||||
[_headerClipView setFrame:headerClipViewFrame];
|
[_headerClipView setFrame:headerClipViewFrame];
|
||||||
[_cornerView setFrame:[self _cornerViewFrame]];
|
[_cornerView setFrame:[self _cornerViewFrame]];
|
||||||
|
|
||||||
[[self bottomCornerView] setFrame:[self _bottomCornerViewFrame]];
|
|
||||||
[[self bottomCornerView] setBackgroundColor:[self currentValueForThemeAttribute:@"bottom-corner-color"]];
|
|
||||||
|
|
||||||
--_recursionCount;
|
--_recursionCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Managing Graphics Attributes
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the type of border to be drawn around the view.
|
|
||||||
*/
|
|
||||||
- (void)setBorderType:(CPBorderType)borderType
|
|
||||||
{
|
|
||||||
if (_borderType == borderType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_borderType = borderType;
|
|
||||||
|
|
||||||
[self reflectScrolledClipView:_contentView];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the border type drawn around the view.
|
|
||||||
*/
|
|
||||||
- (CPBorderType)borderType
|
|
||||||
{
|
|
||||||
return _borderType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Managing Scrollers
|
// Managing Scrollers
|
||||||
/*!
|
/*!
|
||||||
Sets the scroll view's horizontal scroller.
|
Sets the scroll view's horizontal scroller.
|
||||||
@@ -420,10 +316,8 @@
|
|||||||
|
|
||||||
if (_hasHorizontalScroller && !_horizontalScroller)
|
if (_hasHorizontalScroller && !_horizontalScroller)
|
||||||
{
|
{
|
||||||
var bounds = [self _insetBounds];
|
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, MAX(_CGRectGetWidth([self bounds]), [CPScroller scrollerWidth]+1), [CPScroller scrollerWidth])]];
|
||||||
|
[[self horizontalScroller] setFrameSize:CGSizeMake(_CGRectGetWidth([self bounds]), [CPScroller scrollerWidth])];
|
||||||
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, MAX(_CGRectGetWidth(bounds), [CPScroller scrollerWidth] + 1), [CPScroller scrollerWidth])]];
|
|
||||||
[[self horizontalScroller] setFrameSize:CGSizeMake(_CGRectGetWidth(bounds), [CPScroller scrollerWidth])];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[self reflectScrolledClipView:_contentView];
|
[self reflectScrolledClipView:_contentView];
|
||||||
@@ -483,10 +377,8 @@
|
|||||||
|
|
||||||
if (_hasVerticalScroller && !_verticalScroller)
|
if (_hasVerticalScroller && !_verticalScroller)
|
||||||
{
|
{
|
||||||
var bounds = [self _insetBounds];
|
[self setVerticalScroller:[[CPScroller alloc] initWithFrame:_CGRectMake(0.0, 0.0, [CPScroller scrollerWidth], MAX(_CGRectGetHeight([self bounds]), [CPScroller scrollerWidth]+1))]];
|
||||||
|
[[self verticalScroller] setFrameSize:CGSizeMake([CPScroller scrollerWidth], _CGRectGetHeight([self bounds]))];
|
||||||
[self setVerticalScroller:[[CPScroller alloc] initWithFrame:_CGRectMake(0.0, 0.0, [CPScroller scrollerWidth], MAX(_CGRectGetHeight(bounds), [CPScroller scrollerWidth] + 1))]];
|
|
||||||
[[self verticalScroller] setFrameSize:CGSizeMake([CPScroller scrollerWidth], _CGRectGetHeight(bounds))];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[self reflectScrolledClipView:_contentView];
|
[self reflectScrolledClipView:_contentView];
|
||||||
@@ -553,7 +445,9 @@
|
|||||||
|
|
||||||
- (CPView)_headerView
|
- (CPView)_headerView
|
||||||
{
|
{
|
||||||
return [_headerClipView documentView];
|
var headerClipViewSubviews = [_headerClipView subviews];
|
||||||
|
|
||||||
|
return [headerClipViewSubviews count] ? headerClipViewSubviews[0] : nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)_cornerViewFrame
|
- (CGRect)_cornerViewFrame
|
||||||
@@ -561,11 +455,11 @@
|
|||||||
if (!_cornerView)
|
if (!_cornerView)
|
||||||
return _CGRectMakeZero();
|
return _CGRectMakeZero();
|
||||||
|
|
||||||
var bounds = [self _insetBounds],
|
var bounds = [self bounds],
|
||||||
frame = [_cornerView frame];
|
frame = [_cornerView frame];
|
||||||
|
|
||||||
frame.origin.x = _CGRectGetMaxX(bounds) - _CGRectGetWidth(frame);
|
frame.origin.x = _CGRectGetMaxX(bounds) - _CGRectGetWidth(frame);
|
||||||
frame.origin.y = _CGRectGetMinY(bounds);
|
frame.origin.y = 0;
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
@@ -577,7 +471,7 @@
|
|||||||
if (!headerView)
|
if (!headerView)
|
||||||
return _CGRectMakeZero();
|
return _CGRectMakeZero();
|
||||||
|
|
||||||
var frame = [self _insetBounds];
|
var frame = [self bounds];
|
||||||
|
|
||||||
frame.size.height = _CGRectGetHeight([headerView frame]);
|
frame.size.height = _CGRectGetHeight([headerView frame]);
|
||||||
frame.size.width -= _CGRectGetWidth([self _cornerViewFrame]);
|
frame.size.width -= _CGRectGetWidth([self _cornerViewFrame]);
|
||||||
@@ -585,47 +479,11 @@
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)_bottomCornerViewFrame
|
|
||||||
{
|
|
||||||
if ([[self horizontalScroller] isHidden] || [[self verticalScroller] isHidden])
|
|
||||||
return CGRectMakeZero();
|
|
||||||
|
|
||||||
var verticalFrame = [[self verticalScroller] frame],
|
|
||||||
bottomCornerFrame = CGRectMakeZero();
|
|
||||||
|
|
||||||
bottomCornerFrame.origin.x = CGRectGetMinX(verticalFrame);
|
|
||||||
bottomCornerFrame.origin.y = CGRectGetMaxY(verticalFrame);
|
|
||||||
bottomCornerFrame.size.width = [CPScroller scrollerWidth];
|
|
||||||
bottomCornerFrame.size.height = [CPScroller scrollerWidth];
|
|
||||||
|
|
||||||
return bottomCornerFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setBottomCornerView:(CPView)aBottomCornerView
|
|
||||||
{
|
|
||||||
if (_bottomCornerView === aBottomCornerView)
|
|
||||||
return;
|
|
||||||
|
|
||||||
[_bottomCornerView removeFromSuperview];
|
|
||||||
|
|
||||||
[aBottomCornerView setFrame:[self _bottomCornerViewFrame]];
|
|
||||||
[self addSubview:aBottomCornerView];
|
|
||||||
|
|
||||||
_bottomCornerView = aBottomCornerView;
|
|
||||||
|
|
||||||
[self _updateCornerAndHeaderView];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPView)bottomCornerView
|
|
||||||
{
|
|
||||||
return _bottomCornerView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @ignore */
|
/* @ignore */
|
||||||
- (void)_verticalScrollerDidScroll:(CPScroller)aScroller
|
- (void)_verticalScrollerDidScroll:(CPScroller)aScroller
|
||||||
{
|
{
|
||||||
var value = [aScroller floatValue],
|
var value = [aScroller floatValue],
|
||||||
documentFrame = [[_contentView documentView] frame],
|
documentFrame = [[_contentView documentView] frame];
|
||||||
contentBounds = [_contentView bounds];
|
contentBounds = [_contentView bounds];
|
||||||
|
|
||||||
switch ([_verticalScroller hitPart])
|
switch ([_verticalScroller hitPart])
|
||||||
@@ -696,7 +554,7 @@
|
|||||||
/*
|
/*
|
||||||
@ignore
|
@ignore
|
||||||
*/
|
*/
|
||||||
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
|
-(void)resizeSubviewsWithOldSize:(CGSize)aSize
|
||||||
{
|
{
|
||||||
[self reflectScrolledClipView:_contentView];
|
[self reflectScrolledClipView:_contentView];
|
||||||
}
|
}
|
||||||
@@ -806,169 +664,35 @@
|
|||||||
return _verticalPageScroll;
|
return _verticalPageScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPView Overrides
|
|
||||||
|
|
||||||
- (void)drawRect:(CPRect)aRect
|
|
||||||
{
|
|
||||||
[super drawRect:aRect];
|
|
||||||
|
|
||||||
if (_borderType == CPNoBorder)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var strokeRect = [self bounds],
|
|
||||||
context = [[CPGraphicsContext currentContext] graphicsPort];
|
|
||||||
|
|
||||||
CGContextSetLineWidth(context, 1);
|
|
||||||
|
|
||||||
switch (_borderType)
|
|
||||||
{
|
|
||||||
case CPLineBorder:
|
|
||||||
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"border-color"]);
|
|
||||||
CGContextStrokeRect(context, _CGRectInset(strokeRect, 0.5, 0.5));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPBezelBorder:
|
|
||||||
[self _drawGrayBezelInContext:context bounds:strokeRect];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPGrooveBorder:
|
|
||||||
[self _drawGrooveInContext:context bounds:strokeRect];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_drawGrayBezelInContext:(CGContext)context bounds:(CGRect)aRect
|
|
||||||
{
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:142.0 / 255.0 alpha:1.0]);
|
|
||||||
|
|
||||||
var y = _CGRectGetMinY(aRect) + 0.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, _CGRectGetMinX(aRect), y);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMinX(aRect) + 1.0, y);
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0 / 255.0 alpha:1.0]);
|
|
||||||
CGContextMoveToPoint(context, _CGRectGetMinX(aRect) + 1.0, y);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMaxX(aRect) - 1.0, y);
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:142.0 / 255.0 alpha:1.0]);
|
|
||||||
CGContextMoveToPoint(context, _CGRectGetMaxX(aRect) - 1.0, y);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMaxX(aRect), y);
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:190.0 / 255.0 alpha:1.0]);
|
|
||||||
|
|
||||||
var x = _CGRectGetMaxX(aRect) - 0.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, x, _CGRectGetMinY(aRect) + 1.0);
|
|
||||||
CGContextAddLineToPoint(context, x, _CGRectGetMaxY(aRect));
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, x - 0.5, _CGRectGetMaxY(aRect) - 0.5);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMinX(aRect), _CGRectGetMaxY(aRect) - 0.5);
|
|
||||||
|
|
||||||
x = _CGRectGetMinX(aRect) + 0.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, x, _CGRectGetMaxY(aRect));
|
|
||||||
CGContextAddLineToPoint(context, x, _CGRectGetMinY(aRect) + 1.0);
|
|
||||||
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_drawGrooveInContext:(CGContext)context bounds:(CGRect)aRect
|
|
||||||
{
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:159.0 / 255.0 alpha:1.0]);
|
|
||||||
|
|
||||||
var y = _CGRectGetMinY(aRect) + 0.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, _CGRectGetMinX(aRect), y);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMaxX(aRect), y);
|
|
||||||
|
|
||||||
var x = _CGRectGetMaxX(aRect) - 1.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, x, _CGRectGetMinY(aRect) + 2.0);
|
|
||||||
CGContextAddLineToPoint(context, x, _CGRectGetMaxY(aRect) - 1.0);
|
|
||||||
|
|
||||||
y = _CGRectGetMaxY(aRect) - 1.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, _CGRectGetMaxX(aRect) - 1.0, y);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMinX(aRect) + 2.0, y);
|
|
||||||
|
|
||||||
x = _CGRectGetMinX(aRect) + 0.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, x, _CGRectGetMaxY(aRect));
|
|
||||||
CGContextAddLineToPoint(context, x, _CGRectGetMinY(aRect));
|
|
||||||
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor whiteColor]);
|
|
||||||
|
|
||||||
var rect = _CGRectOffset(aRect, 1.0, 1.0);
|
|
||||||
|
|
||||||
rect.size.width -= 1.0;
|
|
||||||
rect.size.height -= 1.0;
|
|
||||||
CGContextStrokeRect(context, _CGRectInset(rect, 0.5, 0.5));
|
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0 / 255.0 alpha:1.0]);
|
|
||||||
|
|
||||||
y = _CGRectGetMinY(aRect) + 2.5;
|
|
||||||
|
|
||||||
CGContextMoveToPoint(context, _CGRectGetMinX(aRect) + 2.0, y);
|
|
||||||
CGContextAddLineToPoint(context, _CGRectGetMaxX(aRect) - 2.0, y);
|
|
||||||
CGContextStrokePath(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// CPResponder Overrides
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Handles a scroll wheel event from the user.
|
Handles a scroll wheel event from the user.
|
||||||
@param anEvent the scroll wheel event
|
@param anEvent the scroll wheel event
|
||||||
*/
|
*/
|
||||||
- (void)scrollWheel:(CPEvent)anEvent
|
- (void)scrollWheel:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
[self _respondToScrollWheelEventWithDeltaX:[anEvent deltaX] deltaY:[anEvent deltaY]];
|
var documentFrame = [[self documentView] frame],
|
||||||
}
|
contentBounds = [_contentView bounds];
|
||||||
|
|
||||||
- (void)_respondToScrollWheelEventWithDeltaX:(float)deltaX deltaY:(float)deltaY
|
|
||||||
{
|
|
||||||
var documentFrame = [[self documentView] frame],
|
|
||||||
contentBounds = [_contentView bounds],
|
|
||||||
contentFrame = [_contentView frame],
|
|
||||||
enclosingScrollView = [self enclosingScrollView];
|
|
||||||
|
|
||||||
// We want integral bounds!
|
// We want integral bounds!
|
||||||
contentBounds.origin.x = ROUND(contentBounds.origin.x + deltaX);
|
contentBounds.origin.x = ROUND(contentBounds.origin.x + [anEvent deltaX] * _horizontalLineScroll);
|
||||||
contentBounds.origin.y = ROUND(contentBounds.origin.y + deltaY);
|
contentBounds.origin.y = ROUND(contentBounds.origin.y + [anEvent deltaY] * _verticalLineScroll);
|
||||||
|
|
||||||
var constrainedOrigin = [_contentView constrainScrollPoint:CGPointCreateCopy(contentBounds.origin)],
|
[_contentView scrollToPoint:contentBounds.origin];
|
||||||
extraX = contentBounds.origin.x - constrainedOrigin.x,
|
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)];
|
||||||
extraY = contentBounds.origin.y - constrainedOrigin.y;
|
|
||||||
|
|
||||||
[_contentView scrollToPoint:constrainedOrigin];
|
|
||||||
[_headerClipView scrollToPoint:CGPointMake(constrainedOrigin.x, 0.0)];
|
|
||||||
|
|
||||||
if (extraX || extraY)
|
|
||||||
[enclosingScrollView _respondToScrollWheelEventWithDeltaX:extraX deltaY:extraY];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollPageUp:(id)sender
|
- (void)keyDown:(CPEvent)anEvent
|
||||||
|
{
|
||||||
|
[self interpretKeyEvents:[anEvent]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pageUp:(id)sender
|
||||||
{
|
{
|
||||||
var contentBounds = [_contentView bounds];
|
var contentBounds = [_contentView bounds];
|
||||||
[self moveByOffset:CGSizeMake(0.0, -(_CGRectGetHeight(contentBounds) - _verticalPageScroll))];
|
[self moveByOffset:CGSizeMake(0.0, -(_CGRectGetHeight(contentBounds) - _verticalPageScroll))];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollPageDown:(id)sender
|
- (void)pageDown:(id)sender
|
||||||
{
|
{
|
||||||
var contentBounds = [_contentView bounds];
|
var contentBounds = [_contentView bounds];
|
||||||
[self moveByOffset:CGSizeMake(0.0, _CGRectGetHeight(contentBounds) - _verticalPageScroll)];
|
[self moveByOffset:CGSizeMake(0.0, _CGRectGetHeight(contentBounds) - _verticalPageScroll)];
|
||||||
@@ -1008,20 +732,18 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPScrollViewContentViewKey = @"CPScrollViewContentView",
|
var CPScrollViewContentViewKey = "CPScrollViewContentView",
|
||||||
CPScrollViewHeaderClipViewKey = @"CPScrollViewHeaderClipViewKey",
|
CPScrollViewHeaderClipViewKey = "CPScrollViewHeaderClipViewKey",
|
||||||
CPScrollViewVLineScrollKey = @"CPScrollViewVLineScroll",
|
CPScrollViewVLineScrollKey = "CPScrollViewVLineScroll",
|
||||||
CPScrollViewHLineScrollKey = @"CPScrollViewHLineScroll",
|
CPScrollViewHLineScrollKey = "CPScrollViewHLineScroll",
|
||||||
CPScrollViewVPageScrollKey = @"CPScrollViewVPageScroll",
|
CPScrollViewVPageScrollKey = "CPScrollViewVPageScroll",
|
||||||
CPScrollViewHPageScrollKey = @"CPScrollViewHPageScroll",
|
CPScrollViewHPageScrollKey = "CPScrollViewHPageScroll",
|
||||||
CPScrollViewHasVScrollerKey = @"CPScrollViewHasVScroller",
|
CPScrollViewHasVScrollerKey = "CPScrollViewHasVScroller",
|
||||||
CPScrollViewHasHScrollerKey = @"CPScrollViewHasHScroller",
|
CPScrollViewHasHScrollerKey = "CPScrollViewHasHScroller",
|
||||||
CPScrollViewVScrollerKey = @"CPScrollViewVScroller",
|
CPScrollViewVScrollerKey = "CPScrollViewVScroller",
|
||||||
CPScrollViewHScrollerKey = @"CPScrollViewHScroller",
|
CPScrollViewHScrollerKey = "CPScrollViewHScroller",
|
||||||
CPScrollViewAutohidesScrollerKey = @"CPScrollViewAutohidesScroller",
|
CPScrollViewAutohidesScrollerKey = "CPScrollViewAutohidesScroller",
|
||||||
CPScrollViewCornerViewKey = @"CPScrollViewCornerViewKey",
|
CPScrollViewCornerViewKey = "CPScrollViewCornerViewKey";
|
||||||
CPScrollViewBottomCornerViewKey = @"CPScrollViewBottomCornerViewKey",
|
|
||||||
CPScrollViewBorderTypeKey = @"CPScrollViewBorderTypeKey";
|
|
||||||
|
|
||||||
@implementation CPScrollView (CPCoding)
|
@implementation CPScrollView (CPCoding)
|
||||||
|
|
||||||
@@ -1038,12 +760,6 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
|
|||||||
_contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey];
|
_contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey];
|
||||||
_headerClipView = [aCoder decodeObjectForKey:CPScrollViewHeaderClipViewKey];
|
_headerClipView = [aCoder decodeObjectForKey:CPScrollViewHeaderClipViewKey];
|
||||||
|
|
||||||
if (!_headerClipView)
|
|
||||||
{
|
|
||||||
_headerClipView = [[CPClipView alloc] init];
|
|
||||||
[self addSubview:_headerClipView];
|
|
||||||
}
|
|
||||||
|
|
||||||
_verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey];
|
_verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey];
|
||||||
_horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey];
|
_horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey];
|
||||||
|
|
||||||
@@ -1051,10 +767,7 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
|
|||||||
_hasHorizontalScroller = [aCoder decodeBoolForKey:CPScrollViewHasHScrollerKey];
|
_hasHorizontalScroller = [aCoder decodeBoolForKey:CPScrollViewHasHScrollerKey];
|
||||||
_autohidesScrollers = [aCoder decodeBoolForKey:CPScrollViewAutohidesScrollerKey];
|
_autohidesScrollers = [aCoder decodeBoolForKey:CPScrollViewAutohidesScrollerKey];
|
||||||
|
|
||||||
_borderType = [aCoder decodeIntForKey:CPScrollViewBorderTypeKey];
|
|
||||||
|
|
||||||
_cornerView = [aCoder decodeObjectForKey:CPScrollViewCornerViewKey];
|
_cornerView = [aCoder decodeObjectForKey:CPScrollViewCornerViewKey];
|
||||||
_bottomCornerView = [aCoder decodeObjectForKey:CPScrollViewBottomCornerViewKey];
|
|
||||||
|
|
||||||
// Do to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state.
|
// Do to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state.
|
||||||
[[CPRunLoop currentRunLoop] performSelector:@selector(reflectScrolledClipView:) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]];
|
[[CPRunLoop currentRunLoop] performSelector:@selector(reflectScrolledClipView:) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]];
|
||||||
@@ -1083,9 +796,6 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
|
|||||||
[aCoder encodeBool:_autohidesScrollers forKey:CPScrollViewAutohidesScrollerKey];
|
[aCoder encodeBool:_autohidesScrollers forKey:CPScrollViewAutohidesScrollerKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_cornerView forKey:CPScrollViewCornerViewKey];
|
[aCoder encodeObject:_cornerView forKey:CPScrollViewCornerViewKey];
|
||||||
[aCoder encodeObject:_bottomCornerView forKey:CPScrollViewBottomCornerViewKey];
|
|
||||||
|
|
||||||
[aCoder encodeInt:_borderType forKey:CPScrollViewBorderTypeKey];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+22
-34
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
@import "CPControl.j"
|
@import "CPControl.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
// CPScroller Constants
|
// CPScroller Constants
|
||||||
CPScrollerNoPart = 0;
|
CPScrollerNoPart = 0;
|
||||||
@@ -70,25 +72,24 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
CGPoint _trackingStartPoint;
|
CGPoint _trackingStartPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return "scroller";
|
return "scroller";
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)themeAttributes
|
+ (id)themeAttributes
|
||||||
{
|
{
|
||||||
return [CPDictionary dictionaryWithJSObject:{
|
return [CPDictionary dictionaryWithObjects:[ [CPNull null], [CPNull null], [CPNull null], [CPNull null],
|
||||||
@"scroller-width": 15.0,
|
_CGSizeMakeZero(), _CGSizeMakeZero(), _CGInsetMakeZero(), _CGInsetMakeZero(), _CGSizeMakeZero()]
|
||||||
@"knob-slot-color": [CPColor lightGrayColor],
|
forKeys:[ @"knob-slot-color",
|
||||||
@"decrement-line-color": [CPNull null],
|
@"decrement-line-color",
|
||||||
@"increment-line-color": [CPNull null],
|
@"increment-line-color",
|
||||||
@"knob-color": [CPColor grayColor],
|
@"knob-color",
|
||||||
@"decrement-line-size":_CGSizeMakeZero(),
|
@"decrement-line-size",
|
||||||
@"increment-line-size":_CGSizeMakeZero(),
|
@"increment-line-size",
|
||||||
@"track-inset":_CGInsetMakeZero(),
|
@"track-inset",
|
||||||
@"knob-inset": _CGInsetMakeZero(),
|
@"knob-inset",
|
||||||
@"minimum-knob-length":21.0
|
@"minimum-knob-length"]];
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
*/
|
*/
|
||||||
+ (float)scrollerWidth
|
+ (float)scrollerWidth
|
||||||
{
|
{
|
||||||
return [[[CPScroller alloc] init] currentValueForThemeAttribute:@"scroller-width"];
|
return 15.0;//[self scrollerWidthForControlSize:CPRegularControlSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -129,7 +130,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
*/
|
*/
|
||||||
+ (float)scrollerWidthForControlSize:(CPControlSize)aControlSize
|
+ (float)scrollerWidthForControlSize:(CPControlSize)aControlSize
|
||||||
{
|
{
|
||||||
return [self scrollerWidth];
|
return 15.0;//_CPScrollerWidths[aControlSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -280,10 +281,10 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
|
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
|
||||||
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
|
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
|
||||||
|
|
||||||
if (height < knobHeight + decrementLineSize.height + incrementLineSize.height + trackInset.top + trackInset.bottom)
|
if(height < knobHeight + decrementLineSize.height + incrementLineSize.height + trackInset.top + trackInset.bottom)
|
||||||
_partRects[CPScrollerKnob] = _CGRectMakeZero();
|
_partRects[CPScrollerKnob] = _CGRectMakeZero();
|
||||||
|
|
||||||
if (height < decrementLineSize.height + incrementLineSize.height - 2)
|
if(height < decrementLineSize.height + incrementLineSize.height - 2)
|
||||||
{
|
{
|
||||||
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
|
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
|
||||||
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
|
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
|
||||||
@@ -295,7 +296,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"],
|
var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"],
|
||||||
incrementLineSize = [self currentValueForThemeAttribute:"increment-line-size"],
|
incrementLineSize = [self currentValueForThemeAttribute:"increment-line-size"],
|
||||||
effectiveDecrementLineWidth = decrementLineSize.width + trackInset.left,
|
effectiveDecrementLineWidth = decrementLineSize.width + trackInset.left,
|
||||||
effectiveIncrementLineWidth = incrementLineSize.width + trackInset.right,
|
effectiveIncrementLineWidth = incrementLineSize.width + trackInset.right;
|
||||||
slotWidth = width - effectiveDecrementLineWidth - effectiveIncrementLineWidth,
|
slotWidth = width - effectiveDecrementLineWidth - effectiveIncrementLineWidth,
|
||||||
minimumKnobLength = [self currentValueForThemeAttribute:"minimum-knob-length"],
|
minimumKnobLength = [self currentValueForThemeAttribute:"minimum-knob-length"],
|
||||||
knobWidth = MAX(minimumKnobLength, (slotWidth * _knobProportion)),
|
knobWidth = MAX(minimumKnobLength, (slotWidth * _knobProportion)),
|
||||||
@@ -309,10 +310,10 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
|
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
|
||||||
_partRects[CPScrollerIncrementLine] = _CGRectMake(width - incrementLineSize.width, 0.0, incrementLineSize.width, incrementLineSize.height);
|
_partRects[CPScrollerIncrementLine] = _CGRectMake(width - incrementLineSize.width, 0.0, incrementLineSize.width, incrementLineSize.height);
|
||||||
|
|
||||||
if (width < knobWidth + decrementLineSize.width + incrementLineSize.width + trackInset.left + trackInset.right)
|
if(width < knobWidth + decrementLineSize.width + incrementLineSize.width + trackInset.left + trackInset.right)
|
||||||
_partRects[CPScrollerKnob] = _CGRectMakeZero();
|
_partRects[CPScrollerKnob] = _CGRectMakeZero();
|
||||||
|
|
||||||
if (width < decrementLineSize.width + incrementLineSize.width - 2)
|
if(width < decrementLineSize.width + incrementLineSize.width - 2)
|
||||||
{
|
{
|
||||||
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
|
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
|
||||||
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
|
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
|
||||||
@@ -449,7 +450,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
|
|||||||
[self setFloatValue:0.0];
|
[self setFloatValue:0.0];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
var location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||||
delta = ![self isVertical] ? location.x - _trackingStartPoint.x : location.y - _trackingStartPoint.y;
|
delta = ![self isVertical] ? location.x - _trackingStartPoint.x : location.y - _trackingStartPoint.y;
|
||||||
|
|
||||||
[self setFloatValue:_trackingFloatValue + delta / remainder];
|
[self setFloatValue:_trackingFloatValue + delta / remainder];
|
||||||
@@ -606,19 +607,6 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
|
|||||||
_hitPart = CPScrollerNoPart;
|
_hitPart = CPScrollerNoPart;
|
||||||
|
|
||||||
[self _calculateIsVertical];
|
[self _calculateIsVertical];
|
||||||
|
|
||||||
// Adjust the size of the scroller if the size from cib
|
|
||||||
// isn't equal to the scrollerWidth
|
|
||||||
var frame = [self frame],
|
|
||||||
scrollerWidth = [CPScroller scrollerWidth];
|
|
||||||
|
|
||||||
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
|
|
||||||
frame.size.width = scrollerWidth;
|
|
||||||
|
|
||||||
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
|
|
||||||
frame.size.height = scrollerWidth;
|
|
||||||
|
|
||||||
[self setFrame:frame];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
+120
-223
@@ -20,28 +20,20 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPButton.j"
|
|
||||||
@import "CPTextField.j"
|
@import "CPTextField.j"
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
CPSearchFieldRecentsTitleMenuItemTag = 1000;
|
CPSearchFieldRecentsTitleMenuItemTag = 1000;
|
||||||
CPSearchFieldRecentsMenuItemTag = 1001;
|
CPSearchFieldRecentsMenuItemTag = 1001;
|
||||||
CPSearchFieldClearRecentsMenuItemTag = 1002;
|
CPSearchFieldClearRecentsMenuItemTag = 1002;
|
||||||
CPSearchFieldNoRecentsMenuItemTag = 1003;
|
CPSearchFieldNoRecentsMenuItemTag = 1003;
|
||||||
CPSearchFieldSeparatorMenuItemTag = 1004;
|
|
||||||
|
|
||||||
var CPSearchFieldSearchImage = nil,
|
var CPSearchFieldSearchImage = nil,
|
||||||
CPSearchFieldFindImage = nil,
|
CPSearchFieldFindImage = nil,
|
||||||
CPSearchFieldCancelImage = nil,
|
CPSearchFieldCancelImage = nil,
|
||||||
CPSearchFieldCancelPressedImage = nil;
|
CPSearchFieldCancelPressedImage = nil;
|
||||||
|
|
||||||
var SEARCH_BUTTON_DEFAULT_WIDTH = 25.0,
|
|
||||||
CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
|
|
||||||
BUTTON_DEFAULT_HEIGHT = 22.0;
|
|
||||||
|
|
||||||
var RECENT_SEARCH_PREFIX = @" ";
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPSearchField
|
@class CPSearchField
|
||||||
@@ -62,37 +54,32 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
int _maximumRecents;
|
int _maximumRecents;
|
||||||
BOOL _sendsWholeSearchString;
|
BOOL _sendsWholeSearchString;
|
||||||
BOOL _sendsSearchStringImmediately;
|
BOOL _sendsSearchStringImmediately;
|
||||||
BOOL _canResignFirstResponder;
|
|
||||||
CPTimer _partialStringTimer;
|
CPTimer _partialStringTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
|
||||||
{
|
|
||||||
return @"searchfield"
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initialize
|
+ (void)initialize
|
||||||
{
|
{
|
||||||
if (self != [CPSearchField class])
|
if (self != [CPSearchField class])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bundle = [CPBundle bundleForClass:self];
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
|
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:CGSizeMake(25, 22)];
|
||||||
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
|
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:CGSizeMake(25, 22)];
|
||||||
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
|
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:CGSizeMake(22, 22)];
|
||||||
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
|
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:CGSizeMake(22, 22)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)frame
|
- (id)initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
if (self = [super initWithFrame:frame])
|
if (self = [super initWithFrame:frame])
|
||||||
{
|
{
|
||||||
|
_recentSearches = [CPArray array];
|
||||||
_maximumRecents = 10;
|
_maximumRecents = 10;
|
||||||
_sendsWholeSearchString = NO;
|
_sendsWholeSearchString = NO;
|
||||||
_sendsSearchStringImmediately = NO;
|
_sendsSearchStringImmediately = NO;
|
||||||
_recentsAutosaveName = nil;
|
_recentsAutosaveName = nil;
|
||||||
|
|
||||||
[self _init];
|
[self _initWithFrame:frame];
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
_cancelButton._DOMElement.style.cursor = "default";
|
_cancelButton._DOMElement.style.cursor = "default";
|
||||||
_searchButton._DOMElement.style.cursor = "default";
|
_searchButton._DOMElement.style.cursor = "default";
|
||||||
@@ -102,28 +89,23 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_init
|
- (void)_initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
_recentSearches = [CPArray array];
|
|
||||||
|
|
||||||
[self setBezeled:YES];
|
[self setBezeled:YES];
|
||||||
[self setBezelStyle:CPTextFieldRoundedBezel];
|
[self setBezelStyle:CPTextFieldRoundedBezel];
|
||||||
[self setBordered:YES];
|
[self setBordered:YES];
|
||||||
[self setEditable:YES];
|
[self setEditable:YES];
|
||||||
[self setDelegate:self];
|
[self setDelegate:self];
|
||||||
[self setContinuous:YES];
|
|
||||||
|
|
||||||
var bounds = [self bounds],
|
_cancelButton = [[CPButton alloc] initWithFrame:CGRectMake(frame.size.width - 27,(frame.size.height-22)/2,22,22)];
|
||||||
cancelButton = [[CPButton alloc] initWithFrame:[self cancelButtonRectForBounds:bounds]],
|
|
||||||
searchButton = [[CPButton alloc] initWithFrame:[self searchButtonRectForBounds:bounds]];
|
|
||||||
|
|
||||||
[self setCancelButton:cancelButton];
|
|
||||||
[self resetCancelButton];
|
[self resetCancelButton];
|
||||||
|
[_cancelButton setHidden:YES];
|
||||||
|
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
|
||||||
|
[self addSubview:_cancelButton];
|
||||||
|
|
||||||
[self setSearchButton:searchButton];
|
_searchButton = [[CPButton alloc] initWithFrame:CGRectMake(5,(frame.size.height-25)/2,25,25)];
|
||||||
[self resetSearchButton];
|
[self resetSearchButton];
|
||||||
|
[self addSubview:_searchButton];
|
||||||
_canResignFirstResponder = YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Managing Buttons
|
// Managing Buttons
|
||||||
@@ -133,15 +115,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
*/
|
*/
|
||||||
- (void)setSearchButton:(CPButton)button
|
- (void)setSearchButton:(CPButton)button
|
||||||
{
|
{
|
||||||
if (button != _searchButton)
|
_searchButton = button;
|
||||||
{
|
|
||||||
[_searchButton removeFromSuperview];
|
|
||||||
_searchButton = button;
|
|
||||||
|
|
||||||
[_searchButton setFrame:[self searchButtonRectForBounds:[self bounds]]];
|
|
||||||
[_searchButton setAutoresizingMask:CPViewMaxXMargin];
|
|
||||||
[self addSubview:_searchButton];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -159,13 +133,30 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
*/
|
*/
|
||||||
- (void)resetSearchButton
|
- (void)resetSearchButton
|
||||||
{
|
{
|
||||||
var button = [self searchButton],
|
var searchButtonImage,
|
||||||
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
|
action,
|
||||||
|
target,
|
||||||
|
button = [self searchButton];
|
||||||
|
|
||||||
|
if (_searchMenuTemplate === nil)
|
||||||
|
{
|
||||||
|
searchButtonImage = CPSearchFieldSearchImage;
|
||||||
|
action = @selector(_sendAction:);
|
||||||
|
target = self;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
searchButtonImage = CPSearchFieldFindImage;
|
||||||
|
action = @selector(_showMenu:);
|
||||||
|
target = self;
|
||||||
|
}
|
||||||
|
|
||||||
[button setBordered:NO];
|
[button setBordered:NO];
|
||||||
[button setImageScaling:CPScaleToFit];
|
[button setImageScaling:CPScaleToFit];
|
||||||
[button setImage:searchButtonImage];
|
[button setImage:searchButtonImage];
|
||||||
[button setAutoresizingMask:CPViewMaxXMargin];
|
[button setAutoresizingMask:CPViewMaxXMargin];
|
||||||
|
[button setTarget:target];
|
||||||
|
[button setAction:action];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -174,18 +165,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
*/
|
*/
|
||||||
- (void)setCancelButton:(CPButton)button
|
- (void)setCancelButton:(CPButton)button
|
||||||
{
|
{
|
||||||
if (button != _cancelButton)
|
_cancelButton = button;
|
||||||
{
|
|
||||||
[_cancelButton removeFromSuperview];
|
|
||||||
_cancelButton = button;
|
|
||||||
|
|
||||||
[_cancelButton setFrame:[self cancelButtonRectForBounds:[self bounds]]];
|
|
||||||
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
|
|
||||||
[_cancelButton setTarget:self];
|
|
||||||
[_cancelButton setAction:@selector(_searchFieldCancel:)];
|
|
||||||
[self _updateCancelButtonVisibility];
|
|
||||||
[self addSubview:_cancelButton];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -220,25 +200,23 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@return The updated bounding rectangle to use for the search text field. The default value is the value passed into the rect parameter.
|
@return The updated bounding rectangle to use for the search text field. The default value is the value passed into the rect parameter.
|
||||||
Subclasses can override this method to return a new bounding rectangle for the text-field object. You might use this method to provide a custom layout for the search field control.
|
Subclasses can override this method to return a new bounding rectangle for the text-field object. You might use this method to provide a custom layout for the search field control.
|
||||||
*/
|
*/
|
||||||
- (CGRect)searchTextRectForBounds:(CGRect)rect
|
- (CPRect)searchTextRectForBounds:(CPRect)rect
|
||||||
{
|
{
|
||||||
var leftOffset = 0,
|
var leftOffset = 0, width = rect.size.width;
|
||||||
width = _CGRectGetWidth(rect),
|
|
||||||
bounds = [self bounds];
|
|
||||||
|
|
||||||
if (_searchButton)
|
if (_searchButton)
|
||||||
{
|
{
|
||||||
var searchBounds = [self searchButtonRectForBounds:bounds];
|
var searchRect = [_searchButton frame];
|
||||||
leftOffset = _CGRectGetMaxX(searchBounds) + 2;
|
leftOffset = searchRect.origin.x + searchRect.size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cancelButton)
|
if (_cancelButton)
|
||||||
{
|
{
|
||||||
var cancelRect = [self cancelButtonRectForBounds:bounds];
|
var cancelRect = [_cancelButton frame];
|
||||||
width = _CGRectGetMinX(cancelRect) - leftOffset;
|
width = cancelRect.origin.x - leftOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _CGRectMake(leftOffset, _CGRectGetMinY(rect), width, _CGRectGetHeight(rect));
|
return CPMakeRect(leftOffset,rect.origin.y,width,rect.size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -246,9 +224,9 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@param rect The current bounding rectangle for the search button.
|
@param rect The current bounding rectangle for the search button.
|
||||||
Subclasses can override this method to return a new bounding rectangle for the search button. You might use this method to provide a custom layout for the search field control.
|
Subclasses can override this method to return a new bounding rectangle for the search button. You might use this method to provide a custom layout for the search field control.
|
||||||
*/
|
*/
|
||||||
- (CGRect)searchButtonRectForBounds:(CGRect)rect
|
- (CPRect)searchButtonRectForBounds:(CPRect)rect
|
||||||
{
|
{
|
||||||
return _CGRectMake(5, (_CGRectGetHeight(rect) - BUTTON_DEFAULT_HEIGHT) / 2, SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT);
|
return [_searchButton frame];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -256,9 +234,9 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@param rect The updated bounding rectangle to use for the cancel button. The default value is the value passed into the rect parameter.
|
@param rect The updated bounding rectangle to use for the cancel button. The default value is the value passed into the rect parameter.
|
||||||
Subclasses can override this method to return a new bounding rectangle for the cancel button. You might use this method to provide a custom layout for the search field control.
|
Subclasses can override this method to return a new bounding rectangle for the cancel button. You might use this method to provide a custom layout for the search field control.
|
||||||
*/
|
*/
|
||||||
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
|
- (CPRect)cancelButtonRectForBounds:(CPRect)rect
|
||||||
{
|
{
|
||||||
return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
|
return [_cancelButton frame];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Managing Menu Templates
|
// Managing Menu Templates
|
||||||
@@ -276,9 +254,9 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@param menu The menu template to use.
|
@param menu The menu template to use.
|
||||||
The receiver looks for the tag constants described in ŇMenu tagsÓ to determine how to populate the menu with items related to recent searches. See ŇConfiguring a Search MenuÓ for a sample of how you might set up the search menu template.
|
The receiver looks for the tag constants described in ŇMenu tagsÓ to determine how to populate the menu with items related to recent searches. See ŇConfiguring a Search MenuÓ for a sample of how you might set up the search menu template.
|
||||||
*/
|
*/
|
||||||
- (void)setSearchMenuTemplate:(CPMenu)aMenu
|
- (void)setSearchMenuTemplate:(CPMenu)menu
|
||||||
{
|
{
|
||||||
_searchMenuTemplate = aMenu;
|
_searchMenuTemplate = menu;
|
||||||
|
|
||||||
[self resetSearchButton];
|
[self resetSearchButton];
|
||||||
[self _loadRecentSearchList];
|
[self _loadRecentSearchList];
|
||||||
@@ -395,7 +373,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
// Private methods and subclassing
|
// Private methods and subclassing
|
||||||
|
|
||||||
- (CGRect)contentRectForBounds:(CGRect)bounds
|
- (CPRect)contentRectForBounds:(CPRect)bounds
|
||||||
{
|
{
|
||||||
var superbounds = [super contentRectForBounds:bounds];
|
var superbounds = [super contentRectForBounds:bounds];
|
||||||
return [self searchTextRectForBounds:superbounds];
|
return [self searchTextRectForBounds:superbounds];
|
||||||
@@ -469,78 +447,37 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
[self _updateSearchMenu];
|
[self _updateSearchMenu];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPView)hitTest:(CGPoint)aPoint
|
- (BOOL)trackMouse:(CPEvent)event
|
||||||
{
|
{
|
||||||
// Make sure a hit anywhere within the search field returns the search field itself
|
var rect,
|
||||||
if (_CGRectContainsPoint([self frame], aPoint))
|
point,
|
||||||
return self;
|
location = [event locationInWindow];
|
||||||
else
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)resignFirstResponder
|
point = [self convertPoint:location fromView:nil];
|
||||||
{
|
|
||||||
return _canResignFirstResponder && [super resignFirstResponder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)mouseDown:(CPEvent)anEvent
|
rect = [self searchButtonRectForBounds:[self frame]];
|
||||||
{
|
if (CPRectContainsPoint(rect,point))
|
||||||
var location = [anEvent locationInWindow],
|
|
||||||
point = [self convertPoint:location fromView:nil];
|
|
||||||
|
|
||||||
if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
|
|
||||||
{
|
{
|
||||||
if (_searchMenuTemplate == nil)
|
return [[self searchButton] trackMouse:event];
|
||||||
[self _sendAction:self];
|
|
||||||
else
|
|
||||||
[self _showMenu];
|
|
||||||
}
|
}
|
||||||
else if (_CGRectContainsPoint([self cancelButtonRectForBounds:[self bounds]], point))
|
|
||||||
[_cancelButton mouseDown:anEvent];
|
rect = [self cancelButtonRectForBounds:[self frame]];
|
||||||
else
|
if (CPRectContainsPoint(rect,point))
|
||||||
[super mouseDown:anEvent];
|
{
|
||||||
|
return [[self cancelButton] trackMouse:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [super trackMouse:event];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
- (CPMenu)_defaultSearchMenuTemplate
|
||||||
Provides the common case items for a recent searches menu. If there are not recent searches,
|
|
||||||
displays a single disabled item:
|
|
||||||
|
|
||||||
No Recent Searches
|
|
||||||
|
|
||||||
If there are 1 more recent searches, it displays:
|
|
||||||
|
|
||||||
Recent Searches
|
|
||||||
recent search 1
|
|
||||||
recent search 2
|
|
||||||
etc.
|
|
||||||
---------------------
|
|
||||||
Clear Recent Searches
|
|
||||||
|
|
||||||
If you wish to add items before or after the template, you can. If you put items
|
|
||||||
before, a separator will automatically be placed before the default template item.
|
|
||||||
If you add items after the default template, it is your responsibility to add a separator.
|
|
||||||
|
|
||||||
To add a custom item:
|
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"google"
|
|
||||||
action:@selector(google:)
|
|
||||||
keyEquivalent:@""];
|
|
||||||
[item setTag:700];
|
|
||||||
[item setTarget:self];
|
|
||||||
[template addItem:item];
|
|
||||||
|
|
||||||
Be sure that your custom items do not use tags in the range 1000-1004 inclusive.
|
|
||||||
If you wish to maintain state in custom menu items that you add, you will need to maintain
|
|
||||||
the item state yourself, then in the action method of the custom items, modify the items
|
|
||||||
in the search menu template and send [searchField setSearchMenuTemplate:template] to update the menu.
|
|
||||||
*/
|
|
||||||
- (CPMenu)defaultSearchMenuTemplate
|
|
||||||
{
|
{
|
||||||
var template = [[CPMenu alloc] init],
|
var template, item;
|
||||||
item;
|
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"Recent Searches"
|
template = [[CPMenu alloc] init];
|
||||||
action:nil
|
|
||||||
|
item = [[CPMenuItem alloc] initWithTitle:@"Recent searches"
|
||||||
|
action:NULL
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldRecentsTitleMenuItemTag];
|
[item setTag:CPSearchFieldRecentsTitleMenuItemTag];
|
||||||
[item setEnabled:NO];
|
[item setEnabled:NO];
|
||||||
@@ -553,15 +490,15 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"Clear Recent Searches"
|
item = [[CPMenuItem alloc] initWithTitle:@"Clear recent searches"
|
||||||
action:@selector(_searchFieldClearRecents:)
|
action:@selector(_searchFieldClearRecents:)
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
|
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"No Recent Searches"
|
item = [[CPMenuItem alloc] initWithTitle:@"No recent searches"
|
||||||
action:nil
|
action:NULL
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldNoRecentsMenuItemTag];
|
[item setTag:CPSearchFieldNoRecentsMenuItemTag];
|
||||||
[item setEnabled:NO];
|
[item setEnabled:NO];
|
||||||
@@ -575,96 +512,61 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
if (_searchMenuTemplate === nil)
|
if (_searchMenuTemplate === nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var menu = [[CPMenu alloc] init],
|
var i, menu = [[CPMenu alloc] init],
|
||||||
countOfRecents = [_recentSearches count],
|
countOfRecents = [_recentSearches count],
|
||||||
numberOfItems = [_searchMenuTemplate numberOfItems];
|
numberOfItems = [_searchMenuTemplate numberOfItems];
|
||||||
|
|
||||||
for (var i = 0; i < numberOfItems; i++)
|
for (i = 0; i < numberOfItems; i++)
|
||||||
{
|
{
|
||||||
var item = [[_searchMenuTemplate itemAtIndex:i] copy];
|
var item = [_searchMenuTemplate itemAtIndex:i],
|
||||||
|
tag = [item tag];
|
||||||
|
|
||||||
switch ([item tag])
|
if (!(tag === CPSearchFieldRecentsTitleMenuItemTag && countOfRecents === 0) &&
|
||||||
|
!(tag === CPSearchFieldClearRecentsMenuItemTag && countOfRecents === 0) &&
|
||||||
|
!(tag === CPSearchFieldNoRecentsMenuItemTag && countOfRecents != 0) &&
|
||||||
|
!(tag === CPSearchFieldRecentsMenuItemTag))
|
||||||
{
|
{
|
||||||
case CPSearchFieldRecentsTitleMenuItemTag:
|
var itemAction, itemTarget;
|
||||||
if (countOfRecents === 0)
|
switch (tag)
|
||||||
continue;
|
|
||||||
|
|
||||||
if ([menu numberOfItems] > 0)
|
|
||||||
[self _addSeparatorToMenu:menu];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPSearchFieldRecentsMenuItemTag:
|
|
||||||
{
|
{
|
||||||
var itemAction = @selector(_searchFieldSearch:);
|
case CPSearchFieldRecentsTitleMenuItemTag : itemAction = NULL; itemTarget = NULL; break;
|
||||||
|
case CPSearchFieldClearRecentsMenuItemTag : itemAction = @selector(_searchFieldClearRecents:); itemTarget = self; break;
|
||||||
for (var recentIndex = 0; recentIndex < countOfRecents; ++recentIndex)
|
case CPSearchFieldNoRecentsMenuItemTag : itemAction = NULL; itemTarget = NULL; break;
|
||||||
{
|
default: itemAction = [item action]; itemTarget = [item target]; break;
|
||||||
// RECENT_SEARCH_PREFIX is a hack until CPMenuItem -setIndentationLevel works
|
|
||||||
var recentItem = [[CPMenuItem alloc] initWithTitle:RECENT_SEARCH_PREFIX + [_recentSearches objectAtIndex:recentIndex]
|
|
||||||
action:itemAction
|
|
||||||
keyEquivalent:[item keyEquivalent]];
|
|
||||||
[item setTarget:self];
|
|
||||||
[menu addItem:recentItem];
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case CPSearchFieldClearRecentsMenuItemTag:
|
if (tag === CPSearchFieldClearRecentsMenuItemTag || tag === CPSearchFieldRecentsTitleMenuItemTag)
|
||||||
if (countOfRecents === 0)
|
{
|
||||||
continue;
|
var separator = [CPMenuItem separatorItem];
|
||||||
|
[separator setEnabled:NO];
|
||||||
|
[menu addItem:separator];
|
||||||
|
}
|
||||||
|
|
||||||
if ([menu numberOfItems] > 0)
|
var templateItem = [[CPMenuItem alloc] initWithTitle:[item title]
|
||||||
[self _addSeparatorToMenu:menu];
|
action:itemAction
|
||||||
|
keyEquivalent:[item keyEquivalent]];
|
||||||
[item setAction:@selector(_searchFieldClearRecents:)];
|
[templateItem setTarget:itemTarget];
|
||||||
[item setTarget:self];
|
[templateItem setEnabled:([item isEnabled] && itemAction != NULL)];
|
||||||
break;
|
[templateItem setTag:tag];
|
||||||
|
[menu addItem:templateItem];
|
||||||
case CPSearchFieldNoRecentsMenuItemTag:
|
}
|
||||||
if (countOfRecents !== 0)
|
else if (tag === CPSearchFieldRecentsMenuItemTag)
|
||||||
continue;
|
{
|
||||||
|
var j;
|
||||||
if ([menu numberOfItems] > 0)
|
for (j = 0; j < countOfRecents; j++)
|
||||||
[self _addSeparatorToMenu:menu];
|
{
|
||||||
break;
|
var rencentItem = [[CPMenuItem alloc] initWithTitle:[_recentSearches objectAtIndex:j]
|
||||||
|
action:@selector(_searchFieldSearch:)
|
||||||
case CPSearchFieldSeparatorMenuItemTag:
|
keyEquivalent:[item keyEquivalent]];
|
||||||
item = [CPMenuItem separatorItem];
|
[rencentItem setTarget:self];
|
||||||
[item setEnabled:NO];
|
[menu addItem:rencentItem];
|
||||||
[menu addItem:item];
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[item setEnabled:([item isEnabled] && [item action] != nil && [item target] != nil)];
|
|
||||||
[menu addItem:item];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[menu setDelegate:self];
|
|
||||||
|
|
||||||
_searchMenu = menu;
|
_searchMenu = menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_addSeparatorToMenu:(CPMenu)aMenu
|
- (void)_showMenu:(id)sender
|
||||||
{
|
|
||||||
var separator = [CPMenuItem separatorItem];
|
|
||||||
[separator setEnabled:NO];
|
|
||||||
[aMenu addItem:separator];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)menuWillOpen:(CPMenu)menu
|
|
||||||
{
|
|
||||||
_canResignFirstResponder = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)menuDidClose:(CPMenu)menu
|
|
||||||
{
|
|
||||||
_canResignFirstResponder = YES;
|
|
||||||
|
|
||||||
[self becomeFirstResponder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_showMenu
|
|
||||||
{
|
{
|
||||||
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
|
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
|
||||||
return;
|
return;
|
||||||
@@ -674,14 +576,12 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
|
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
|
||||||
|
|
||||||
[self selectAll:nil];
|
[CPMenu popUpContextMenu:_searchMenu withEvent:anEvent forView:sender];
|
||||||
[CPMenu popUpContextMenu:_searchMenu withEvent:anEvent forView:self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_sendPartialString
|
- (void)_sendPartialString
|
||||||
{
|
{
|
||||||
[super sendAction:[self action] to:[self target]];
|
[[self target] performSelector:[self action] withObject:self];
|
||||||
[_partialStringTimer invalidate];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_searchFieldCancel:(id)sender
|
- (void)_searchFieldCancel:(id)sender
|
||||||
@@ -693,14 +593,13 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
- (void)_searchFieldSearch:(id)sender
|
- (void)_searchFieldSearch:(id)sender
|
||||||
{
|
{
|
||||||
var searchString = [[sender title] substringFromIndex:[RECENT_SEARCH_PREFIX length]];
|
var searchString = [sender title];
|
||||||
|
|
||||||
if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
|
if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
|
||||||
[self _addStringToRecentSearches:searchString];
|
[self _addStringToRecentSearches:searchString];
|
||||||
|
|
||||||
[self setObjectValue:searchString];
|
[self setObjectValue:searchString];
|
||||||
[self _sendPartialString];
|
[self _sendPartialString];
|
||||||
[self selectAll:nil];
|
|
||||||
|
|
||||||
[self _updateCancelButtonVisibility];
|
[self _updateCancelButtonVisibility];
|
||||||
}
|
}
|
||||||
@@ -709,8 +608,6 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
[self setRecentSearches:[CPArray array]];
|
[self setRecentSearches:[CPArray array]];
|
||||||
[self _updateSearchMenu];
|
[self _updateSearchMenu];
|
||||||
[self setStringValue:@""];
|
|
||||||
[self _updateCancelButtonVisibility];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_registerForAutosaveNotification
|
- (void)_registerForAutosaveNotification
|
||||||
@@ -793,7 +690,6 @@ var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
|
|||||||
|
|
||||||
if (_recentsAutosaveName)
|
if (_recentsAutosaveName)
|
||||||
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
|
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
|
||||||
|
|
||||||
if (_searchMenuTemplate)
|
if (_searchMenuTemplate)
|
||||||
[coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
|
[coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
|
||||||
}
|
}
|
||||||
@@ -802,17 +698,18 @@ var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
|
|||||||
{
|
{
|
||||||
if (self = [super initWithCoder:coder])
|
if (self = [super initWithCoder:coder])
|
||||||
{
|
{
|
||||||
|
[self _initWithFrame:[self frame]];
|
||||||
|
|
||||||
_recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey];
|
_recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey];
|
||||||
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
|
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
|
||||||
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
|
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
|
||||||
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
|
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
|
||||||
|
|
||||||
var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
|
var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
|
||||||
|
|
||||||
if (template)
|
if (template)
|
||||||
[self setSearchMenuTemplate:template];
|
[self setSearchMenuTemplate:template];
|
||||||
|
|
||||||
[self _init];
|
[self setDelegate:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
@import "CPTextField.j"
|
@import "CPTextField.j"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
*/
|
*/
|
||||||
|
|||||||
+75
-74
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
@import "CPControl.j"
|
@import "CPControl.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
CPSegmentSwitchTrackingSelectOne = 0;
|
CPSegmentSwitchTrackingSelectOne = 0;
|
||||||
CPSegmentSwitchTrackingSelectAny = 1;
|
CPSegmentSwitchTrackingSelectAny = 1;
|
||||||
@@ -48,7 +49,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
BOOL _trackingHighlighted;
|
BOOL _trackingHighlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return "segmented-control";
|
return "segmented-control";
|
||||||
}
|
}
|
||||||
@@ -81,7 +82,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (int)selectedTag
|
- (int)selectedTag
|
||||||
{
|
{
|
||||||
return [_segments[_selectedSegment] tag];
|
return _segments[_selectedSegment].tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specifying the number of segments
|
// Specifying the number of segments
|
||||||
@@ -182,7 +183,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
selected = NO;
|
selected = NO;
|
||||||
|
|
||||||
for (; index < _segments.length; ++index)
|
for (; index < _segments.length; ++index)
|
||||||
if ([_segments[index] selected])
|
if (_segments[index].selected)
|
||||||
if (selected)
|
if (selected)
|
||||||
[self setSelected:NO forSegment:index];
|
[self setSelected:NO forSegment:index];
|
||||||
else
|
else
|
||||||
@@ -194,7 +195,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
var index = 0;
|
var index = 0;
|
||||||
|
|
||||||
for (; index < _segments.length; ++index)
|
for (; index < _segments.length; ++index)
|
||||||
if ([_segments[index] selected])
|
if (_segments[index].selected)
|
||||||
[self setSelected:NO forSegment:index];
|
[self setSelected:NO forSegment:index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +217,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)setWidth:(float)aWidth forSegment:(unsigned)aSegment
|
- (void)setWidth:(float)aWidth forSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
[_segments[aSegment] setWidth:aWidth];
|
_segments[aSegment].width = aWidth;
|
||||||
|
|
||||||
[self tileWithChangedSegment:aSegment];
|
[self tileWithChangedSegment:aSegment];
|
||||||
}
|
}
|
||||||
@@ -228,7 +229,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (float)widthForSegment:(unsigned)aSegment
|
- (float)widthForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] width];
|
return _segments[aSegment].width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -239,7 +240,9 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)setImage:(CPImage)anImage forSegment:(unsigned)aSegment
|
- (void)setImage:(CPImage)anImage forSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
[_segments[aSegment] setImage:anImage];
|
var segment = _segments[aSegment];
|
||||||
|
|
||||||
|
segment.image = anImage;
|
||||||
|
|
||||||
[self tileWithChangedSegment:aSegment];
|
[self tileWithChangedSegment:aSegment];
|
||||||
}
|
}
|
||||||
@@ -251,7 +254,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (CPImage)imageForSegment:(unsigned)aSegment
|
- (CPImage)imageForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] image];
|
return _segments[aSegment].image;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -262,7 +265,9 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)setLabel:(CPString)aLabel forSegment:(unsigned)aSegment
|
- (void)setLabel:(CPString)aLabel forSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
[_segments[aSegment] setLabel:aLabel];
|
var segment = _segments[aSegment];
|
||||||
|
|
||||||
|
_segments[aSegment].label = aLabel;
|
||||||
|
|
||||||
[self tileWithChangedSegment:aSegment];
|
[self tileWithChangedSegment:aSegment];
|
||||||
}
|
}
|
||||||
@@ -274,7 +279,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (CPString)labelForSegment:(unsigned)aSegment
|
- (CPString)labelForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] label];
|
return _segments[aSegment].label;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -285,7 +290,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)setMenu:(CPMenu)aMenu forSegment:(unsigned)aSegment
|
- (void)setMenu:(CPMenu)aMenu forSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
[_segments[aSegment] setMenu:aMenu];
|
_segments[aSegment].menu = aMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -295,7 +300,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (CPMenu)menuForSegment:(unsigned)aSegment
|
- (CPMenu)menuForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] menu];
|
return _segments[aSegment].menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -310,10 +315,10 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
var segment = _segments[aSegment];
|
var segment = _segments[aSegment];
|
||||||
|
|
||||||
// If we're already in this state, bail.
|
// If we're already in this state, bail.
|
||||||
if ([segment selected] == isSelected)
|
if (segment.selected == isSelected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[segment setSelected:isSelected];
|
segment.selected = isSelected;
|
||||||
|
|
||||||
_themeStates[aSegment] = isSelected ? CPThemeStateSelected : CPThemeStateNormal;
|
_themeStates[aSegment] = isSelected ? CPThemeStateSelected : CPThemeStateNormal;
|
||||||
|
|
||||||
@@ -326,7 +331,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
|
|
||||||
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1)
|
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1)
|
||||||
{
|
{
|
||||||
[_segments[oldSelectedSegment] setSelected:NO];
|
_segments[oldSelectedSegment].selected = NO;
|
||||||
_themeStates[oldSelectedSegment] = CPThemeStateNormal;
|
_themeStates[oldSelectedSegment] = CPThemeStateNormal;
|
||||||
|
|
||||||
[self drawSegmentBezel:oldSelectedSegment highlight:NO];
|
[self drawSegmentBezel:oldSelectedSegment highlight:NO];
|
||||||
@@ -347,7 +352,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (BOOL)isSelectedForSegment:(unsigned)aSegment
|
- (BOOL)isSelectedForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] selected];
|
return _segments[aSegment].selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -358,8 +363,6 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
|
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
[_segments[aSegment] setEnabled:isEnabled];
|
|
||||||
|
|
||||||
if (isEnabled)
|
if (isEnabled)
|
||||||
_themeStates[aSegment] &= ~CPThemeStateDisabled;
|
_themeStates[aSegment] &= ~CPThemeStateDisabled;
|
||||||
else
|
else
|
||||||
@@ -376,7 +379,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (BOOL)isEnabledForSegment:(unsigned)aSegment
|
- (BOOL)isEnabledForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] enabled];
|
return !(_themeStates[aSegment] & CPThemeStateDisabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -386,7 +389,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (void)setTag:(int)aTag forSegment:(unsigned)aSegment
|
- (void)setTag:(int)aTag forSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
[_segments[aSegment] setTag:aTag];
|
_segments[aSegment].tag = aTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -395,7 +398,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
*/
|
*/
|
||||||
- (int)tagForSegment:(unsigned)aSegment
|
- (int)tagForSegment:(unsigned)aSegment
|
||||||
{
|
{
|
||||||
return [_segments[aSegment] tag];
|
return _segments[aSegment].tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drawings
|
// Drawings
|
||||||
@@ -458,7 +461,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
else if (aName.indexOf("segment-bezel") === 0)
|
else if (aName.indexOf("segment-bezel") === 0)
|
||||||
{
|
{
|
||||||
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
|
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
|
||||||
frame = CGRectCreateCopy([_segments[segment] frame]);
|
frame = CGRectCreateCopy(_segments[segment].frame);
|
||||||
|
|
||||||
if (segment === 0)
|
if (segment === 0)
|
||||||
{
|
{
|
||||||
@@ -492,7 +495,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
|
|
||||||
- (CPView)createEphemeralSubviewNamed:(CPString)aName
|
- (CPView)createEphemeralSubviewNamed:(CPString)aName
|
||||||
{
|
{
|
||||||
if ([aName hasPrefix:@"segment-content"])
|
if (aName.substring(0, "segment-content".length) == "segment-content")
|
||||||
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
|
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
|
||||||
|
|
||||||
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
|
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
|
||||||
@@ -508,9 +511,9 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
themeState |= _themeState & CPThemeStateDisabled;
|
themeState |= _themeState & CPThemeStateDisabled;
|
||||||
|
|
||||||
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
|
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
|
||||||
inState:themeState],
|
inState:themeState];
|
||||||
|
|
||||||
leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
|
var leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
|
||||||
positioned:CPWindowBelow
|
positioned:CPWindowBelow
|
||||||
relativeToEphemeralSubviewNamed:nil];
|
relativeToEphemeralSubviewNamed:nil];
|
||||||
|
|
||||||
@@ -521,38 +524,40 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
themeState |= _themeState & CPThemeStateDisabled;
|
themeState |= _themeState & CPThemeStateDisabled;
|
||||||
|
|
||||||
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
|
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
|
||||||
inState:themeState],
|
inState:themeState];
|
||||||
|
|
||||||
rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
|
var rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
|
||||||
positioned:CPWindowBelow
|
positioned:CPWindowBelow
|
||||||
relativeToEphemeralSubviewNamed:nil];
|
relativeToEphemeralSubviewNamed:nil];
|
||||||
|
|
||||||
[rightBezelView setBackgroundColor:rightCapColor];
|
[rightBezelView setBackgroundColor:rightCapColor];
|
||||||
|
|
||||||
for (var i = 0, count = _themeStates.length; i < count; i++)
|
for (var i=0, count = _themeStates.length; i<count; i++)
|
||||||
{
|
{
|
||||||
var themeState = _themeStates[i];
|
var themeState = _themeStates[i];
|
||||||
|
|
||||||
themeState |= _themeState & CPThemeStateDisabled;
|
themeState |= _themeState & CPThemeStateDisabled;
|
||||||
|
|
||||||
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
|
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
|
||||||
inState:themeState],
|
inState:themeState];
|
||||||
|
|
||||||
bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-" + i
|
var bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-"+i
|
||||||
positioned:CPWindowBelow
|
positioned:CPWindowBelow
|
||||||
relativeToEphemeralSubviewNamed:nil];
|
relativeToEphemeralSubviewNamed:nil];
|
||||||
|
|
||||||
[bezelView setBackgroundColor:bezelColor];
|
[bezelView setBackgroundColor:bezelColor];
|
||||||
|
|
||||||
|
|
||||||
// layout image/title views
|
//layout image/title views
|
||||||
var segment = _segments[i],
|
var segment = _segments[i];
|
||||||
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
|
|
||||||
positioned:CPWindowAbove
|
|
||||||
relativeToEphemeralSubviewNamed:@"segment-bezel-" + i];
|
|
||||||
|
|
||||||
[contentView setText:[segment label]];
|
|
||||||
[contentView setImage:[segment image]];
|
var contentView = [self layoutEphemeralSubviewNamed:@"segment-content-"+i
|
||||||
|
positioned:CPWindowAbove
|
||||||
|
relativeToEphemeralSubviewNamed:@"segment-bezel-"+i];
|
||||||
|
|
||||||
|
[contentView setText:segment.label];
|
||||||
|
[contentView setImage:segment.image];
|
||||||
|
|
||||||
[contentView setFont:[self valueForThemeAttribute:@"font" inState:themeState]];
|
[contentView setFont:[self valueForThemeAttribute:@"font" inState:themeState]];
|
||||||
[contentView setTextColor:[self valueForThemeAttribute:@"text-color" inState:themeState]];
|
[contentView setTextColor:[self valueForThemeAttribute:@"text-color" inState:themeState]];
|
||||||
@@ -563,24 +568,24 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
[contentView setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset" inState:themeState]];
|
[contentView setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset" inState:themeState]];
|
||||||
[contentView setImageScaling:[self valueForThemeAttribute:@"image-scaling" inState:themeState]];
|
[contentView setImageScaling:[self valueForThemeAttribute:@"image-scaling" inState:themeState]];
|
||||||
|
|
||||||
if ([segment image] && [segment label])
|
if (segment.image && segment.label)
|
||||||
[contentView setImagePosition:[self valueForThemeAttribute:@"image-position" inState:themeState]];
|
[contentView setImagePosition:[self valueForThemeAttribute:@"image-position" inState:themeState]];
|
||||||
else if ([segment image])
|
else if (segment.image)
|
||||||
[contentView setImagePosition:CPImageOnly];
|
[contentView setImagePosition:CPImageOnly];
|
||||||
|
|
||||||
if (i == count - 1)
|
if (i == count - 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var borderState = _themeStates[i] | _themeStates[i + 1];
|
var borderState = _themeStates[i] | _themeStates[i+1];
|
||||||
|
|
||||||
borderState = (borderState & CPThemeStateSelected & ~CPThemeStateHighlighted) ? CPThemeStateSelected : CPThemeStateNormal;
|
borderState = (borderState & CPThemeStateSelected & ~CPThemeStateHighlighted) ? CPThemeStateSelected : CPThemeStateNormal;
|
||||||
|
|
||||||
borderState |= _themeState & CPThemeStateDisabled;
|
borderState |= _themeState & CPThemeStateDisabled;
|
||||||
|
|
||||||
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
|
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
|
||||||
inState:borderState],
|
inState:borderState];
|
||||||
|
|
||||||
borderView = [self layoutEphemeralSubviewNamed:"divider-bezel-" + i
|
var borderView = [self layoutEphemeralSubviewNamed:"divider-bezel-"+i
|
||||||
positioned:CPWindowBelow
|
positioned:CPWindowBelow
|
||||||
relativeToEphemeralSubviewNamed:nil];
|
relativeToEphemeralSubviewNamed:nil];
|
||||||
|
|
||||||
@@ -604,48 +609,43 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var segment = _segments[aSegment],
|
var segment = _segments[aSegment],
|
||||||
segmentWidth = [segment width],
|
segmentWidth = segment.width,
|
||||||
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
|
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
|
||||||
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
|
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
|
||||||
font = [self valueForThemeAttribute:@"font" inState:themeState];
|
font = [self valueForThemeAttribute:@"font" inState:themeState];
|
||||||
|
|
||||||
if (!segmentWidth)
|
if (!segmentWidth)
|
||||||
{
|
{
|
||||||
if ([segment image] && [segment label])
|
if (segment.image && segment.label)
|
||||||
segmentWidth = [[segment label] sizeWithFont:font].width + [[segment image] size].width + contentInset.left + contentInset.right;
|
segmentWidth = [segment.label sizeWithFont:font].width + [segment.image size].width + contentInset.left + contentInset.right;
|
||||||
else if (segment.image)
|
else if (segment.image)
|
||||||
segmentWidth = [[segment image] size].width + contentInset.left + contentInset.right;
|
segmentWidth = [segment.image size].width + contentInset.left + contentInset.right;
|
||||||
else if (segment.label)
|
else if (segment.label)
|
||||||
segmentWidth = [[segment label] sizeWithFont:font].width + contentInset.left + contentInset.right;
|
segmentWidth = [segment.label sizeWithFont:font].width + contentInset.left + contentInset.right;
|
||||||
else
|
else
|
||||||
segmentWidth = 0.0;
|
segmentWidth = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var delta = segmentWidth - CGRectGetWidth([segment frame]);
|
var delta = segmentWidth - CGRectGetWidth(segment.frame);
|
||||||
|
|
||||||
if (!delta)
|
if (!delta)
|
||||||
{
|
|
||||||
[self setNeedsLayout];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Update control size
|
// Update Contorl Size
|
||||||
var frame = [self frame];
|
var frame = [self frame];
|
||||||
|
|
||||||
[self setFrameSize:CGSizeMake(CGRectGetWidth(frame) + delta, CGRectGetHeight(frame))];
|
[self setFrameSize:CGSizeMake(CGRectGetWidth(frame) + delta, CGRectGetHeight(frame))];
|
||||||
|
|
||||||
// Update segment width
|
// Update Segment Width
|
||||||
[segment setWidth:segmentWidth];
|
segment.width = segmentWidth;
|
||||||
[segment setFrame:[self frameForSegment:aSegment]];
|
segment.frame = [self frameForSegment:aSegment];;
|
||||||
|
|
||||||
// Update following segments widths
|
// Update Following Segments Widths
|
||||||
var index = aSegment + 1;
|
var index = aSegment + 1;
|
||||||
|
|
||||||
for (; index < _segments.length; ++index)
|
for (; index < _segments.length; ++index)
|
||||||
{
|
{
|
||||||
[_segments[index] frame].origin.x += delta;
|
_segments[index].frame.origin.x += delta;
|
||||||
|
|
||||||
[self drawSegmentBezel:index highlight:NO];
|
[self drawSegmentBezel:index highlight:NO];
|
||||||
[self drawSegment:index highlight:NO];
|
[self drawSegment:index highlight:NO];
|
||||||
@@ -698,12 +698,12 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
count = _segments.length;
|
count = _segments.length;
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
if (CGRectContainsPoint([_segments[count] frame], aPoint))
|
if (CGRectContainsPoint(_segments[count].frame, aPoint))
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
if (_segments.length)
|
if (_segments.length)
|
||||||
{
|
{
|
||||||
var adjustedLastFrame = CGRectCreateCopy([_segments[_segments.length - 1] frame]);
|
var adjustedLastFrame = CGRectCreateCopy(_segments[_segments.length - 1].frame);
|
||||||
adjustedLastFrame.size.width = CGRectGetWidth([self bounds]) - adjustedLastFrame.origin.x;
|
adjustedLastFrame.size.width = CGRectGetWidth([self bounds]) - adjustedLastFrame.origin.x;
|
||||||
|
|
||||||
if (CGRectContainsPoint(adjustedLastFrame, aPoint))
|
if (CGRectContainsPoint(adjustedLastFrame, aPoint))
|
||||||
@@ -844,15 +844,15 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
|||||||
|
|
||||||
for (var i = 0; i < _segments.length; i++)
|
for (var i = 0; i < _segments.length; i++)
|
||||||
{
|
{
|
||||||
_themeStates[i] = [_segments[i] selected] ? CPThemeStateSelected : CPThemeStateNormal;
|
_themeStates[i] = _segments[i].selected ? CPThemeStateSelected : CPThemeStateNormal;
|
||||||
[self tileWithChangedSegment:i];
|
[self tileWithChangedSegment:i];
|
||||||
}
|
}
|
||||||
|
|
||||||
var difference = MAX(originalWidth - [self frame].size.width, 0.0),
|
var difference = MAX(originalWidth - [self frame].size.width, 0.0),
|
||||||
remainingWidth = FLOOR(difference / _segments.length);
|
remainingWidth = FLOOR(difference / _segments.length);
|
||||||
|
|
||||||
for (var i = 0; i < _segments.length; i++)
|
for (var i=0; i < _segments.length; i++)
|
||||||
[self setWidth:[_segments[i] width] + remainingWidth forSegment:i];
|
[self setWidth:_segments[i].width + remainingWidth forSegment:i];
|
||||||
|
|
||||||
[self tileWithChangedSegment:0];
|
[self tileWithChangedSegment:0];
|
||||||
}
|
}
|
||||||
@@ -875,15 +875,15 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
|||||||
|
|
||||||
@implementation _CPSegmentItem : CPObject
|
@implementation _CPSegmentItem : CPObject
|
||||||
{
|
{
|
||||||
CPImage image @accessors;
|
CPImage image;
|
||||||
CPString label @accessors;
|
CPString label;
|
||||||
CPMenu menu @accessors;
|
CPMenu menu;
|
||||||
BOOL selected @accessors;
|
BOOL selected;
|
||||||
BOOL enabled @accessors;
|
BOOL enabled;
|
||||||
int tag @accessors;
|
int tag;
|
||||||
int width @accessors;
|
int width;
|
||||||
|
|
||||||
CGRect frame @accessors;
|
CGRect frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)init
|
- (id)init
|
||||||
@@ -894,8 +894,8 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
|||||||
label = @"";
|
label = @"";
|
||||||
menu = nil;
|
menu = nil;
|
||||||
selected = NO;
|
selected = NO;
|
||||||
enabled = YES;
|
enabled = NO;
|
||||||
tag = -1;
|
tag = 0;
|
||||||
width = 0;
|
width = 0;
|
||||||
|
|
||||||
frame = CGRectMakeZero();
|
frame = CGRectMakeZero();
|
||||||
@@ -947,3 +947,4 @@ var CPSegmentItemImageKey = "CPSegmentItemImageKey",
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
+2
-25
@@ -28,6 +28,8 @@
|
|||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
CPLightShadow = 0;
|
CPLightShadow = 0;
|
||||||
CPHeavyShadow = 1;
|
CPHeavyShadow = 1;
|
||||||
|
|
||||||
@@ -91,31 +93,6 @@ var LIGHT_LEFT_INSET = 3.0,
|
|||||||
]]];
|
]]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)shadowViewEnclosingView:(CPView)aView
|
|
||||||
{
|
|
||||||
return [self shadowViewEnclosingView:aView withWeight:CPLightShadow];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)shadowViewEnclosingView:(CPView)aView withWeight:(CPShadowWeight)aWeight
|
|
||||||
{
|
|
||||||
var shadowView = [[CPShadowView alloc] initWithFrame:[aView frame]];
|
|
||||||
[shadowView setWeight:aWeight];
|
|
||||||
|
|
||||||
var size = [shadowView frame].size,
|
|
||||||
width = size.width - [shadowView leftInset] - [shadowView rightInset],
|
|
||||||
height = size.height - [shadowView topInset] - [shadowView bottomInset],
|
|
||||||
enclosingView = [aView superview];
|
|
||||||
|
|
||||||
[shadowView setHitTests:[aView hitTests]];
|
|
||||||
[shadowView setAutoresizingMask:[aView autoresizingMask]];
|
|
||||||
[aView removeFromSuperview];
|
|
||||||
[shadowView addSubview:aView];
|
|
||||||
[aView setFrame:CGRectMake([shadowView leftInset], [shadowView topInset], width, height)]
|
|
||||||
[enclosingView addSubview:shadowView];
|
|
||||||
|
|
||||||
return shadowView;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|||||||
+6
-16
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
@import "CPControl.j"
|
@import "CPControl.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
/*! SLIDER STATES */
|
/*! SLIDER STATES */
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ CPCircularSlider = 1;
|
|||||||
BOOL _isVertical;
|
BOOL _isVertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return "slider";
|
return "slider";
|
||||||
}
|
}
|
||||||
@@ -188,7 +189,7 @@ CPCircularSlider = 1;
|
|||||||
|
|
||||||
if ([self hasThemeState:CPThemeStateCircular])
|
if ([self hasThemeState:CPThemeStateCircular])
|
||||||
{
|
{
|
||||||
var angle = 3 * PI_2 - (1.0 - [self doubleValue] - _minValue) / (_maxValue - _minValue) * PI2,
|
var angle = 3*PI_2 - (1.0 - [self doubleValue] - _minValue) / (_maxValue - _minValue) * PI2,
|
||||||
radius = CGRectGetWidth(trackRect) / 2.0 - 8.0;
|
radius = CGRectGetWidth(trackRect) / 2.0 - 8.0;
|
||||||
|
|
||||||
knobRect.origin.x = radius * COS(angle) + CGRectGetMidX(trackRect) - 3.0;
|
knobRect.origin.x = radius * COS(angle) + CGRectGetMidX(trackRect) - 3.0;
|
||||||
@@ -197,7 +198,7 @@ CPCircularSlider = 1;
|
|||||||
else if ([self isVertical])
|
else if ([self isVertical])
|
||||||
{
|
{
|
||||||
knobRect.origin.x = _CGRectGetMidX(trackRect) - knobSize.width / 2.0;
|
knobRect.origin.x = _CGRectGetMidX(trackRect) - knobSize.width / 2.0;
|
||||||
knobRect.origin.y = ((_maxValue - [self doubleValue]) / (_maxValue - _minValue)) * (_CGRectGetHeight(trackRect) - knobSize.height);
|
knobRect.origin.y = (([self doubleValue] - _minValue) / (_maxValue - _minValue)) * (_CGRectGetHeight(trackRect) - knobSize.height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -319,7 +320,7 @@ CPCircularSlider = 1;
|
|||||||
|
|
||||||
var minValue = [self minValue];
|
var minValue = [self minValue];
|
||||||
|
|
||||||
return MAX(0.0, MIN(1.0, (_CGRectGetMaxY(trackRect) - aPoint.y) / _CGRectGetHeight(trackRect))) * ([self maxValue] - minValue) + minValue;
|
return MAX(0.0, MIN(1.0, (aPoint.y - _CGRectGetMinY(trackRect)) / _CGRectGetHeight(trackRect))) * ([self maxValue] - minValue) + minValue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -341,6 +342,7 @@ CPCircularSlider = 1;
|
|||||||
|
|
||||||
if (_CGRectContainsPoint(knobRect, aPoint))
|
if (_CGRectContainsPoint(knobRect, aPoint))
|
||||||
_dragOffset = _CGSizeMake(_CGRectGetMidX(knobRect) - aPoint.x, _CGRectGetMidY(knobRect) - aPoint.y);
|
_dragOffset = _CGSizeMake(_CGRectGetMidX(knobRect) - aPoint.x, _CGRectGetMidY(knobRect) - aPoint.y);
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var trackRect = [self trackRectForBounds:bounds];
|
var trackRect = [self trackRectForBounds:bounds];
|
||||||
@@ -394,18 +396,6 @@ CPCircularSlider = 1;
|
|||||||
_sendActionOn &= ~CPLeftMouseDraggedMask;
|
_sendActionOn &= ~CPLeftMouseDraggedMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
var count = objects.length,
|
|
||||||
value = [objects[0] valueForKeyPath:aKeyPath];
|
|
||||||
|
|
||||||
[self setObjectValue:value];
|
|
||||||
|
|
||||||
while (count-- > 1)
|
|
||||||
if (value !== ([objects[count] valueForKeyPath:aKeyPath]))
|
|
||||||
return [self setFloatValue:1.0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPSliderMinValueKey = "CPSliderMinValueKey",
|
var CPSliderMinValueKey = "CPSliderMinValueKey",
|
||||||
|
|||||||
+167
-103
@@ -20,10 +20,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPView.j"
|
|
||||||
@import "CPColorPicker.j"
|
@import "CPColorPicker.j"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ignore
|
@ignore
|
||||||
*/
|
*/
|
||||||
@@ -47,15 +45,16 @@
|
|||||||
CPTextField _saturationLabel;
|
CPTextField _saturationLabel;
|
||||||
CPTextField _brightnessLabel;
|
CPTextField _brightnessLabel;
|
||||||
CPTextField _hexLabel;
|
CPTextField _hexLabel;
|
||||||
CPTextField _hexValue;
|
|
||||||
|
|
||||||
CPTextField _hexValue;
|
#if PLATFORM(DOM)
|
||||||
CPTextField _redValue;
|
DOMElement _redValue;
|
||||||
CPTextField _greenValue;
|
DOMElement _greenValue;
|
||||||
CPTextField _blueValue;
|
DOMElement _blueValue;
|
||||||
CPTextField _hueValue;
|
DOMElement _hueValue;
|
||||||
CPTextField _saturationValue;
|
DOMElement _saturationValue;
|
||||||
CPTextField _brightnessValue;
|
DOMElement _brightnessValue;
|
||||||
|
DOMElement _hexValue;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
|
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
|
||||||
@@ -85,13 +84,73 @@
|
|||||||
[_redSlider setAction: @selector(sliderChanged:)];
|
[_redSlider setAction: @selector(sliderChanged:)];
|
||||||
[_redSlider setAutoresizingMask: CPViewWidthSizable];
|
[_redSlider setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
// red value input box
|
#if PLATFORM(DOM)
|
||||||
_redValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 30, 45, 29)];
|
var updateFunction = function(aDOMEvent)
|
||||||
[_redValue setAutoresizingMask: CPViewMinXMargin];
|
{
|
||||||
[_redValue setEditable: YES];
|
if(isNaN(this.value))
|
||||||
[_redValue setBezeled: YES];
|
return;
|
||||||
[_redValue setDelegate: self];
|
|
||||||
[_contentView addSubview: _redValue];
|
switch(this)
|
||||||
|
{
|
||||||
|
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
|
||||||
|
//[self sliderChanged: _redSlider];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
|
||||||
|
//[self sliderChanged: _greenSlider];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
|
||||||
|
//[self sliderChanged: _blueSlider];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(this.value), 360), 0)];
|
||||||
|
//[self sliderChanged: _hueSlider];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(this.value), 100), 0)];
|
||||||
|
//[self sliderChanged: _saturationSlider];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(this.value), 100), 0)];
|
||||||
|
//[self sliderChanged: _brightnessSlider];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.blur();
|
||||||
|
};
|
||||||
|
|
||||||
|
var keypressFunction = function(aDOMEvent)
|
||||||
|
{
|
||||||
|
aDOMEvent = aDOMEvent || window.event;
|
||||||
|
if (aDOMEvent.keyCode == 13)
|
||||||
|
{
|
||||||
|
updateFunction(aDOMEvent);
|
||||||
|
|
||||||
|
if(aDOMEvent.preventDefault)
|
||||||
|
aDOMEvent.preventDefault();
|
||||||
|
else if(aDOMEvent.stopPropagation)
|
||||||
|
aDOMEvent.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//red value input box
|
||||||
|
var redValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 35, 45, 20)];
|
||||||
|
[redValue setAutoresizingMask: CPViewMinXMargin];
|
||||||
|
|
||||||
|
_redValue = document.createElement("input");
|
||||||
|
_redValue.style.width = "40px";
|
||||||
|
_redValue.style.backgroundColor = "transparent";
|
||||||
|
_redValue.style.border = "1px solid black";
|
||||||
|
_redValue.style.color = "black";
|
||||||
|
_redValue.style.position = "absolute";
|
||||||
|
_redValue.style.top = "0px";
|
||||||
|
_redValue.style.left = "0px";
|
||||||
|
_redValue.onchange = updateFunction;
|
||||||
|
|
||||||
|
redValue._DOMElement.appendChild(_redValue);
|
||||||
|
[_contentView addSubview: redValue];
|
||||||
|
#endif
|
||||||
|
|
||||||
_greenLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 58, 15, 20)];
|
_greenLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 58, 15, 20)];
|
||||||
[_greenLabel setStringValue: "G"];
|
[_greenLabel setStringValue: "G"];
|
||||||
@@ -104,13 +163,17 @@
|
|||||||
[_greenSlider setAction: @selector(sliderChanged:)];
|
[_greenSlider setAction: @selector(sliderChanged:)];
|
||||||
[_greenSlider setAutoresizingMask: CPViewWidthSizable];
|
[_greenSlider setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
// green value input box
|
#if PLATFORM(DOM)
|
||||||
_greenValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 53, 45, 29)];
|
//green value input box
|
||||||
[_greenValue setAutoresizingMask: CPViewMinXMargin];
|
var greenValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 58, 45, 20)];
|
||||||
[_greenValue setEditable: YES];
|
[greenValue setAutoresizingMask: CPViewMinXMargin];
|
||||||
[_greenValue setBezeled: YES];
|
|
||||||
[_greenValue setDelegate: self];
|
_greenValue = _redValue.cloneNode(false);
|
||||||
[_contentView addSubview: _greenValue];
|
_greenValue.onchange = updateFunction;
|
||||||
|
|
||||||
|
greenValue._DOMElement.appendChild(_greenValue);
|
||||||
|
[_contentView addSubview: greenValue];
|
||||||
|
#endif
|
||||||
|
|
||||||
_blueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 81, 15, 20)];
|
_blueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 81, 15, 20)];
|
||||||
[_blueLabel setStringValue: "B"];
|
[_blueLabel setStringValue: "B"];
|
||||||
@@ -123,14 +186,17 @@
|
|||||||
[_blueSlider setAction: @selector(sliderChanged:)];
|
[_blueSlider setAction: @selector(sliderChanged:)];
|
||||||
[_blueSlider setAutoresizingMask: CPViewWidthSizable];
|
[_blueSlider setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
// blue value input box
|
#if PLATFORM(DOM)
|
||||||
_blueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 76, 45, 29)];
|
//blue value input box
|
||||||
[_blueValue setAutoresizingMask: CPViewMinXMargin];
|
var blueValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 81, 45, 20)];
|
||||||
[_blueValue setEditable: YES];
|
[blueValue setAutoresizingMask: CPViewMinXMargin];
|
||||||
[_blueValue setBezeled: YES];
|
|
||||||
[_blueValue setDelegate: self];
|
|
||||||
[_contentView addSubview: _blueValue];
|
|
||||||
|
|
||||||
|
_blueValue = _redValue.cloneNode(false);
|
||||||
|
_blueValue.onchange = updateFunction;
|
||||||
|
|
||||||
|
blueValue._DOMElement.appendChild(_blueValue);
|
||||||
|
[_contentView addSubview: blueValue];
|
||||||
|
#endif
|
||||||
_hsbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 120, 190, 20)];
|
_hsbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 120, 190, 20)];
|
||||||
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
|
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
|
||||||
[_hsbLabel setTextColor:[CPColor blackColor]];
|
[_hsbLabel setTextColor:[CPColor blackColor]];
|
||||||
@@ -146,14 +212,17 @@
|
|||||||
[_hueSlider setAction: @selector(sliderChanged:)];
|
[_hueSlider setAction: @selector(sliderChanged:)];
|
||||||
[_hueSlider setAutoresizingMask: CPViewWidthSizable];
|
[_hueSlider setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
// hue value input box
|
#if PLATFORM(DOM)
|
||||||
_hueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 140, 45, 29)];
|
//red value input box
|
||||||
[_hueValue setAutoresizingMask: CPViewMinXMargin];
|
var hueValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 145, 45, 20)];
|
||||||
[_hueValue setEditable: YES];
|
[hueValue setAutoresizingMask: CPViewMinXMargin];
|
||||||
[_hueValue setBezeled: YES];
|
|
||||||
[_hueValue setDelegate: self];
|
|
||||||
[_contentView addSubview: _hueValue];
|
|
||||||
|
|
||||||
|
_hueValue = _redValue.cloneNode(false);
|
||||||
|
_hueValue.onchange = updateFunction;
|
||||||
|
|
||||||
|
hueValue._DOMElement.appendChild(_hueValue);
|
||||||
|
[_contentView addSubview: hueValue];
|
||||||
|
#endif
|
||||||
_saturationLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 168, 15, 20)];
|
_saturationLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 168, 15, 20)];
|
||||||
[_saturationLabel setStringValue: "S"];
|
[_saturationLabel setStringValue: "S"];
|
||||||
[_saturationLabel setTextColor:[CPColor blackColor]];
|
[_saturationLabel setTextColor:[CPColor blackColor]];
|
||||||
@@ -165,14 +234,17 @@
|
|||||||
[_saturationSlider setAction: @selector(sliderChanged:)];
|
[_saturationSlider setAction: @selector(sliderChanged:)];
|
||||||
[_saturationSlider setAutoresizingMask: CPViewWidthSizable];
|
[_saturationSlider setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
// saturation value input box
|
#if PLATFORM(DOM)
|
||||||
_saturationValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 163, 45, 29)];
|
//green value input box
|
||||||
[_saturationValue setAutoresizingMask: CPViewMinXMargin];
|
var saturationValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 168, 45, 20)];
|
||||||
[_saturationValue setEditable: YES];
|
[saturationValue setAutoresizingMask: CPViewMinXMargin];
|
||||||
[_saturationValue setBezeled: YES];
|
|
||||||
[_saturationValue setDelegate: self];
|
|
||||||
[_contentView addSubview: _saturationValue];
|
|
||||||
|
|
||||||
|
_saturationValue = _redValue.cloneNode(false);
|
||||||
|
_saturationValue.onchange = updateFunction;
|
||||||
|
|
||||||
|
saturationValue._DOMElement.appendChild(_saturationValue);
|
||||||
|
[_contentView addSubview: saturationValue];
|
||||||
|
#endif
|
||||||
_brightnessLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 191, 15, 20)];
|
_brightnessLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 191, 15, 20)];
|
||||||
[_brightnessLabel setStringValue: "B"];
|
[_brightnessLabel setStringValue: "B"];
|
||||||
[_brightnessLabel setTextColor:[CPColor blackColor]];
|
[_brightnessLabel setTextColor:[CPColor blackColor]];
|
||||||
@@ -184,24 +256,51 @@
|
|||||||
[_brightnessSlider setAction: @selector(sliderChanged:)];
|
[_brightnessSlider setAction: @selector(sliderChanged:)];
|
||||||
[_brightnessSlider setAutoresizingMask: CPViewWidthSizable];
|
[_brightnessSlider setAutoresizingMask: CPViewWidthSizable];
|
||||||
|
|
||||||
// brightness value input box
|
#if PLATFORM(DOM)
|
||||||
_brightnessValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 186, 45, 29)];
|
//blue value input box
|
||||||
[_brightnessValue setAutoresizingMask: CPViewMinXMargin];
|
var brightnessValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 191, 45, 20)];
|
||||||
[_brightnessValue setEditable: YES];
|
[brightnessValue setAutoresizingMask: CPViewMinXMargin];
|
||||||
[_brightnessValue setBezeled: YES];
|
|
||||||
[_brightnessValue setDelegate: self];
|
|
||||||
[_contentView addSubview: _brightnessValue];
|
|
||||||
|
|
||||||
|
_brightnessValue = _redValue.cloneNode(false);
|
||||||
|
_brightnessValue.onchange = updateFunction;
|
||||||
|
|
||||||
|
brightnessValue._DOMElement.appendChild(_brightnessValue);
|
||||||
|
[_contentView addSubview: brightnessValue];
|
||||||
|
#endif
|
||||||
_hexLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 230, 30, 20)];
|
_hexLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 230, 30, 20)];
|
||||||
[_hexLabel setStringValue: "Hex"];
|
[_hexLabel setStringValue: "Hex"];
|
||||||
[_hexLabel setTextColor:[CPColor blackColor]];
|
[_hexLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
|
#if PLATFORM(DOM)
|
||||||
//hex input box
|
//hex input box
|
||||||
_hexValue = [[CPTextField alloc] initWithFrame: CGRectMake(32, 225, 80, 29)];
|
_hexValue = _redValue.cloneNode(false);
|
||||||
[_hexValue setEditable: YES];
|
_hexValue.style.top = "228px";
|
||||||
[_hexValue setBezeled: YES];
|
_hexValue.style.width = "80px";
|
||||||
[_hexValue setDelegate: self];
|
_hexValue.style.left = "35px";
|
||||||
[_contentView addSubview: _hexValue];
|
_hexValue.onkeypress = function(aDOMEvent)
|
||||||
|
{
|
||||||
|
aDOMEvent = aDOMEvent || window.event;
|
||||||
|
if (aDOMEvent.keyCode == 13)
|
||||||
|
{
|
||||||
|
var newColor = [CPColor colorWithHexString: this.value];
|
||||||
|
|
||||||
|
if(newColor)
|
||||||
|
{
|
||||||
|
[self setColor: newColor];
|
||||||
|
[[self colorPanel] setColor: newColor];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aDOMEvent.preventDefault)
|
||||||
|
aDOMEvent.preventDefault();
|
||||||
|
else if(aDOMEvent.stopPropagation)
|
||||||
|
aDOMEvent.stopPropagation();
|
||||||
|
|
||||||
|
this.blur();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_contentView._DOMElement.appendChild(_hexValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
[_contentView addSubview: _rgbLabel];
|
[_contentView addSubview: _rgbLabel];
|
||||||
[_contentView addSubview: _redLabel];
|
[_contentView addSubview: _redLabel];
|
||||||
@@ -293,7 +392,9 @@
|
|||||||
|
|
||||||
- (void)updateHex:(CPColor)aColor
|
- (void)updateHex:(CPColor)aColor
|
||||||
{
|
{
|
||||||
[_hexValue setStringValue:[aColor hexString]];
|
#if PLATFORM(DOM)
|
||||||
|
_hexValue.value = [aColor hexString];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateRGBSliders:(CPColor)aColor
|
- (void)updateRGBSliders:(CPColor)aColor
|
||||||
@@ -307,13 +408,15 @@
|
|||||||
|
|
||||||
- (void)updateLabels
|
- (void)updateLabels
|
||||||
{
|
{
|
||||||
[_hueValue setStringValue: ROUND([_hueSlider floatValue])];
|
#if PLATFORM(DOM)
|
||||||
[_saturationValue setStringValue: ROUND([_saturationSlider floatValue])];
|
_hueValue.value = ROUND([_hueSlider floatValue]);
|
||||||
[_brightnessValue setStringValue: ROUND([_brightnessSlider floatValue])];
|
_saturationValue.value = ROUND([_saturationSlider floatValue]);
|
||||||
|
_brightnessValue.value = ROUND([_brightnessSlider floatValue]);
|
||||||
|
|
||||||
[_redValue setStringValue: ROUND([_redSlider floatValue] * 255)];
|
_redValue.value = ROUND([_redSlider floatValue] * 255);
|
||||||
[_greenValue setStringValue: ROUND([_greenSlider floatValue] * 255)];
|
_greenValue.value = ROUND([_greenSlider floatValue] * 255);
|
||||||
[_blueValue setStringValue: ROUND([_blueSlider floatValue] * 255)];
|
_blueValue.value = ROUND([_blueSlider floatValue] * 255);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPImage)provideNewButtonImage
|
- (CPImage)provideNewButtonImage
|
||||||
@@ -326,43 +429,4 @@
|
|||||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button_h.png"] size:CGSizeMake(32, 32)];
|
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button_h.png"] size:CGSizeMake(32, 32)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)controlTextDidEndEditing:(CPNotification)aNotification
|
|
||||||
{
|
|
||||||
var field = [aNotification object],
|
|
||||||
value = [[field stringValue] stringByTrimmingWhitespace];
|
|
||||||
if (field === _hexValue) {
|
|
||||||
var newColor = [CPColor colorWithHexString: value];
|
|
||||||
if (newColor) {
|
|
||||||
[self setColor: newColor];
|
|
||||||
[[self colorPanel] setColor: newColor];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(field) {
|
|
||||||
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
|
|
||||||
[self sliderChanged: _redSlider];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
|
|
||||||
[self sliderChanged: _greenSlider];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
|
|
||||||
[self sliderChanged: _blueSlider];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360), 0)];
|
|
||||||
[self sliderChanged: _hueSlider];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
|
|
||||||
[self sliderChanged: _saturationSlider];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
|
|
||||||
[self sliderChanged: _brightnessSlider];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+26
-48
@@ -24,6 +24,10 @@
|
|||||||
@import "CPImage.j"
|
@import "CPImage.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
#include "Platform/DOM/CPDOMDisplayServer.h"
|
||||||
|
|
||||||
|
|
||||||
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
|
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
|
||||||
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
|
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
|
||||||
@@ -43,7 +47,6 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
|
|
||||||
int _currentDivider;
|
int _currentDivider;
|
||||||
float _initialOffset;
|
float _initialOffset;
|
||||||
float _preCollapsePosition;
|
|
||||||
|
|
||||||
CPString _originComponent;
|
CPString _originComponent;
|
||||||
CPString _sizeComponent;
|
CPString _sizeComponent;
|
||||||
@@ -57,17 +60,6 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
CPArray _buttonBars;
|
CPArray _buttonBars;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
|
||||||
{
|
|
||||||
return @"splitview";
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)themeAttributes
|
|
||||||
{
|
|
||||||
return [CPDictionary dictionaryWithObjects:[10.0, 1.0, [CPColor grayColor]]
|
|
||||||
forKeys:[@"divider-thickness", @"pane-divider-thickness", @"pane-divider-color"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ignore
|
@ignore
|
||||||
*/
|
*/
|
||||||
@@ -98,7 +90,7 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
|
|
||||||
- (float)dividerThickness
|
- (float)dividerThickness
|
||||||
{
|
{
|
||||||
return [self currentValueForThemeAttribute:[self isPaneSplitter] ? @"pane-divider-thickness" : @"divider-thickness"];
|
return _isPaneSplitter ? 1.0 : 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isVertical
|
- (BOOL)isVertical
|
||||||
@@ -159,8 +151,8 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
|
|
||||||
_isPaneSplitter = shouldBePaneSplitter;
|
_isPaneSplitter = shouldBePaneSplitter;
|
||||||
|
|
||||||
if (_DOMDividerElements[_drawingDivider])
|
if(_DOMDividerElements[_drawingDivider])
|
||||||
[self _setupDOMDivider];
|
[self _setupDOMDivider]
|
||||||
|
|
||||||
// The divider changes size when pane splitter mode is toggled, so the
|
// The divider changes size when pane splitter mode is toggled, so the
|
||||||
// subviews need to change size too.
|
// subviews need to change size too.
|
||||||
@@ -193,8 +185,9 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
|
|
||||||
- (CGRect)effectiveRectOfDividerAtIndex:(int)aDivider
|
- (CGRect)effectiveRectOfDividerAtIndex:(int)aDivider
|
||||||
{
|
{
|
||||||
var realRect = [self rectOfDividerAtIndex:aDivider],
|
var realRect = [self rectOfDividerAtIndex:aDivider];
|
||||||
padding = 2;
|
|
||||||
|
var padding = 2;
|
||||||
|
|
||||||
realRect.size[_sizeComponent] += padding * 2;
|
realRect.size[_sizeComponent] += padding * 2;
|
||||||
realRect.origin[_originComponent] -= padding;
|
realRect.origin[_originComponent] -= padding;
|
||||||
@@ -224,9 +217,10 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
_DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
|
_DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
|
||||||
|
|
||||||
CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
|
CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
|
||||||
|
|
||||||
|
[self _setupDOMDivider];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _setupDOMDivider];
|
|
||||||
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
|
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
|
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
|
||||||
#endif
|
#endif
|
||||||
@@ -236,7 +230,7 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
{
|
{
|
||||||
if (_isPaneSplitter)
|
if (_isPaneSplitter)
|
||||||
{
|
{
|
||||||
_DOMDividerElements[_drawingDivider].style.backgroundColor = [[self currentValueForThemeAttribute:@"pane-divider-color"] cssString];
|
_DOMDividerElements[_drawingDivider].style.backgroundColor = "#A5A5A5";
|
||||||
_DOMDividerElements[_drawingDivider].style.backgroundImage = "";
|
_DOMDividerElements[_drawingDivider].style.backgroundImage = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -310,9 +304,9 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
if ([self isHidden] || ![self hitTests] || !CGRectContainsPoint([self frame], aPoint))
|
if ([self isHidden] || ![self hitTests] || !CGRectContainsPoint([self frame], aPoint))
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
var point = [self convertPoint:aPoint fromView:[self superview]],
|
var point = [self convertPoint:aPoint fromView:[self superview]];
|
||||||
count = [_subviews count] - 1;
|
|
||||||
|
|
||||||
|
var count = [_subviews count] - 1;
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if ([self cursorAtPoint:point hitDividerAtIndex:i])
|
if ([self cursorAtPoint:point hitDividerAtIndex:i])
|
||||||
@@ -365,14 +359,14 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
|
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
|
||||||
{
|
{
|
||||||
if ([self isSubviewCollapsed:_subviews[i]])
|
if ([self isSubviewCollapsed:_subviews[i]])
|
||||||
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
|
[self setPosition:(minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
|
||||||
else
|
else
|
||||||
[self setPosition:minPosition ofDividerAtIndex:i];
|
[self setPosition:minPosition ofDividerAtIndex:i];
|
||||||
}
|
}
|
||||||
else if ([_delegate splitView:self canCollapseSubview:_subviews[i + 1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
|
else if ([_delegate splitView:self canCollapseSubview:_subviews[i+1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i+1] forDoubleClickOnDividerAtIndex:i])
|
||||||
{
|
{
|
||||||
if ([self isSubviewCollapsed:_subviews[i + 1]])
|
if ([self isSubviewCollapsed:_subviews[i+1]])
|
||||||
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
|
[self setPosition:(minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
|
||||||
else
|
else
|
||||||
[self setPosition:maxPosition ofDividerAtIndex:i];
|
[self setPosition:maxPosition ofDividerAtIndex:i];
|
||||||
}
|
}
|
||||||
@@ -451,19 +445,11 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
|
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
|
||||||
{
|
{
|
||||||
var frame = [_subviews[i] frame],
|
var frame = [_subviews[i] frame],
|
||||||
size = frame.size[_sizeComponent],
|
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
|
||||||
startPosition = frame.origin[_originComponent] + size,
|
canShrink = [self _realPositionForPosition:startPosition-1 ofDividerAtIndex:i] < startPosition,
|
||||||
canShrink = [self _realPositionForPosition:startPosition - 1 ofDividerAtIndex:i] < startPosition,
|
canGrow = [self _realPositionForPosition:startPosition+1 ofDividerAtIndex:i] > startPosition,
|
||||||
canGrow = [self _realPositionForPosition:startPosition + 1 ofDividerAtIndex:i] > startPosition,
|
|
||||||
cursor = [CPCursor arrowCursor];
|
cursor = [CPCursor arrowCursor];
|
||||||
|
|
||||||
if (size === 0)
|
|
||||||
canGrow = YES; // Subview is collapsed.
|
|
||||||
else if (!canShrink &&
|
|
||||||
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
|
|
||||||
[_delegate splitView:self canCollapseSubview:_subviews[i]])
|
|
||||||
canShrink = YES; // Subview is collapsible.
|
|
||||||
|
|
||||||
if (_isVertical && canShrink && canGrow)
|
if (_isVertical && canShrink && canGrow)
|
||||||
cursor = [CPCursor resizeLeftRightCursor];
|
cursor = [CPCursor resizeLeftRightCursor];
|
||||||
else if (_isVertical && canShrink)
|
else if (_isVertical && canShrink)
|
||||||
@@ -518,10 +504,10 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
actualMax = proposedMax,
|
actualMax = proposedMax,
|
||||||
actualMin = proposedMin;
|
actualMin = proposedMin;
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
|
if([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
|
||||||
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
|
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
|
if([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
|
||||||
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
|
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
|
||||||
|
|
||||||
var viewA = _subviews[dividerIndex],
|
var viewA = _subviews[dividerIndex],
|
||||||
@@ -546,18 +532,10 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
viewB = _subviews[dividerIndex + 1],
|
viewB = _subviews[dividerIndex + 1],
|
||||||
frameB = [viewB frame];
|
frameB = [viewB frame];
|
||||||
|
|
||||||
_preCollapsePosition = 0;
|
|
||||||
|
|
||||||
var preSize = frameA.size[_sizeComponent];
|
|
||||||
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
|
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
|
||||||
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
|
|
||||||
_preCollapsePosition = preSize;
|
|
||||||
[_subviews[dividerIndex] setFrame:frameA];
|
[_subviews[dividerIndex] setFrame:frameA];
|
||||||
|
|
||||||
preSize = frameB.size[_sizeComponent];
|
|
||||||
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
|
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
|
||||||
if (preSize !== 0 && frameB.size[_sizeComponent] === 0)
|
|
||||||
_preCollapsePosition = preSize;
|
|
||||||
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
|
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
|
||||||
[_subviews[dividerIndex + 1] setFrame:frameB];
|
[_subviews[dividerIndex + 1] setFrame:frameB];
|
||||||
|
|
||||||
@@ -612,8 +590,8 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
|
|
||||||
var nonSizableSpace = totalSizableSpace ? bounds.size[_sizeComponent] - totalSizableSpace : 0,
|
var nonSizableSpace = totalSizableSpace ? bounds.size[_sizeComponent] - totalSizableSpace : 0,
|
||||||
remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent],
|
remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent],
|
||||||
oldDimension = (oldSize[_sizeComponent] - totalDividers * dividerThickness - nonSizableSpace),
|
oldDimension = (oldSize[_sizeComponent]- totalDividers*dividerThickness - nonSizableSpace),
|
||||||
ratio = oldDimension <= 0 ? 0 : (bounds.size[_sizeComponent] - totalDividers * dividerThickness - nonSizableSpace) / oldDimension;
|
ratio = oldDimension <= 0 ? 0 : (bounds.size[_sizeComponent] - totalDividers*dividerThickness - nonSizableSpace) / oldDimension;
|
||||||
|
|
||||||
for (index = 0; index < count; ++index)
|
for (index = 0; index < count; ++index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,20 +25,8 @@
|
|||||||
@import "CPPlatformString.j"
|
@import "CPPlatformString.j"
|
||||||
|
|
||||||
|
|
||||||
var CPStringSizeWithFontInWidthCache = {};
|
|
||||||
|
|
||||||
CPStringSizeCachingEnabled = YES;
|
|
||||||
|
|
||||||
@implementation CPString (CPStringDrawing)
|
@implementation CPString (CPStringDrawing)
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a dictionary with the items "ascender", "descender", "lineHeight"
|
|
||||||
*/
|
|
||||||
+ (CPDictionary)metricsOfFont:(CPFont)aFont
|
|
||||||
{
|
|
||||||
return [CPPlatformString metricsOfFont:aFont];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the string
|
Returns the string
|
||||||
*/
|
*/
|
||||||
@@ -54,19 +42,7 @@ CPStringSizeCachingEnabled = YES;
|
|||||||
|
|
||||||
- (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
|
- (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
|
||||||
{
|
{
|
||||||
if (!CPStringSizeCachingEnabled)
|
return [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
|
||||||
return [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
|
|
||||||
|
|
||||||
var cacheKey = self + [aFont cssString] + aWidth,
|
|
||||||
size = CPStringSizeWithFontInWidthCache[cacheKey];
|
|
||||||
|
|
||||||
if (size === undefined)
|
|
||||||
{
|
|
||||||
size = [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
|
|
||||||
CPStringSizeWithFontInWidthCache[cacheKey] = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CGSizeMakeCopy(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+531
-180
@@ -1,8 +1,32 @@
|
|||||||
@import "CPBox.j"
|
/*
|
||||||
@import "CPSegmentedControl.j"
|
* CPTabView.j
|
||||||
|
* AppKit
|
||||||
|
*
|
||||||
|
* Created by Francisco Tolmasky.
|
||||||
|
* Copyright 2008, 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 "CPImageView.j"
|
||||||
@import "CPTabViewItem.j"
|
@import "CPTabViewItem.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Places tabs on top with a bezeled border.
|
Places tabs on top with a bezeled border.
|
||||||
@global
|
@global
|
||||||
@@ -10,7 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
CPTopTabsBezelBorder = 0;
|
CPTopTabsBezelBorder = 0;
|
||||||
//CPLeftTabsBezelBorder = 1;
|
//CPLeftTabsBezelBorder = 1;
|
||||||
CPBottomTabsBezelBorder = 2;
|
//CPBottomTabsBezelBorder = 2;
|
||||||
//CPRightTabsBezelBorder = 3;
|
//CPRightTabsBezelBorder = 3;
|
||||||
/*
|
/*
|
||||||
Displays no tabs and has a bezeled border.
|
Displays no tabs and has a bezeled border.
|
||||||
@@ -31,55 +55,173 @@ CPNoTabsLineBorder = 5;
|
|||||||
*/
|
*/
|
||||||
CPNoTabsNoBorder = 6;
|
CPNoTabsNoBorder = 6;
|
||||||
|
|
||||||
|
var CPTabViewBezelBorderLeftImage = nil,
|
||||||
|
CPTabViewBackgroundCenterImage = nil,
|
||||||
|
CPTabViewBezelBorderRightImage = nil,
|
||||||
|
CPTabViewBezelBorderColor = nil,
|
||||||
|
CPTabViewBezelBorderBackgroundColor = nil;
|
||||||
|
|
||||||
|
var LEFT_INSET = 7.0,
|
||||||
|
RIGHT_INSET = 7.0;
|
||||||
|
|
||||||
var CPTabViewDidSelectTabViewItemSelector = 1,
|
var CPTabViewDidSelectTabViewItemSelector = 1,
|
||||||
CPTabViewShouldSelectTabViewItemSelector = 2,
|
CPTabViewShouldSelectTabViewItemSelector = 2,
|
||||||
CPTabViewWillSelectTabViewItemSelector = 4,
|
CPTabViewWillSelectTabViewItemSelector = 4,
|
||||||
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
|
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
|
||||||
|
|
||||||
var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
/*!
|
||||||
|
@ingroup appkit
|
||||||
|
@class CPTabView
|
||||||
|
|
||||||
|
This class represents a view that has multiple subviews (CPTabViewItem) presented as individual tabs.
|
||||||
|
Only one CPTabViewItem is shown at a time, and other CPTabViewItems can be made visible
|
||||||
|
(one at a time) by clicking on the CPTabViewItem's tab at the top of the tab view.
|
||||||
|
|
||||||
|
THe currently selected CPTabViewItem is the view that is displayed.
|
||||||
|
*/
|
||||||
@implementation CPTabView : CPView
|
@implementation CPTabView : CPView
|
||||||
{
|
{
|
||||||
CPArray items;
|
CPView _labelsView;
|
||||||
|
CPView _backgroundView;
|
||||||
|
CPView _separatorView;
|
||||||
|
|
||||||
CPSegmentedControl tabs;
|
CPView _auxiliaryView;
|
||||||
CPBox box;
|
CPView _contentView;
|
||||||
|
|
||||||
CPNumber selectedIndex;
|
CPArray _tabViewItems;
|
||||||
|
CPTabViewItem _selectedTabViewItem;
|
||||||
|
|
||||||
CPTabViewType type;
|
CPTabViewType _tabViewType;
|
||||||
|
|
||||||
id delegate;
|
id _delegate;
|
||||||
unsigned delegateSelectors;
|
unsigned _delegateSelectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
if (self != CPTabView)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var bundle = [CPBundle bundleForClass:self],
|
||||||
|
|
||||||
|
emptyImage = [[CPImage alloc] initByReferencingFile:@"" size:CGSizeMake(7.0, 0.0)],
|
||||||
|
backgroundImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/CPTabViewBezelBackgroundCenter.png"] size:CGSizeMake(1.0, 1.0)],
|
||||||
|
|
||||||
|
bezelBorderLeftImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/CPTabViewBezelBorderLeft.png"] size:CGSizeMake(7.0, 1.0)],
|
||||||
|
bezerBorderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/CPTabViewBezelBorder.png"] size:CGSizeMake(1.0, 1.0)],
|
||||||
|
bezelBorderRightImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/CPTabViewBezelBorderRight.png"] size:CGSizeMake(7.0, 1.0)];
|
||||||
|
|
||||||
|
CPTabViewBezelBorderBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
|
||||||
|
[
|
||||||
|
emptyImage,
|
||||||
|
emptyImage,
|
||||||
|
emptyImage,
|
||||||
|
|
||||||
|
bezelBorderLeftImage,
|
||||||
|
backgroundImage,
|
||||||
|
bezelBorderRightImage,
|
||||||
|
|
||||||
|
bezelBorderLeftImage,
|
||||||
|
bezerBorderImage,
|
||||||
|
bezelBorderRightImage
|
||||||
|
]]];
|
||||||
|
|
||||||
|
CPTabViewBezelBorderColor = [CPColor colorWithPatternImage:bezerBorderImage];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
+ (CPColor)bezelBorderColor
|
||||||
|
{
|
||||||
|
return CPTabViewBezelBorderColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
items = [CPArray array];
|
_tabViewType = CPTopTabsBezelBorder;
|
||||||
|
_tabViewItems = [];
|
||||||
tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, HEIGHT_OF_SEGMENTED_CONTROL)];
|
|
||||||
[tabs setHitTests:NO];
|
|
||||||
|
|
||||||
box = [[CPBox alloc] initWithFrame:CGRectMake(0, HEIGHT_OF_SEGMENTED_CONTROL / 2, CGRectGetWidth(aFrame),
|
|
||||||
CGRectGetHeight(aFrame) - HEIGHT_OF_SEGMENTED_CONTROL)];
|
|
||||||
|
|
||||||
selectedIndex = CPNotFound;
|
|
||||||
|
|
||||||
[self setTabViewType:CPTopTabsBezelBorder];
|
|
||||||
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
|
|
||||||
|
|
||||||
[self addSubview:box];
|
|
||||||
[self addSubview:tabs];
|
|
||||||
|
|
||||||
[box setAutoresizingMask:CPViewWidthSizable];
|
|
||||||
[tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewDidMoveToWindow
|
||||||
|
{
|
||||||
|
if (_tabViewType != CPTopTabsBezelBorder || _labelsView)
|
||||||
|
return;
|
||||||
|
|
||||||
|
[self _createBezelBorder];
|
||||||
|
[self layoutSubviews];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @ignore */
|
||||||
|
- (void)_createBezelBorder
|
||||||
|
{
|
||||||
|
var bounds = [self bounds];
|
||||||
|
|
||||||
|
_labelsView = [[_CPTabLabelsView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), 0.0)];
|
||||||
|
|
||||||
|
[_labelsView setTabView:self];
|
||||||
|
[_labelsView setAutoresizingMask:CPViewWidthSizable];
|
||||||
|
|
||||||
|
[self addSubview:_labelsView];
|
||||||
|
|
||||||
|
_backgroundView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
|
[_backgroundView setBackgroundColor:CPTabViewBezelBorderBackgroundColor];
|
||||||
|
|
||||||
|
[_backgroundView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
|
|
||||||
|
[self addSubview:_backgroundView];
|
||||||
|
|
||||||
|
_separatorView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
|
[_separatorView setBackgroundColor:[[self class] bezelBorderColor]];
|
||||||
|
[_separatorView setAutoresizingMask:CPViewWidthSizable | CPViewMaxYMargin];
|
||||||
|
|
||||||
|
[self addSubview:_separatorView];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Lays out the subviews
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)layoutSubviews
|
||||||
|
{
|
||||||
|
if (_tabViewType == CPTopTabsBezelBorder)
|
||||||
|
{
|
||||||
|
var backgroundRect = [self bounds],
|
||||||
|
labelsViewHeight = [_CPTabLabelsView height];
|
||||||
|
|
||||||
|
backgroundRect.origin.y += labelsViewHeight;
|
||||||
|
backgroundRect.size.height -= labelsViewHeight;
|
||||||
|
|
||||||
|
[_backgroundView setFrame:backgroundRect];
|
||||||
|
|
||||||
|
var auxiliaryViewHeight = 5.0;
|
||||||
|
|
||||||
|
if (_auxiliaryView)
|
||||||
|
{
|
||||||
|
auxiliaryViewHeight = CGRectGetHeight([_auxiliaryView frame]);
|
||||||
|
|
||||||
|
[_auxiliaryView setFrame:CGRectMake(LEFT_INSET, labelsViewHeight, CGRectGetWidth(backgroundRect) - LEFT_INSET - RIGHT_INSET, auxiliaryViewHeight)];
|
||||||
|
}
|
||||||
|
|
||||||
|
[_separatorView setFrame:CGRectMake(LEFT_INSET, labelsViewHeight + auxiliaryViewHeight, CGRectGetWidth(backgroundRect) - LEFT_INSET - RIGHT_INSET, 1.0)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// CPNoTabsNoBorder
|
||||||
|
[_contentView setFrame:[self contentRect]];
|
||||||
|
}
|
||||||
|
|
||||||
// Adding and Removing Tabs
|
// Adding and Removing Tabs
|
||||||
/*!
|
/*!
|
||||||
Adds a CPTabViewItem to the tab view.
|
Adds a CPTabViewItem to the tab view.
|
||||||
@@ -87,7 +229,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
|
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
[self insertTabViewItem:aTabViewItem atIndex:[items count]];
|
[self insertTabViewItem:aTabViewItem atIndex:[_tabViewItems count]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -98,13 +240,20 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
|
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
[items insertObject:aTabViewItem atIndex:anIndex];
|
if (!_labelsView && _tabViewType == CPTopTabsBezelBorder)
|
||||||
|
[self _createBezelBorder];
|
||||||
|
|
||||||
[self _updateItems];
|
[_tabViewItems insertObject:aTabViewItem atIndex:anIndex];
|
||||||
[self _repositionTabs];
|
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
[_labelsView tabView:self didAddTabViewItem:aTabViewItem];
|
||||||
[delegate tabViewDidChangeNumberOfTabViewItems:self];
|
|
||||||
|
[aTabViewItem _setTabView:self];
|
||||||
|
|
||||||
|
if ([_tabViewItems count] == 1)
|
||||||
|
[self selectFirstTabViewItem:self];
|
||||||
|
|
||||||
|
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
||||||
|
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -113,19 +262,16 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
|
- (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
for (var i = 0; i < [items count]; i++)
|
var index = [self indexOfTabViewItem:aTabViewItem];
|
||||||
{
|
|
||||||
if ([items objectAtIndex:i] === aTabViewItem)
|
|
||||||
{
|
|
||||||
[items removeObjectAtIndex:i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[self _updateItems];
|
[_tabViewItems removeObjectIdenticalTo:aTabViewItem];
|
||||||
[self _repositionTabs];
|
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
[_labelsView tabView:self didRemoveTabViewItemAtIndex:index];
|
||||||
[delegate tabViewDidChangeNumberOfTabViewItems:self];
|
|
||||||
|
[aTabViewItem _setTabView:nil];
|
||||||
|
|
||||||
|
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
||||||
|
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessing Tabs
|
// Accessing Tabs
|
||||||
@@ -135,7 +281,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
|
- (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
return [items indexOfObjectIdenticalTo:aTabViewItem];
|
return [_tabViewItems indexOfObjectIdenticalTo:aTabViewItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -144,11 +290,14 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
|
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
|
||||||
{
|
{
|
||||||
for (var index = [items count]; index >= 0; index--)
|
var index = 0,
|
||||||
if ([[items[index] identifier] isEqual:anIdentifier])
|
count = [_tabViewItems count];
|
||||||
|
|
||||||
|
for (; index < count; ++index)
|
||||||
|
if ([[_tabViewItems[index] identifier] isEqual:anIdentifier])
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
return CPNotFound;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -156,7 +305,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (unsigned)numberOfTabViewItems
|
- (unsigned)numberOfTabViewItems
|
||||||
{
|
{
|
||||||
return [items count];
|
return [_tabViewItems count];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -164,7 +313,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
|
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
return [items objectAtIndex:anIndex];
|
return _tabViewItems[anIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -172,7 +321,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPArray)tabViewItems
|
- (CPArray)tabViewItems
|
||||||
{
|
{
|
||||||
return [items copy]; // Copy?
|
return _tabViewItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selecting a Tab
|
// Selecting a Tab
|
||||||
@@ -182,10 +331,10 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectFirstTabViewItem:(id)aSender
|
- (void)selectFirstTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if ([items count] === 0)
|
var count = [_tabViewItems count];
|
||||||
return; // throw?
|
|
||||||
|
|
||||||
[self selectTabViewItemAtIndex:0];
|
if (count)
|
||||||
|
[self selectTabViewItemAtIndex:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -194,10 +343,10 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectLastTabViewItem:(id)aSender
|
- (void)selectLastTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if ([items count] === 0)
|
var count = [_tabViewItems count];
|
||||||
return; // throw?
|
|
||||||
|
|
||||||
[self selectTabViewItemAtIndex:[items count] - 1];
|
if (count)
|
||||||
|
[self selectTabViewItemAtIndex:count - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -206,16 +355,13 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectNextTabViewItem:(id)aSender
|
- (void)selectNextTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if (selectedIndex === CPNotFound)
|
if (!_selectedTabViewItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var nextIndex = selectedIndex + 1;
|
var index = [self indexOfTabViewItem:_selectedTabViewItem],
|
||||||
|
count = [_tabViewItems count];
|
||||||
|
|
||||||
if (nextIndex === [items count])
|
[self selectTabViewItemAtIndex:index + 1 % count];
|
||||||
// does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:)
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self selectTabViewItemAtIndex:nextIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -224,15 +370,13 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectPreviousTabViewItem:(id)aSender
|
- (void)selectPreviousTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if (selectedIndex === CPNotFound)
|
if (!_selectedTabViewItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var previousIndex = selectedIndex - 1;
|
var index = [self indexOfTabViewItem:_selectedTabViewItem],
|
||||||
|
count = [_tabViewItems count];
|
||||||
|
|
||||||
if (previousIndex < 0)
|
[self selectTabViewItemAtIndex:index == 0 ? count : index - 1];
|
||||||
return; // does nothing. See above.
|
|
||||||
|
|
||||||
[self selectTabViewItemAtIndex:previousIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -241,7 +385,41 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectTabViewItem:(CPTabViewItem)aTabViewItem
|
- (void)selectTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
[self selectTabViewItemAtIndex:[self indexOfTabViewItem:aTabViewItem]];
|
if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![_delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
|
||||||
|
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
|
||||||
|
|
||||||
|
if (_selectedTabViewItem)
|
||||||
|
{
|
||||||
|
_selectedTabViewItem._tabState = CPBackgroundTab;
|
||||||
|
[_labelsView tabView:self didChangeStateOfTabViewItem:_selectedTabViewItem];
|
||||||
|
|
||||||
|
[_contentView removeFromSuperview];
|
||||||
|
[_auxiliaryView removeFromSuperview];
|
||||||
|
}
|
||||||
|
_selectedTabViewItem = aTabViewItem;
|
||||||
|
|
||||||
|
_selectedTabViewItem._tabState = CPSelectedTab;
|
||||||
|
|
||||||
|
_contentView = [_selectedTabViewItem view];
|
||||||
|
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
|
|
||||||
|
_auxiliaryView = [_selectedTabViewItem auxiliaryView];
|
||||||
|
[_auxiliaryView setAutoresizingMask:CPViewWidthSizable];
|
||||||
|
|
||||||
|
[self addSubview:_contentView];
|
||||||
|
|
||||||
|
if (_auxiliaryView)
|
||||||
|
[self addSubview:_auxiliaryView];
|
||||||
|
|
||||||
|
[_labelsView tabView:self didChangeStateOfTabViewItem:_selectedTabViewItem];
|
||||||
|
|
||||||
|
[self layoutSubviews];
|
||||||
|
|
||||||
|
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
|
||||||
|
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -250,24 +428,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
|
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
var aTabViewItem = [items objectAtIndex:anIndex];
|
[self selectTabViewItem:_tabViewItems[anIndex]];
|
||||||
|
|
||||||
if (anIndex === selectedIndex)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
|
|
||||||
|
|
||||||
if ((delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
|
|
||||||
[delegate tabView:self willSelectTabViewItem:aTabViewItem];
|
|
||||||
|
|
||||||
[tabs selectSegmentWithTag:anIndex];
|
|
||||||
[self _setSelectedIndex:anIndex];
|
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
|
|
||||||
[delegate tabView:self didSelectTabViewItem:aTabViewItem];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -275,7 +436,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPTabViewItem)selectedTabViewItem
|
- (CPTabViewItem)selectedTabViewItem
|
||||||
{
|
{
|
||||||
return [items objectAtIndex:selectedIndex];
|
return _selectedTabViewItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -285,33 +446,22 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)setTabViewType:(CPTabViewType)aTabViewType
|
- (void)setTabViewType:(CPTabViewType)aTabViewType
|
||||||
{
|
{
|
||||||
if (type === aTabViewType)
|
if (_tabViewType == aTabViewType)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((type === CPTopTabsBezelBorder || type === CPBottomTabsBezelBorder)
|
_tabViewType = aTabViewType;
|
||||||
&& (aTabViewType !== CPTopTabsBezelBorder && aTabViewType !== CPBottomTabsBezelBorder))
|
|
||||||
[tabs removeFromSuperview];
|
|
||||||
|
|
||||||
if ((type === CPNoTabsBezelBorder || type === CPNoTabsLineBorder || type === CPNoTabsNoBorder)
|
if (_tabViewType == CPNoTabsBezelBorder || _tabViewType == CPNoTabsLineBorder || _tabViewType == CPNoTabsNoBorder)
|
||||||
&& (aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsNoBorder))
|
[_labelsView removeFromSuperview];
|
||||||
[self addSubview:tabs];
|
else if (![_labelsView superview])
|
||||||
|
[self addSubview:_labelsView];
|
||||||
|
|
||||||
type = aTabViewType;
|
if (_tabViewType == CPNoTabsLineBorder || _tabViewType == CPNoTabsNoBorder)
|
||||||
|
[_backgroundView removeFromSuperview];
|
||||||
|
else if (![_backgroundView superview])
|
||||||
|
[self addSubview:_backgroundView];
|
||||||
|
|
||||||
switch (type)
|
[self layoutSubviews];
|
||||||
{
|
|
||||||
case CPTopTabsBezelBorder:
|
|
||||||
case CPBottomTabsBezelBorder:
|
|
||||||
case CPNoTabsBezelBorder:
|
|
||||||
[box setBorderType:CPBezelBorder];
|
|
||||||
break;
|
|
||||||
case CPNoTabsLineBorder:
|
|
||||||
[box setBorderType:CPLineBorder];
|
|
||||||
break;
|
|
||||||
case CPNoTabsNoBorder:
|
|
||||||
[box setBorderType:CPNoBorder];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -319,7 +469,31 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPTabViewType)tabViewType
|
- (CPTabViewType)tabViewType
|
||||||
{
|
{
|
||||||
return type;
|
return _tabViewType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determining the Size
|
||||||
|
/*!
|
||||||
|
Returns the content rectangle.
|
||||||
|
*/
|
||||||
|
- (CGRect)contentRect
|
||||||
|
{
|
||||||
|
var contentRect = CGRectMakeCopy([self bounds]);
|
||||||
|
|
||||||
|
if (_tabViewType == CPTopTabsBezelBorder)
|
||||||
|
{
|
||||||
|
var labelsViewHeight = [_CPTabLabelsView height],
|
||||||
|
auxiliaryViewHeight = _auxiliaryView ? CGRectGetHeight([_auxiliaryView frame]) : 5.0,
|
||||||
|
separatorViewHeight = 1.0;
|
||||||
|
|
||||||
|
contentRect.origin.y += labelsViewHeight + auxiliaryViewHeight + separatorViewHeight;
|
||||||
|
contentRect.size.height -= labelsViewHeight + auxiliaryViewHeight + separatorViewHeight * 2.0; // 2 for the bottom border as well.
|
||||||
|
|
||||||
|
contentRect.origin.x += LEFT_INSET;
|
||||||
|
contentRect.size.width -= LEFT_INSET + RIGHT_INSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -327,7 +501,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (id)delegate
|
- (id)delegate
|
||||||
{
|
{
|
||||||
return delegate;
|
return _delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -336,74 +510,35 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)setDelegate:(id)aDelegate
|
- (void)setDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
if (delegate == aDelegate)
|
if (_delegate == aDelegate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delegate = aDelegate;
|
_delegate = aDelegate;
|
||||||
|
|
||||||
delegateSelectors = 0;
|
_delegateSelectors = 0;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
|
if ([_delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
|
||||||
delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
|
_delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
|
if ([_delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
|
||||||
delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
|
_delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
|
if ([_delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
|
||||||
delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
|
_delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
if ([_delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
||||||
delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector;
|
_delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBackgroundColor:(CPColor)aColor
|
//
|
||||||
{
|
|
||||||
[box setBackgroundColor:aColor];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)mouseDown:(CPEvent)anEvent
|
- (void)mouseDown:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var segmentIndex = [tabs testSegment:[tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
|
var location = [_labelsView convertPoint:[anEvent locationInWindow] fromView:nil],
|
||||||
|
tabViewItem = [_labelsView representedTabViewItemAtPoint:location];
|
||||||
|
|
||||||
if (segmentIndex != CPNotFound)
|
if (tabViewItem)
|
||||||
{
|
[self selectTabViewItem:tabViewItem];
|
||||||
[self selectTabViewItemAtIndex:segmentIndex];
|
|
||||||
[tabs trackSegment:anEvent];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_repositionTabs
|
|
||||||
{
|
|
||||||
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
|
|
||||||
verticalCenterOfTabs = CGRectGetHeight([tabs bounds]) / 2;
|
|
||||||
|
|
||||||
if (type === CPBottomTabsBezelBorder)
|
|
||||||
[tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
|
|
||||||
else
|
|
||||||
[tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_setSelectedIndex:(CPNumber)index
|
|
||||||
{
|
|
||||||
selectedIndex = index;
|
|
||||||
|
|
||||||
[box setContentView:[[items objectAtIndex:selectedIndex] view]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_updateItems
|
|
||||||
{
|
|
||||||
[tabs setSegmentCount:[items count]];
|
|
||||||
|
|
||||||
for (var i = 0; i < [items count]; i++)
|
|
||||||
{
|
|
||||||
[tabs setLabel:[[items objectAtIndex:i] label] forSegment:i];
|
|
||||||
[tabs setTag:i forSegment:i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedIndex === CPNotFound)
|
|
||||||
{
|
|
||||||
[self selectFirstTabViewItem:self];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -419,12 +554,15 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
|||||||
{
|
{
|
||||||
if (self = [super initWithCoder:aCoder])
|
if (self = [super initWithCoder:aCoder])
|
||||||
{
|
{
|
||||||
type = [aCoder decodeIntForKey:CPTabViewTypeKey];
|
_tabViewType = [aCoder decodeIntForKey:CPTabViewTypeKey];
|
||||||
items = [];
|
_tabViewItems = [];
|
||||||
|
|
||||||
var encodedItems = [aCoder decodeObjectForKey:CPTabViewItemsKey];
|
// FIXME: this is somewhat hacky
|
||||||
for (var i = 0; encodedItems && i < encodedItems.length; i++)
|
[self _createBezelBorder];
|
||||||
[self insertTabViewItem:encodedItems[i] atIndex:i];
|
|
||||||
|
var items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
|
||||||
|
for (var i = 0; items && i < items.length; i++)
|
||||||
|
[self insertTabViewItem:items[i] atIndex:i];
|
||||||
|
|
||||||
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
|
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
|
||||||
if (selected)
|
if (selected)
|
||||||
@@ -438,14 +576,227 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
|||||||
|
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
{
|
{
|
||||||
|
var actualSubviews = _subviews;
|
||||||
|
_subviews = [];
|
||||||
[super encodeWithCoder:aCoder];
|
[super encodeWithCoder:aCoder];
|
||||||
|
_subviews = actualSubviews;
|
||||||
|
|
||||||
[aCoder encodeObject:items forKey:CPTabViewItemsKey];;
|
[aCoder encodeObject:_tabViewItems forKey:CPTabViewItemsKey];;
|
||||||
[aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey];
|
[aCoder encodeObject:_selectedTabViewItem forKey:CPTabViewSelectedItemKey];
|
||||||
|
|
||||||
[aCoder encodeInt:type forKey:CPTabViewTypeKey];
|
[aCoder encodeInt:_tabViewType forKey:CPTabViewTypeKey];
|
||||||
|
|
||||||
[aCoder encodeConditionalObject:delegate forKey:CPTabViewDelegateKey];
|
[aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
var _CPTabLabelsViewBackgroundColor = nil,
|
||||||
|
_CPTabLabelsViewInsideMargin = 10.0,
|
||||||
|
_CPTabLabelsViewOutsideMargin = 15.0;
|
||||||
|
|
||||||
|
/* @ignore */
|
||||||
|
@implementation _CPTabLabelsView : CPView
|
||||||
|
{
|
||||||
|
CPTabView _tabView;
|
||||||
|
CPDictionary _tabLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
if (self != [_CPTabLabelsView class])
|
||||||
|
return;
|
||||||
|
|
||||||
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
|
|
||||||
|
_CPTabLabelsViewBackgroundColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
|
||||||
|
[
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelsViewLeft.png"] size:CGSizeMake(12.0, 26.0)],
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelsViewCenter.png"] size:CGSizeMake(1.0, 26.0)],
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelsViewRight.png"] size:CGSizeMake(12.0, 26.0)]
|
||||||
|
] isVertical:NO]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (float)height
|
||||||
|
{
|
||||||
|
return 26.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
|
{
|
||||||
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
_tabLabels = [];
|
||||||
|
|
||||||
|
[self setBackgroundColor:_CPTabLabelsViewBackgroundColor];
|
||||||
|
|
||||||
|
[self setFrameSize:CGSizeMake(CGRectGetWidth(aFrame), 26.0)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setTabView:(CPTabView)aTabView
|
||||||
|
{
|
||||||
|
_tabView = aTabView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPTabView)tabView
|
||||||
|
{
|
||||||
|
return _tabView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tabView:(CPTabView)aTabView didAddTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
|
{
|
||||||
|
var label = [[_CPTabLabel alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
|
[label setTabViewItem:aTabViewItem];
|
||||||
|
|
||||||
|
_tabLabels.push(label);
|
||||||
|
|
||||||
|
[self addSubview:label];
|
||||||
|
|
||||||
|
[self layoutSubviews];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tabView:(CPTabView)aTabView didRemoveTabViewItemAtIndex:(unsigned)index
|
||||||
|
{
|
||||||
|
var label = _tabLabels[index];
|
||||||
|
|
||||||
|
[_tabLabels removeObjectAtIndex:index];
|
||||||
|
|
||||||
|
[label removeFromSuperview];
|
||||||
|
|
||||||
|
[self layoutSubviews];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)tabView:(CPTabView)aTabView didChangeStateOfTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
|
{
|
||||||
|
[_tabLabels[[aTabView indexOfTabViewItem:aTabViewItem]] setTabState:[aTabViewItem tabState]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPTabViewItem)representedTabViewItemAtPoint:(CGPoint)aPoint
|
||||||
|
{
|
||||||
|
var index = 0,
|
||||||
|
count = _tabLabels.length;
|
||||||
|
|
||||||
|
for (; index < count; ++index)
|
||||||
|
{
|
||||||
|
var label = _tabLabels[index];
|
||||||
|
|
||||||
|
if (CGRectContainsPoint([label frame], aPoint))
|
||||||
|
return [label tabViewItem];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews
|
||||||
|
{
|
||||||
|
var index = 0,
|
||||||
|
count = _tabLabels.length,
|
||||||
|
width = (_CGRectGetWidth([self bounds]) - (count - 1) * _CPTabLabelsViewInsideMargin - 2 * _CPTabLabelsViewOutsideMargin) / count,
|
||||||
|
x = _CPTabLabelsViewOutsideMargin;
|
||||||
|
|
||||||
|
for (; index < count; ++index)
|
||||||
|
{
|
||||||
|
var label = _tabLabels[index],
|
||||||
|
frame = _CGRectMake(x, 8.0, width, 18.0);
|
||||||
|
|
||||||
|
[label setFrame:frame];
|
||||||
|
|
||||||
|
x = _CGRectGetMaxX(frame) + _CPTabLabelsViewInsideMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFrameSize:(CGSize)aSize
|
||||||
|
{
|
||||||
|
if (CGSizeEqualToSize([self frame].size, aSize))
|
||||||
|
return;
|
||||||
|
|
||||||
|
[super setFrameSize:aSize];
|
||||||
|
|
||||||
|
[self layoutSubviews];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
var _CPTabLabelBackgroundColor = nil,
|
||||||
|
_CPTabLabelSelectedBackgroundColor = nil;
|
||||||
|
|
||||||
|
/* @ignore */
|
||||||
|
@implementation _CPTabLabel : CPView
|
||||||
|
{
|
||||||
|
CPTabViewItem _tabViewItem;
|
||||||
|
CPTextField _labelField;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
if (self != [_CPTabLabel class])
|
||||||
|
return;
|
||||||
|
|
||||||
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
|
|
||||||
|
_CPTabLabelBackgroundColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
|
||||||
|
[
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelBackgroundLeft.png"] size:CGSizeMake(6.0, 18.0)],
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelBackgroundCenter.png"] size:CGSizeMake(1.0, 18.0)],
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelBackgroundRight.png"] size:CGSizeMake(6.0, 18.0)]
|
||||||
|
] isVertical:NO]];
|
||||||
|
|
||||||
|
_CPTabLabelSelectedBackgroundColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
|
||||||
|
[
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelSelectedLeft.png"] size:CGSizeMake(3.0, 18.0)],
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelSelectedCenter.png"] size:CGSizeMake(1.0, 18.0)],
|
||||||
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPTabView/_CPTabLabelSelectedRight.png"] size:CGSizeMake(3.0, 18.0)]
|
||||||
|
] isVertical:NO]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
|
{
|
||||||
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
_labelField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
|
[_labelField setAlignment:CPCenterTextAlignment];
|
||||||
|
[_labelField setFrame:CGRectMake(5.0, 0.0, CGRectGetWidth(aFrame) - 10.0, 20.0)];
|
||||||
|
[_labelField setAutoresizingMask:CPViewWidthSizable];
|
||||||
|
[_labelField setFont:[CPFont boldSystemFontOfSize:11.0]];
|
||||||
|
|
||||||
|
[self addSubview:_labelField];
|
||||||
|
|
||||||
|
[self setTabState:CPBackgroundTab];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setTabState:(CPTabState)aTabState
|
||||||
|
{
|
||||||
|
[self setBackgroundColor:aTabState == CPSelectedTab ? _CPTabLabelSelectedBackgroundColor : _CPTabLabelBackgroundColor];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
|
{
|
||||||
|
_tabViewItem = aTabViewItem;
|
||||||
|
|
||||||
|
[self update];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPTabViewItem)tabViewItem
|
||||||
|
{
|
||||||
|
return _tabViewItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)update
|
||||||
|
{
|
||||||
|
[_labelField setStringValue:[_tabViewItem label]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+13
-97
@@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
@import <Foundation/CPDictionary.j>
|
@import <Foundation/CPDictionary.j>
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
@import <Foundation/CPIndexSet.j>
|
|
||||||
@import <Foundation/CPSortDescriptor.j>
|
@import <Foundation/CPSortDescriptor.j>
|
||||||
@import <Foundation/CPString.j>
|
@import <Foundation/CPString.j>
|
||||||
|
|
||||||
@import "CPTableHeaderView.j"
|
@import "CPTableHeaderView.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
CPTableColumnNoResizing = 0;
|
CPTableColumnNoResizing = 0;
|
||||||
CPTableColumnAutoresizingMask = 1 << 0;
|
CPTableColumnAutoresizingMask = 1 << 0;
|
||||||
@@ -78,7 +78,13 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
var header = [[_CPTableColumnHeaderView alloc] initWithFrame:CGRectMakeZero()];
|
var header = [[_CPTableColumnHeaderView alloc] initWithFrame:CGRectMakeZero()];
|
||||||
[self setHeaderView:header];
|
[self setHeaderView:header];
|
||||||
|
|
||||||
[self setDataView:[CPTextField new]];
|
var textDataView = [CPTextField new];
|
||||||
|
[textDataView setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||||
|
[textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"];
|
||||||
|
[textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelected];
|
||||||
|
[textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelected];
|
||||||
|
[textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
|
||||||
|
[self setDataView:textDataView];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -242,11 +248,12 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
*/
|
*/
|
||||||
- (void)setDataView:(CPView)aView
|
- (void)setDataView:(CPView)aView
|
||||||
{
|
{
|
||||||
|
if (_dataView === aView)
|
||||||
|
return;
|
||||||
|
|
||||||
if (_dataView)
|
if (_dataView)
|
||||||
_dataViewData[[_dataView UID]] = nil;
|
_dataViewData[[_dataView UID]] = nil;
|
||||||
|
|
||||||
[aView setThemeState:CPThemeStateTableDataView];
|
|
||||||
|
|
||||||
_dataView = aView;
|
_dataView = aView;
|
||||||
_dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
|
_dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
|
||||||
}
|
}
|
||||||
@@ -286,9 +293,6 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
|
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
|
||||||
newDataView.identifier = dataViewUID;
|
newDataView.identifier = dataViewUID;
|
||||||
|
|
||||||
// make sure only we have control over the size and placement
|
|
||||||
[newDataView setAutoresizingMask:CPViewNotSizable];
|
|
||||||
|
|
||||||
return newDataView;
|
return newDataView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,14 +348,7 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
|
|
||||||
- (void)setHidden:(BOOL)shouldBeHidden
|
- (void)setHidden:(BOOL)shouldBeHidden
|
||||||
{
|
{
|
||||||
shouldBeHidden = !!shouldBeHidden
|
|
||||||
if (_isHidden === shouldBeHidden)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_isHidden = shouldBeHidden;
|
_isHidden = shouldBeHidden;
|
||||||
|
|
||||||
[[self headerView] setHidden:shouldBeHidden];
|
|
||||||
[[self tableView] _tableColumnVisibilityDidChange:self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isHidden
|
- (BOOL)isHidden
|
||||||
@@ -385,86 +382,13 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation CPTableColumn (Bindings)
|
|
||||||
|
|
||||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
|
||||||
{
|
|
||||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
|
||||||
|
|
||||||
if (![aBinding isEqual:@"someListOfExceptedBindings(notAcceptedBindings)"])
|
|
||||||
[[self tableView] _establishBindingsIfUnbound:anObject];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)prepareDataView:(CPView)aDataView forRow:(unsigned)aRow
|
|
||||||
{
|
|
||||||
var bindingsDictionary = [CPKeyValueBinding allBindingsForObject:self],
|
|
||||||
keys = [bindingsDictionary allKeys];
|
|
||||||
|
|
||||||
for (var i = 0, count = [keys count]; i < count; i++)
|
|
||||||
{
|
|
||||||
var bindingName = keys[i],
|
|
||||||
bindingPath = [aDataView _replacementKeyPathForBinding:bindingName],
|
|
||||||
binding = [bindingsDictionary objectForKey:bindingName],
|
|
||||||
bindingInfo = binding._info,
|
|
||||||
destination = [bindingInfo objectForKey:CPObservedObjectKey],
|
|
||||||
keyPath = [bindingInfo objectForKey:CPObservedKeyPathKey],
|
|
||||||
dotIndex = keyPath.lastIndexOf("."),
|
|
||||||
value;
|
|
||||||
|
|
||||||
if (dotIndex === CPNotFound)
|
|
||||||
value = [[destination valueForKeyPath:keyPath] objectAtIndex:aRow];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Optimize the prototypical use case where the key path describes a value
|
|
||||||
in an array. Without this optimization, we call CPArray's valueForKey
|
|
||||||
which generates as many values as objects in the array, of which we then
|
|
||||||
pick one and throw away the rest.
|
|
||||||
|
|
||||||
The optimization is to get the array and access the value directly. This
|
|
||||||
turns the operation into a single access regardless of how long the model
|
|
||||||
array is.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var firstPart = keyPath.substring(0, dotIndex),
|
|
||||||
secondPart = keyPath.substring(dotIndex + 1),
|
|
||||||
firstValue = [destination valueForKeyPath:firstPart];
|
|
||||||
|
|
||||||
if ([firstValue isKindOfClass:CPArray])
|
|
||||||
value = [[firstValue objectAtIndex:aRow] valueForKeyPath:secondPart];
|
|
||||||
else
|
|
||||||
value = [[firstValue valueForKeyPath:secondPart] objectAtIndex:aRow];
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [binding transformValue:value withOptions:[bindingInfo objectForKey:CPOptionsKey]];
|
|
||||||
|
|
||||||
// console.log(bindingName+" : "+keyPath+" : "+aRow+" : "+[[destination valueForKeyPath:keyPath] objectAtIndex:aRow]);
|
|
||||||
[aDataView setValue:value forKey:bindingPath];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//- (void)objectValue
|
|
||||||
//{
|
|
||||||
// return nil;
|
|
||||||
//}
|
|
||||||
|
|
||||||
- (void)setValue:(CPArray)content
|
|
||||||
{
|
|
||||||
[[self tableView] reloadData];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
|
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
|
||||||
CPTableColumnHeaderViewKey = @"CPTableColumnHeaderViewKey",
|
CPTableColumnHeaderViewKey = @"CPTableColumnHeaderViewKey",
|
||||||
CPTableColumnDataViewKey = @"CPTableColumnDataViewKey",
|
CPTableColumnDataViewKey = @"CPTableColumnDataViewKey",
|
||||||
CPTableColumnWidthKey = @"CPTableColumnWidthKey",
|
CPTableColumnWidthKey = @"CPTableColumnWidthKey",
|
||||||
CPTableColumnMinWidthKey = @"CPTableColumnMinWidthKey",
|
CPTableColumnMinWidthKey = @"CPTableColumnMinWidthKey",
|
||||||
CPTableColumnMaxWidthKey = @"CPTableColumnMaxWidthKey",
|
CPTableColumnMaxWidthKey = @"CPTableColumnMaxWidthKey",
|
||||||
CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey",
|
CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey";
|
||||||
CPTableColumnIsHiddenKey = @"CPTableColumnIsHiddenKey",
|
|
||||||
CPSortDescriptorPrototypeKey = @"CPSortDescriptorPrototypeKey",
|
|
||||||
CPTableColumnIsEditableKey = @"CPTableColumnIsEditableKey";
|
|
||||||
|
|
||||||
@implementation CPTableColumn (CPCoding)
|
@implementation CPTableColumn (CPCoding)
|
||||||
|
|
||||||
@@ -485,11 +409,7 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
|
|||||||
[self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
|
[self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
|
||||||
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
|
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
|
||||||
|
|
||||||
_resizingMask = [aCoder decodeIntForKey:CPTableColumnResizingMaskKey];
|
_resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey];
|
||||||
_isHidden = [aCoder decodeBoolForKey:CPTableColumnIsHiddenKey];
|
|
||||||
_isEditable = [aCoder decodeBoolForKey:CPTableColumnIsEditableKey];
|
|
||||||
|
|
||||||
_sortDescriptorPrototype = [aCoder decodeObjectForKey:CPSortDescriptorPrototypeKey];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -507,10 +427,6 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
|
|||||||
[aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
|
[aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
|
[aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
|
||||||
[aCoder encodeBool:_isHidden forKey:CPTableColumnIsHiddenKey];
|
|
||||||
[aCoder encodeBool:_isEditable forKey:CPTableColumnIsEditableKey];
|
|
||||||
|
|
||||||
[aCoder encodeObject:_sortDescriptorPrototype forKey:CPSortDescriptorPrototypeKey];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+156
-342
@@ -20,64 +20,54 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPIndexSet.j>
|
|
||||||
|
|
||||||
@import "CPTableColumn.j"
|
@import "CPTableColumn.j"
|
||||||
@import "CPTableView.j"
|
@import "CPTableView.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
|
|
||||||
@implementation _CPTableColumnHeaderView : CPView
|
@implementation _CPTableColumnHeaderView : CPView
|
||||||
{
|
{
|
||||||
_CPImageAndTextView _textField;
|
_CPImageAndTextView _textField;
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
|
||||||
{
|
|
||||||
return @"columnHeader";
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)themeAttributes
|
|
||||||
{
|
|
||||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
|
|
||||||
forKeys:[@"background-color", @"text-alignment", @"text-inset", @"text-color", @"text-font", @"text-shadow-color", @"text-shadow-offset"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)initWithFrame:(CGRect)frame
|
- (void)initWithFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:frame];
|
self = [super initWithFrame:frame];
|
||||||
if (self)
|
if (self)
|
||||||
|
{
|
||||||
[self _init];
|
[self _init];
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_init
|
- (void)_init
|
||||||
{
|
{
|
||||||
_textField = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
|
_textField = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(5, 1, CGRectGetWidth([self bounds]) - 10, CGRectGetHeight([self bounds]) - 1)];
|
||||||
|
|
||||||
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
||||||
|
|
||||||
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
|
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||||
|
[_textField setTextColor: [CPColor colorWithHexString: @"333333"]];
|
||||||
|
[_textField setFont:[CPFont boldSystemFontOfSize:12.0]];
|
||||||
[_textField setAlignment:CPLeftTextAlignment];
|
[_textField setAlignment:CPLeftTextAlignment];
|
||||||
[_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
|
[_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||||
|
[_textField setTextShadowColor:[CPColor whiteColor]];
|
||||||
|
[_textField setTextShadowOffset:CGSizeMake(0,1)];
|
||||||
|
|
||||||
[self addSubview:_textField];
|
[self addSubview:_textField];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)layoutSubviews
|
- (void)layoutSubviews
|
||||||
{
|
{
|
||||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
|
var themeState = [self themeState];
|
||||||
|
|
||||||
var inset = [self currentValueForThemeAttribute:@"text-inset"],
|
if(themeState & CPThemeStateSelected && themeState & CPThemeStateHighlighted)
|
||||||
bounds = [self bounds];
|
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted-pressed.png", CGSizeMake(1.0, 22.0))]];
|
||||||
|
else if (themeState & CPThemeStateSelected)
|
||||||
[_textField setFrame:_CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
|
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted.png", CGSizeMake(1.0, 22.0))]];
|
||||||
[_textField setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
|
else if (themeState & CPThemeStateHighlighted)
|
||||||
[_textField setFont:[self currentValueForThemeAttribute:@"text-font"]];
|
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-pressed.png", CGSizeMake(1.0, 22.0))]];
|
||||||
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
|
else
|
||||||
[_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
|
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
|
||||||
[_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setStringValue:(CPString)string
|
- (void)setStringValue:(CPString)string
|
||||||
@@ -105,6 +95,11 @@
|
|||||||
[_textField setFont:aFont];
|
[_textField setFont:aFont];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setValue:(id)aValue forThemeAttribute:(id)aKey
|
||||||
|
{
|
||||||
|
[_textField setValue:aValue forThemeAttribute:aKey];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)_setIndicatorImage:(CPImage)anImage
|
- (void)_setIndicatorImage:(CPImage)anImage
|
||||||
{
|
{
|
||||||
if (anImage)
|
if (anImage)
|
||||||
@@ -152,47 +147,27 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
|
|
||||||
@implementation CPTableHeaderView : CPView
|
@implementation CPTableHeaderView : CPView
|
||||||
{
|
{
|
||||||
CGPoint _mouseDownLocation;
|
int _resizedColumn @accessors(readonly, property=resizedColumn);
|
||||||
CGPoint _previousTrackingLocation;
|
int _draggedColumn @accessors(readonly, property=draggedColumn);
|
||||||
int _activeColumn;
|
int _pressedColumn @accessors(readonly, property=pressedColumn);
|
||||||
int _pressedColumn;
|
|
||||||
|
|
||||||
BOOL _isResizing;
|
float _draggedDistance @accessors(readonly, property=draggedDistance);
|
||||||
BOOL _isDragging;
|
float _lastLocation;
|
||||||
BOOL _isTrackingColumn;
|
float _columnOldWidth;
|
||||||
BOOL _drawsColumnLines;
|
|
||||||
|
|
||||||
float _columnOldWidth;
|
CPTableView _tableView @accessors(property=tableView);
|
||||||
|
|
||||||
CPTableView _tableView @accessors(property=tableView);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
|
||||||
{
|
|
||||||
return @"tableHeaderRow";
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)themeAttributes
|
|
||||||
{
|
|
||||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPColor grayColor]]
|
|
||||||
forKeys:[@"background-color", @"divider-color"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_init
|
- (void)_init
|
||||||
{
|
{
|
||||||
_mouseDownLocation = _CGPointMakeZero();
|
_resizedColumn = -1;
|
||||||
_previousTrackingLocation = _CGPointMakeZero();
|
_draggedColumn = -1;
|
||||||
_activeColumn = -1;
|
|
||||||
_pressedColumn = -1;
|
_pressedColumn = -1;
|
||||||
|
_draggedDistance = 0.0;
|
||||||
|
_lastLocation = nil;
|
||||||
|
_columnOldWidth = nil;
|
||||||
|
|
||||||
_isResizing = NO;
|
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
|
||||||
_isDragging = NO;
|
|
||||||
_isTrackingColumn = NO;
|
|
||||||
_drawsColumnLines = YES;
|
|
||||||
|
|
||||||
_columnOldWidth = 0.0;
|
|
||||||
|
|
||||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -207,38 +182,36 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
|
|
||||||
- (int)columnAtPoint:(CGPoint)aPoint
|
- (int)columnAtPoint:(CGPoint)aPoint
|
||||||
{
|
{
|
||||||
return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
|
return [_tableView columnAtPoint:CGPointMake(aPoint.x, 0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)headerRectOfColumn:(int)aColumnIndex
|
- (CGRect)headerRectOfColumn:(int)aColumnIndex
|
||||||
{
|
{
|
||||||
var headerRect = [self bounds],
|
var tableColumns = [_tableView tableColumns];
|
||||||
columnRect = [_tableView rectOfColumn:aColumnIndex];
|
|
||||||
|
|
||||||
headerRect.origin.x = _CGRectGetMinX(columnRect);
|
if (aColumnIndex < 0 || aColumnIndex > [tableColumns count])
|
||||||
headerRect.size.width = _CGRectGetWidth(columnRect);
|
[CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"];
|
||||||
|
|
||||||
return headerRect;
|
// UPDATE COLUMN RANGES ?
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setDrawsColumnLines:(BOOL)aFlag
|
var tableRange = _tableView._tableColumnRanges[aColumnIndex],
|
||||||
{
|
bounds = [self bounds];
|
||||||
_drawsColumnLines = aFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)drawsColumnLines
|
var rMinX = ROUND(tableRange.location);
|
||||||
{
|
bounds.origin.x = rMinX;
|
||||||
return _drawsColumnLines;
|
bounds.size.width = FLOOR(tableRange.length + tableRange.location - rMinX);
|
||||||
|
|
||||||
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)_cursorRectForColumn:(int)column
|
- (CGRect)_cursorRectForColumn:(int)column
|
||||||
{
|
{
|
||||||
if (column == -1 || !([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask))
|
if (column == -1 || !([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask))
|
||||||
return _CGRectMakeZero();
|
return CGRectMakeZero();
|
||||||
|
|
||||||
var rect = [self headerRectOfColumn:column];
|
var rect = [self headerRectOfColumn:column];
|
||||||
|
|
||||||
rect.origin.x = _CGRectGetMaxX(rect) - 5;
|
rect.origin.x = CGRectGetMaxX(rect) - 5;
|
||||||
rect.size.width = 20;
|
rect.size.width = 20;
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
@@ -263,280 +236,104 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
|
|
||||||
- (void)mouseDown:(CPEvent)theEvent
|
- (void)mouseDown:(CPEvent)theEvent
|
||||||
{
|
{
|
||||||
[self trackMouse:theEvent];
|
var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
|
||||||
|
clickedColumn = [self columnAtPoint:mouseLocation];
|
||||||
|
|
||||||
|
// should we send column -1 ?
|
||||||
|
[_tableView _sendDelegateDidMouseDownInHeader:clickedColumn];
|
||||||
|
|
||||||
|
var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
|
||||||
|
resizedColumn = [self columnAtPoint:resizeLocation];
|
||||||
|
|
||||||
|
if (resizedColumn == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering
|
||||||
|
if ([_tableView allowsColumnResizing]
|
||||||
|
&& CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation))
|
||||||
|
{
|
||||||
|
_resizedColumn = resizedColumn;
|
||||||
|
[_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES];
|
||||||
|
[_tableView setDisableAutomaticResizing:YES];
|
||||||
|
[self trackResizeWithEvent:theEvent];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[self _setPressedColumn:clickedColumn];
|
||||||
|
[self trackMouseWithEvent:theEvent];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)trackMouse:(CPEvent)theEvent
|
- (void)trackMouseWithEvent:(CPEvent)theEvent
|
||||||
{
|
{
|
||||||
var type = [theEvent type],
|
var type = [theEvent type];
|
||||||
currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
|
||||||
|
|
||||||
// Take the right columns resize tracking area into account
|
if (type == CPLeftMouseUp)
|
||||||
currentLocation.x -= 5.0;
|
|
||||||
|
|
||||||
var columnIndex = [self columnAtPoint:currentLocation],
|
|
||||||
shouldResize = [self shouldResizeTableColumn:columnIndex at:_CGPointMake(currentLocation.x + 5.0, currentLocation.y)];
|
|
||||||
|
|
||||||
if (type === CPLeftMouseUp)
|
|
||||||
{
|
{
|
||||||
if (shouldResize)
|
var location = [self convertPoint:[theEvent locationInWindow] fromView:nil],
|
||||||
[self stopResizingTableColumn:_activeColumn at:currentLocation];
|
clickedColumn = [self columnAtPoint:location];
|
||||||
else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation])
|
|
||||||
{
|
|
||||||
[_tableView _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]];
|
|
||||||
[self stopTrackingTableColumn:columnIndex at:currentLocation];
|
|
||||||
|
|
||||||
_isTrackingColumn = NO;
|
[self _setPressedColumn:-1];
|
||||||
}
|
|
||||||
|
|
||||||
[self _updateResizeCursor:[CPApp currentEvent]];
|
if (clickedColumn != -1)
|
||||||
|
[_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]];
|
||||||
|
|
||||||
_activeColumn = CPNotFound;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === CPLeftMouseDown)
|
[CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)trackResizeWithEvent:(CPEvent)anEvent
|
||||||
|
{
|
||||||
|
var location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
||||||
|
tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn],
|
||||||
|
type = [anEvent type];
|
||||||
|
|
||||||
|
if (_lastLocation == nil)
|
||||||
|
_lastLocation = location;
|
||||||
|
|
||||||
|
if (_columnOldWidth == nil)
|
||||||
|
_columnOldWidth = [tableColumn width];
|
||||||
|
|
||||||
|
if (type === CPLeftMouseUp)
|
||||||
{
|
{
|
||||||
if (columnIndex === -1)
|
[self _updateResizeCursor:anEvent];
|
||||||
return;
|
|
||||||
|
|
||||||
_mouseDownLocation = currentLocation;
|
[tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
|
||||||
_activeColumn = columnIndex;
|
[tableColumn setDisableResizingPosting:NO];
|
||||||
|
[_tableView setDisableAutomaticResizing:NO];
|
||||||
|
|
||||||
[_tableView _sendDelegateDidMouseDownInHeader:columnIndex];
|
_resizedColumn = -1;
|
||||||
|
_lastLocation = nil;
|
||||||
|
_columnOldWidth = nil;
|
||||||
|
|
||||||
if (shouldResize)
|
return;
|
||||||
[self startResizingTableColumn:columnIndex at:currentLocation];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[self startTrackingTableColumn:columnIndex at:currentLocation];
|
|
||||||
_isTrackingColumn = YES;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (type === CPLeftMouseDragged)
|
else if (type === CPLeftMouseDragged)
|
||||||
{
|
{
|
||||||
if (shouldResize)
|
var newWidth = [tableColumn width] + location.x - _lastLocation.x;
|
||||||
[self continueResizingTableColumn:_activeColumn at:currentLocation];
|
|
||||||
|
if (newWidth < [tableColumn minWidth])
|
||||||
|
[[CPCursor resizeRightCursor] set];
|
||||||
|
else if (newWidth > [tableColumn maxWidth])
|
||||||
|
[[CPCursor resizeLeftCursor] set];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_activeColumn === columnIndex && _CGRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation))
|
_tableView._lastColumnShouldSnap = NO;
|
||||||
{
|
[tableColumn setWidth:newWidth];
|
||||||
if (_isTrackingColumn && _pressedColumn !== -1)
|
// FIXME: there has to be a better way to do this...
|
||||||
{
|
// We should refactor the auto resizing crap.
|
||||||
if (![self continueTrackingTableColumn:columnIndex at:currentLocation])
|
// We need to figure out the exact cocoa behavior here though.
|
||||||
return; // Stop tracking the column, because it's being dragged
|
_lastLocation = location;
|
||||||
} else
|
|
||||||
[self startTrackingTableColumn:columnIndex at:currentLocation];
|
|
||||||
|
|
||||||
} else if (_isTrackingColumn && _pressedColumn !== -1)
|
[[CPCursor resizeLeftRightCursor] set];
|
||||||
[self stopTrackingTableColumn:_activeColumn at:currentLocation];
|
[self setNeedsLayout];
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_previousTrackingLocation = currentLocation;
|
[CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
||||||
[CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)startTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
[self _setPressedColumn:aColumnIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
if ([self _shouldDragTableColumn:aColumnIndex at:aPoint])
|
|
||||||
{
|
|
||||||
var columnRect = [self headerRectOfColumn:aColumnIndex],
|
|
||||||
offset = _CGPointMakeZero(),
|
|
||||||
view = [_tableView _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset],
|
|
||||||
viewLocation = _CGPointMakeZero();
|
|
||||||
|
|
||||||
viewLocation.x = ( _CGRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x );
|
|
||||||
viewLocation.y = _CGRectGetMinY(columnRect) + offset.y;
|
|
||||||
|
|
||||||
[self dragView:view at:viewLocation offset:_CGSizeMakeZero() event:[CPApp currentEvent]
|
|
||||||
pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES];
|
|
||||||
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
return _isTrackingColumn && _activeColumn === aColumnIndex &&
|
|
||||||
_CGRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
[self _setPressedColumn:CPNotFound];
|
|
||||||
[self _updateResizeCursor:[CPApp currentEvent]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
return [_tableView allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGRect)_headerRectOfLastVisibleColumn
|
|
||||||
{
|
|
||||||
var tableColumns = [_tableView tableColumns],
|
|
||||||
columnIndex = [tableColumns count];
|
|
||||||
|
|
||||||
while (columnIndex--)
|
|
||||||
{
|
|
||||||
var tableColumn = [tableColumns objectAtIndex:columnIndex];
|
|
||||||
|
|
||||||
if (![tableColumn isHidden])
|
|
||||||
return [self headerRectOfColumn:columnIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_constrainDragView:(CPView)theDragView at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
var tableColumns = [_tableView tableColumns],
|
|
||||||
lastColumnRect = [self _headerRectOfLastVisibleColumn],
|
|
||||||
activeColumnRect = [self headerRectOfColumn:_activeColumn],
|
|
||||||
dragWindow = [theDragView window],
|
|
||||||
frame = [dragWindow frame];
|
|
||||||
|
|
||||||
// Convert the frame origin from the global coordinate system to the windows' coordinate system
|
|
||||||
frame.origin = [[self window] convertGlobalToBase:frame.origin];
|
|
||||||
// the from the window to the view
|
|
||||||
frame.origin = [self convertPoint:frame.origin fromView:nil];
|
|
||||||
|
|
||||||
// This effectively clamps the value between the minimum and maximum
|
|
||||||
frame.origin.x = MAX(0.0, MIN(_CGRectGetMinX(frame), _CGRectGetMaxX(lastColumnRect) - _CGRectGetWidth(activeColumnRect)));
|
|
||||||
|
|
||||||
// Make sure the column cannot move vertically
|
|
||||||
frame.origin.y = _CGRectGetMinY(lastColumnRect);
|
|
||||||
|
|
||||||
// Convert the calculated origin back to the window coordinate system
|
|
||||||
frame.origin = [self convertPoint:frame.origin toView:nil];
|
|
||||||
// Then back to the global coordinate system
|
|
||||||
frame.origin = [[self window] convertBaseToGlobal:frame.origin];
|
|
||||||
|
|
||||||
[dragWindow setFrame:frame];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex
|
|
||||||
{
|
|
||||||
[_tableView moveColumn:aFromIndex toColumn:aToIndex];
|
|
||||||
_activeColumn = aToIndex;
|
|
||||||
_pressedColumn = _activeColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)draggedView:(CPView)aView beganAt:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
_isDragging = YES;
|
|
||||||
|
|
||||||
var column = [[_tableView tableColumns] objectAtIndex:_activeColumn];
|
|
||||||
|
|
||||||
[[column headerView] setHidden:YES];
|
|
||||||
[_tableView _setDraggedColumn:column];
|
|
||||||
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)draggedView:(CPView)aView movedTo:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
[self _constrainDragView:aView at:aPoint];
|
|
||||||
|
|
||||||
var dragWindow = [aView window],
|
|
||||||
dragWindowFrame = [dragWindow frame];
|
|
||||||
|
|
||||||
var hoverPoint = CGPointCreateCopy(aPoint);
|
|
||||||
|
|
||||||
if (aPoint.x < _previousTrackingLocation.x)
|
|
||||||
hoverPoint = _CGPointMake(_CGRectGetMinX(dragWindowFrame), _CGRectGetMinY(dragWindowFrame));
|
|
||||||
else if (aPoint.x > _previousTrackingLocation.x)
|
|
||||||
hoverPoint = _CGPointMake(_CGRectGetMaxX(dragWindowFrame), _CGRectGetMinY(dragWindowFrame));
|
|
||||||
|
|
||||||
// Convert the hover point from the global coordinate system to windows' coordinate system
|
|
||||||
hoverPoint = [[self window] convertGlobalToBase:hoverPoint];
|
|
||||||
// then to the view
|
|
||||||
hoverPoint = [self convertPoint:hoverPoint fromView:nil];
|
|
||||||
|
|
||||||
var hoveredColumn = [self columnAtPoint:hoverPoint];
|
|
||||||
|
|
||||||
if (hoveredColumn !== -1)
|
|
||||||
{
|
|
||||||
var columnRect = [self headerRectOfColumn:hoveredColumn],
|
|
||||||
columnCenterPoint = [self convertPoint:CGPointMake(_CGRectGetMidX(columnRect), _CGRectGetMidY(columnRect)) fromView:self];
|
|
||||||
if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x)
|
|
||||||
[self _moveColumn:_activeColumn toColumn:hoveredColumn];
|
|
||||||
else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x)
|
|
||||||
[self _moveColumn:_activeColumn toColumn:hoveredColumn];
|
|
||||||
}
|
|
||||||
|
|
||||||
_previousTrackingLocation = aPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
|
|
||||||
{
|
|
||||||
_isDragging = NO;
|
|
||||||
_isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached
|
|
||||||
|
|
||||||
[_tableView _setDraggedColumn:nil];
|
|
||||||
[[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO];
|
|
||||||
[self stopTrackingTableColumn:_activeColumn at:aLocation];
|
|
||||||
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
if (_isResizing)
|
|
||||||
return YES;
|
|
||||||
|
|
||||||
if (_isTrackingColumn)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
return [_tableView allowsColumnResizing] && _CGRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)startResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
_isResizing = YES;
|
|
||||||
|
|
||||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
|
|
||||||
|
|
||||||
[tableColumn setDisableResizingPosting:YES];
|
|
||||||
[_tableView setDisableAutomaticResizing:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)continueResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
|
|
||||||
newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x;
|
|
||||||
|
|
||||||
if (newWidth < [tableColumn minWidth])
|
|
||||||
[[CPCursor resizeRightCursor] set];
|
|
||||||
else if (newWidth > [tableColumn maxWidth])
|
|
||||||
[[CPCursor resizeLeftCursor] set];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_tableView._lastColumnShouldSnap = NO;
|
|
||||||
[tableColumn setWidth:newWidth];
|
|
||||||
|
|
||||||
[[CPCursor resizeLeftRightCursor] set];
|
|
||||||
[self setNeedsLayout];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)stopResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
|
|
||||||
{
|
|
||||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
|
|
||||||
[tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
|
|
||||||
[tableColumn setDisableResizingPosting:NO];
|
|
||||||
[_tableView setDisableAutomaticResizing:NO];
|
|
||||||
|
|
||||||
_isResizing = NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_updateResizeCursor:(CPEvent)theEvent
|
- (void)_updateResizeCursor:(CPEvent)theEvent
|
||||||
@@ -552,7 +349,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
|
mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
|
||||||
overColumn = [self columnAtPoint:mouseOverLocation];
|
overColumn = [self columnAtPoint:mouseOverLocation];
|
||||||
|
|
||||||
if (overColumn >= 0 && _CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation))
|
if (overColumn >= 0 && CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation))
|
||||||
{
|
{
|
||||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
|
var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
|
||||||
width = [tableColumn width];
|
width = [tableColumn width];
|
||||||
@@ -568,6 +365,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
[[CPCursor arrowCursor] set];
|
[[CPCursor arrowCursor] set];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewDidMoveToWindow
|
||||||
|
{
|
||||||
|
//if ([_tableView allowsColumnResizing])
|
||||||
|
// [[self window] setAcceptsMouseMovedEvents:YES];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)mouseEntered:(CPEvent)theEvent
|
- (void)mouseEntered:(CPEvent)theEvent
|
||||||
{
|
{
|
||||||
[self _updateResizeCursor:theEvent];
|
[self _updateResizeCursor:theEvent];
|
||||||
@@ -607,13 +410,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
if([headerView superview] != self)
|
if([headerView superview] != self)
|
||||||
[self addSubview:headerView];
|
[self addSubview:headerView];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)drawRect:(CGRect)aRect
|
- (void)drawRect:(CGRect)aRect
|
||||||
{
|
{
|
||||||
if (!_tableView || ![self drawsColumnLines])
|
if (!_tableView)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||||
@@ -625,7 +426,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1);
|
exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1);
|
||||||
|
|
||||||
CGContextSetLineWidth(context, 1);
|
CGContextSetLineWidth(context, 1);
|
||||||
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"divider-color"]);
|
CGContextSetStrokeColor(context, [_tableView gridColor]);
|
||||||
|
|
||||||
[exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:exposedRange];
|
[exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:exposedRange];
|
||||||
|
|
||||||
@@ -640,26 +441,40 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
var columnIndex = columnsArray[columnArrayIndex],
|
var columnIndex = columnsArray[columnArrayIndex],
|
||||||
columnToStroke = [self headerRectOfColumn:columnIndex];
|
columnToStroke = [self headerRectOfColumn:columnIndex];
|
||||||
|
|
||||||
columnMaxX = _CGRectGetMaxX(columnToStroke);
|
columnMaxX = CGRectGetMaxX(columnToStroke);
|
||||||
|
|
||||||
CGContextMoveToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(_CGRectGetMinY(columnToStroke)));
|
CGContextMoveToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMinY(columnToStroke)));
|
||||||
CGContextAddLineToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(_CGRectGetMaxY(columnToStroke)));
|
CGContextAddLineToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMaxY(columnToStroke)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CGContextClosePath(context);
|
CGContextClosePath(context);
|
||||||
CGContextStrokePath(context);
|
CGContextStrokePath(context);
|
||||||
|
|
||||||
/*if (_isDragging)
|
/*
|
||||||
|
var maxY = CGRectGetMaxY([self bounds]);
|
||||||
|
// draw normal gradient for remaining space
|
||||||
|
if (supportsCanvasGradient)
|
||||||
{
|
{
|
||||||
CGContextSetFillColor(context, [CPColor grayColor]);
|
aRect.origin.x = columnMaxX - 0.5;
|
||||||
CGContextFillRect(context, [self headerRectOfColumn:_activeColumn])
|
aRect.size.width -= columnMaxX;
|
||||||
}*/
|
CGContextBeginPath(context);
|
||||||
|
CGContextAddRect(context, CGRectMake(columnMaxX + 1, 0, CGRectGetMaxX([self bounds]) - columnMaxX, CGRectGetHeight([self bounds])));
|
||||||
|
CGContextClosePath(context);
|
||||||
|
CGContextDrawLinearGradient(context, [_CPTableColumnHeaderView headerGradient], CGPointMake(0,0), CGPointMake(0, maxY - 1),0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw bottom line
|
||||||
|
CGContextBeginPath(context);
|
||||||
|
CGContextMoveToPoint(context, 0, maxY - 0.5);
|
||||||
|
CGContextAddLineToPoint(context, CGRectGetMaxX([self bounds]), maxY - 0.5);
|
||||||
|
CGContextClosePath(context);
|
||||||
|
CGContextStrokePath(context);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
|
||||||
CPTableHeaderViewDrawsColumnLines = @"CPTableHeaderViewDrawsColumnLines";
|
|
||||||
|
|
||||||
@implementation CPTableHeaderView (CPCoding)
|
@implementation CPTableHeaderView (CPCoding)
|
||||||
|
|
||||||
@@ -669,7 +484,6 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
|||||||
{
|
{
|
||||||
[self _init];
|
[self _init];
|
||||||
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
|
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
|
||||||
_drawsColumnLines = [aCoder decodeBoolForKey:CPTableHeaderViewDrawsColumnLines];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -679,7 +493,7 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
|||||||
{
|
{
|
||||||
[super encodeWithCoder:aCoder];
|
[super encodeWithCoder:aCoder];
|
||||||
[aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
|
[aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
|
||||||
[aCoder encodeBool:_drawsColumnLines forKey:CPTableHeaderViewDrawsColumnLines];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
+408
-921
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
CPEnterCharacter = "\u0003";
|
|
||||||
CPBackspaceCharacter = "\u0008";
|
|
||||||
CPTabCharacter = "\u0009";
|
|
||||||
CPNewlineCharacter = "\u000a";
|
|
||||||
CPFormFeedCharacter = "\u000c";
|
|
||||||
CPCarriageReturnCharacter = "\u000d";
|
|
||||||
CPBackTabCharacter = "\u0019";
|
|
||||||
CPDeleteCharacter = "\u007f";
|
|
||||||
+56
-203
@@ -26,6 +26,9 @@
|
|||||||
@import "CPCompatibility.j"
|
@import "CPCompatibility.j"
|
||||||
@import "_CPImageAndTextView.j"
|
@import "_CPImageAndTextView.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
#include "Platform/DOM/CPDOMDisplayServer.h"
|
||||||
|
|
||||||
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
|
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
|
||||||
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
|
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
|
||||||
@@ -77,15 +80,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
BOOL _isEditable;
|
BOOL _isEditable;
|
||||||
BOOL _isSelectable;
|
BOOL _isSelectable;
|
||||||
BOOL _isSecure;
|
BOOL _isSecure;
|
||||||
BOOL _willBecomeFirstResponderByClick;
|
|
||||||
|
|
||||||
BOOL _drawsBackground;
|
BOOL _drawsBackground;
|
||||||
|
|
||||||
CPColor _textFieldBackgroundColor;
|
CPColor _textFieldBackgroundColor;
|
||||||
|
|
||||||
id _placeholderString;
|
id _placeholderString;
|
||||||
id _originalPlaceholderString;
|
|
||||||
BOOL _currentValueIsPlaceholder;
|
|
||||||
|
|
||||||
id _delegate;
|
id _delegate;
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
return textField;
|
return textField;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return "textfield";
|
return "textfield";
|
||||||
}
|
}
|
||||||
@@ -269,22 +269,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
#pragma mark Controlling Editability and Selectability
|
#pragma mark Controlling Editability and Selectability
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets whether or not the receiver text field can be edited. If NO, any
|
Sets whether or not the receiver text field can be edited
|
||||||
ongoing edit is ended.
|
|
||||||
*/
|
*/
|
||||||
- (void)setEditable:(BOOL)shouldBeEditable
|
- (void)setEditable:(BOOL)shouldBeEditable
|
||||||
{
|
{
|
||||||
if (_isEditable === shouldBeEditable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_isEditable = shouldBeEditable;
|
_isEditable = shouldBeEditable;
|
||||||
|
|
||||||
if (shouldBeEditable)
|
|
||||||
_isSelectable = YES;
|
|
||||||
|
|
||||||
// We only allow first responder status if the field is editable and enabled.
|
|
||||||
if (!shouldBeEditable && [[self window] firstResponder] === self)
|
|
||||||
[[self window] makeFirstResponder:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -295,19 +284,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
return _isEditable;
|
return _isEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets whether the field reacts to events. If NO, any ongoing edit is
|
|
||||||
ended.
|
|
||||||
*/
|
|
||||||
- (void)setEnabled:(BOOL)shouldBeEnabled
|
|
||||||
{
|
|
||||||
[super setEnabled:shouldBeEnabled];
|
|
||||||
|
|
||||||
// We only allow first responder status if the field is editable and enabled.
|
|
||||||
if (!shouldBeEnabled && [[self window] firstResponder] === self)
|
|
||||||
[[self window] makeFirstResponder:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets whether the field's text is selectable by the user.
|
Sets whether the field's text is selectable by the user.
|
||||||
@param aFlag \c YES makes the text selectable
|
@param aFlag \c YES makes the text selectable
|
||||||
@@ -507,13 +483,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
window.setTimeout(function()
|
window.setTimeout(function()
|
||||||
{
|
{
|
||||||
element.focus();
|
element.focus();
|
||||||
|
|
||||||
// Select the text if the textfield became first responder through keyboard interaction
|
|
||||||
if (!_willBecomeFirstResponderByClick)
|
|
||||||
[self selectText:self];
|
|
||||||
|
|
||||||
_willBecomeFirstResponderByClick = NO;
|
|
||||||
|
|
||||||
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
|
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
|
||||||
CPTextFieldInputOwner = self;
|
CPTextFieldInputOwner = self;
|
||||||
}, 0.0);
|
}, 0.0);
|
||||||
@@ -550,8 +519,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
|
|
||||||
var element = [self _inputElement];
|
var element = [self _inputElement];
|
||||||
|
|
||||||
if ([self stringValue] !== element.value)
|
[self setObjectValue:element.value];
|
||||||
[self _setStringValue:element.value];
|
|
||||||
|
|
||||||
CPTextFieldInputResigning = YES;
|
CPTextFieldInputResigning = YES;
|
||||||
element.blur();
|
element.blur();
|
||||||
@@ -569,11 +537,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
|
|
||||||
if (document.attachEvent)
|
if (document.attachEvent)
|
||||||
{
|
{
|
||||||
[[self window] platformWindow]._DOMBodyElement.ondrag = CPTextFieldCachedDragFunction;
|
|
||||||
[[self window] platformWindow]._DOMBodyElement.onselectstart = CPTextFieldCachedSelectStartFunction;
|
|
||||||
|
|
||||||
CPTextFieldCachedSelectStartFunction = nil;
|
CPTextFieldCachedSelectStartFunction = nil;
|
||||||
CPTextFieldCachedDragFunction = nil;
|
CPTextFieldCachedDragFunction = nil;
|
||||||
|
|
||||||
|
[[self window] platformWindow]._DOMBodyElement.ondrag = CPTextFieldCachedDragFunction;
|
||||||
|
[[self window] platformWindow]._DOMBodyElement.onselectstart = CPTextFieldCachedSelectStartFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -605,50 +573,21 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
{
|
{
|
||||||
// Don't track! (ever?)
|
// Don't track! (ever?)
|
||||||
if ([self isEditable] && [self isEnabled])
|
if ([self isEditable] && [self isEnabled])
|
||||||
{
|
return [[self window] makeFirstResponder:self];
|
||||||
_willBecomeFirstResponderByClick = YES;
|
|
||||||
[[self window] makeFirstResponder:self];
|
|
||||||
}
|
|
||||||
else if ([self isSelectable])
|
|
||||||
{
|
|
||||||
if (document.attachEvent)
|
|
||||||
{
|
|
||||||
CPTextFieldCachedSelectStartFunction = [[self window] platformWindow]._DOMBodyElement.onselectstart;
|
|
||||||
CPTextFieldCachedDragFunction = [[self window] platformWindow]._DOMBodyElement.ondrag;
|
|
||||||
|
|
||||||
[[self window] platformWindow]._DOMBodyElement.ondrag = function () {};
|
|
||||||
[[self window] platformWindow]._DOMBodyElement.onselectstart = function () {};
|
|
||||||
}
|
|
||||||
return [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return [[self nextResponder] mouseDown:anEvent];
|
return [[self nextResponder] mouseDown:anEvent];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseUp:(CPEvent)anEvent
|
- (void)mouseUp:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
if (![self isSelectable] && (![self isEditable] || ![self isEnabled]))
|
if (![self isEditable] || ![self isEnabled])
|
||||||
[[self nextResponder] mouseUp:anEvent];
|
[[self nextResponder] mouseUp:anEvent];
|
||||||
else if ([self isSelectable])
|
|
||||||
{
|
|
||||||
if (document.attachEvent)
|
|
||||||
{
|
|
||||||
[[self window] platformWindow]._DOMBodyElement.ondrag = CPTextFieldCachedDragFunction;
|
|
||||||
[[self window] platformWindow]._DOMBodyElement.onselectstart = CPTextFieldCachedSelectStartFunction;
|
|
||||||
|
|
||||||
CPTextFieldCachedSelectStartFunction = nil
|
|
||||||
CPTextFieldCachedDragFunction = nil;
|
|
||||||
}
|
|
||||||
return [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDragged:(CPEvent)anEvent
|
- (void)mouseDragged:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
if (![self isSelectable] && (![self isEditable] || ![self isEnabled]))
|
if (![self isEditable] || ![self isEnabled])
|
||||||
[[self nextResponder] mouseDragged:anEvent];
|
[[self nextResponder] mouseDragged:anEvent];
|
||||||
else if ([self isSelectable])
|
|
||||||
return [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyUp:(CPEvent)anEvent
|
- (void)keyUp:(CPEvent)anEvent
|
||||||
@@ -685,16 +624,29 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
|
|
||||||
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
|
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
|
||||||
}
|
}
|
||||||
|
else if ([anEvent keyCode] === CPTabKeyCode)
|
||||||
|
{
|
||||||
|
if ([anEvent modifierFlags] & CPShiftKeyMask)
|
||||||
|
[[self window] selectPreviousKeyView:self];
|
||||||
|
else
|
||||||
|
[[self window] selectNextKeyView:self];
|
||||||
|
|
||||||
|
if ([[[self window] firstResponder] respondsToSelector:@selector(selectText:)])
|
||||||
|
[[[self window] firstResponder] selectText:self];
|
||||||
|
|
||||||
|
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
|
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
|
||||||
|
|
||||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)textDidBlur:(CPNotification)note
|
- (void)textDidBlur:(CPNotification)note
|
||||||
{
|
{
|
||||||
// this looks to prevent false propagation of notifications for other objects
|
//this looks to prevent false propagation of notifications for other objects
|
||||||
if ([note object] != self)
|
if([note object] != self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter] postNotification:note];
|
[[CPNotificationCenter defaultCenter] postNotification:note];
|
||||||
@@ -702,22 +654,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
|
|
||||||
- (void)textDidFocus:(CPNotification)note
|
- (void)textDidFocus:(CPNotification)note
|
||||||
{
|
{
|
||||||
// this looks to prevent false propagation of notifications for other objects
|
//this looks to prevent false propagation of notifications for other objects
|
||||||
if ([note object] != self)
|
if([note object] != self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter] postNotification:note];
|
[[CPNotificationCenter defaultCenter] postNotification:note];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendAction:(SEL)anAction to:(id)anObject
|
|
||||||
{
|
|
||||||
// Don't reverse set our empty value
|
|
||||||
if (!_currentValueIsPlaceholder)
|
|
||||||
[self _reverseSetBinding];
|
|
||||||
|
|
||||||
[CPApp sendAction:anAction to:anObject from:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the string the text field.
|
Returns the string the text field.
|
||||||
*/
|
*/
|
||||||
@@ -764,7 +707,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
Sets a placeholder string for the receiver. The placeholder is displayed until editing begins,
|
Sets a placeholder string for the receiver. The placeholder is displayed until editing begins,
|
||||||
and after editing ends, if the text field has an empty string value
|
and after editing ends, if the text field has an empty string value
|
||||||
*/
|
*/
|
||||||
- (void)setPlaceholderString:(CPString)aStringValue
|
-(void)setPlaceholderString:(CPString)aStringValue
|
||||||
{
|
{
|
||||||
if (_placeholderString === aStringValue)
|
if (_placeholderString === aStringValue)
|
||||||
return;
|
return;
|
||||||
@@ -787,101 +730,43 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
return _placeholderString;
|
return _placeholderString;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_setCurrentValueIsPlaceholder:(BOOL)isPlaceholder
|
|
||||||
{
|
|
||||||
// The initial _currentValueIsPlaceholder is null so convert it to NO for comparison purposes.
|
|
||||||
if (!!_currentValueIsPlaceholder === isPlaceholder)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (isPlaceholder)
|
|
||||||
{
|
|
||||||
// Save the original placeholder value so we can restore it later
|
|
||||||
// Only do this if the placeholder is not already overridden because the bindings logic might call this method
|
|
||||||
// several times and we don't want the bindings placeholder to ever become the original placeholder
|
|
||||||
if (!_currentValueIsPlaceholder)
|
|
||||||
_originalPlaceholderString = [self placeholderString];
|
|
||||||
|
|
||||||
// Set the current string value as the current placeholder and clear the string value
|
|
||||||
[self setPlaceholderString:[self stringValue]];
|
|
||||||
[self setStringValue:@""];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Restore the original placeholder, the actual textfield value is already correct
|
|
||||||
// because it was set using setValue:forKey:
|
|
||||||
[self setPlaceholderString:_originalPlaceholderString];
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentValueIsPlaceholder = isPlaceholder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
For non-bezeled text fields (typically a label), sizeToFit has two behaviors, depending
|
Size to fit has two behavior, depending on if the receiver is an editable text field or not.
|
||||||
on the line break mode of the receiver.
|
|
||||||
|
|
||||||
For non-bezeled receivers with a non-wrapping line break mode, sizeToFit will change the frame of the
|
For non-editable text fields (typically, a label), sizeToFit will change the frame of the
|
||||||
receiver to perfectly fit the current text in stringValue in the current font, respecting
|
receiver to perfectly fit the current text in stringValue in the current font, and respecting
|
||||||
the current theme value for content-inset. For receivers with a wrapping line break mode,
|
the current theme values for content-inset, min-size, and max-size.
|
||||||
sizeToFit will wrap the text within the current width (respecting the current content-inset),
|
|
||||||
so it will ONLY change the HEIGHT.
|
|
||||||
|
|
||||||
For bezeled text fields (typically editable fields), sizeToFit will ONLY change the HEIGHT
|
For editable text fields, sizeToFit will ONLY change the HEIGHT of the text field. It will not
|
||||||
of the text field. It will not change the width of the text field. sizeToFit will attempt to
|
change the width of the text field. You can use setFrameSize: with the current height to set the
|
||||||
change the height to fit a single line of text, respecting the current theme values for min-size,
|
width, and you can get the size of a string with [CPString sizeWithFont:].
|
||||||
max-size and content-inset.
|
|
||||||
|
|
||||||
The logic behind this decision is that most of the time you do not know what content will be placed
|
The logic behind this decision is that most of the time you do not know what content will be placed
|
||||||
in a bezeled text field, so you want to just choose a fixed width and leave it at that size.
|
in an editable text field, so you want to just choose a fixed width and leave it at that size.
|
||||||
However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
|
However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
|
||||||
useful for making the textfield an appropriate height.
|
useful for making the textfield an appropriate height.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
- (void)sizeToFit
|
- (void)sizeToFit
|
||||||
{
|
{
|
||||||
[self setFrameSize:[self _minimumFrameSize]];
|
var size = [([self stringValue] || " ") sizeWithFont:[self currentValueForThemeAttribute:@"font"]],
|
||||||
}
|
|
||||||
|
|
||||||
- (CGSize)_minimumFrameSize
|
|
||||||
{
|
|
||||||
var frameSize = [self frameSize],
|
|
||||||
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
minSize = [self currentValueForThemeAttribute:@"min-size"],
|
minSize = [self currentValueForThemeAttribute:@"min-size"],
|
||||||
maxSize = [self currentValueForThemeAttribute:@"max-size"],
|
maxSize = [self currentValueForThemeAttribute:@"max-size"];
|
||||||
lineBreakMode = [self lineBreakMode],
|
|
||||||
text = ([self stringValue] || @" "),
|
|
||||||
textSize = _CGSizeMakeCopy(frameSize),
|
|
||||||
font = [self currentValueForThemeAttribute:@"font"];
|
|
||||||
|
|
||||||
textSize.width -= contentInset.left + contentInset.right;
|
size.width = MAX(size.width + contentInset.left + contentInset.right, minSize.width);
|
||||||
textSize.height -= contentInset.top + contentInset.bottom;
|
size.height = MAX(size.height + contentInset.top + contentInset.bottom, minSize.height);
|
||||||
|
|
||||||
if (frameSize.width !== 0 &&
|
if (maxSize.width >= 0.0)
|
||||||
![self isBezeled] &&
|
size.width = MIN(size.width, maxSize.width);
|
||||||
(lineBreakMode === CPLineBreakByWordWrapping || lineBreakMode === CPLineBreakByCharWrapping))
|
|
||||||
{
|
|
||||||
textSize = [text sizeWithFont:font inWidth:textSize.width];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
textSize = [text sizeWithFont:font];
|
|
||||||
|
|
||||||
frameSize.height = textSize.height + contentInset.top + contentInset.bottom;
|
if (maxSize.height >= 0.0)
|
||||||
|
size.height = MIN(size.height, maxSize.height);
|
||||||
|
|
||||||
if ([self isBezeled])
|
if ([self isEditable])
|
||||||
{
|
size.width = CGRectGetWidth([self frame]);
|
||||||
frameSize.height = MAX(frameSize.height, minSize.height);
|
|
||||||
|
|
||||||
if (maxSize.width > 0.0)
|
[self setFrameSize:size];
|
||||||
frameSize.width = MIN(frameSize.width, maxSize.width);
|
|
||||||
|
|
||||||
if (maxSize.height > 0.0)
|
|
||||||
frameSize.height = MIN(frameSize.height, maxSize.height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
frameSize.width = textSize.width + contentInset.left + contentInset.right;
|
|
||||||
|
|
||||||
frameSize.width = MAX(frameSize.width, minSize.width);
|
|
||||||
|
|
||||||
return frameSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -896,8 +781,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
{
|
{
|
||||||
if ([[self window] firstResponder] === self)
|
if ([[self window] firstResponder] === self)
|
||||||
window.setTimeout(function() { element.select(); }, 0);
|
window.setTimeout(function() { element.select(); }, 0);
|
||||||
else if ([self window] !== nil && [[self window] makeFirstResponder:self])
|
else
|
||||||
|
{
|
||||||
|
[[self window] makeFirstResponder:self];
|
||||||
window.setTimeout(function() {[self selectText:sender];}, 0);
|
window.setTimeout(function() {[self selectText:sender];}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -946,7 +834,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
|
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
|
||||||
|
|
||||||
[self setStringValue:newValue];
|
[self setStringValue:newValue];
|
||||||
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
|
[self setSelectedRange:CPMakeRange(selectedRange.location+pasteString.length, 0)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,7 +997,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)bezelRectForBounds:(CGRect)bounds
|
- (CGRect)bezelRectForBounds:(CFRect)bounds
|
||||||
{
|
{
|
||||||
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
|
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
|
||||||
|
|
||||||
@@ -1199,22 +1087,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
|
|
||||||
{
|
|
||||||
var count = objects.length,
|
|
||||||
value = [objects[0] valueForKeyPath:aKeyPath];
|
|
||||||
|
|
||||||
[self setStringValue:value];
|
|
||||||
[self setPlaceholderString:@""];
|
|
||||||
|
|
||||||
while (count-- > 1)
|
|
||||||
if (value !== [objects[count] valueForKeyPath:aKeyPath])
|
|
||||||
{
|
|
||||||
[self setPlaceholderString:@"Multiple Values"];
|
|
||||||
[self setStringValue:@""];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var secureStringForString = function(aString)
|
var secureStringForString = function(aString)
|
||||||
@@ -1223,7 +1095,7 @@ var secureStringForString = function(aString)
|
|||||||
if (!aString)
|
if (!aString)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return Array(aString.length + 1).join(CPSecureTextFieldCharacter);
|
return Array(aString.length+1).join(CPSecureTextFieldCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1234,7 +1106,6 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
|||||||
CPTextFieldBezelStyleKey = "CPTextFieldBezelStyleKey",
|
CPTextFieldBezelStyleKey = "CPTextFieldBezelStyleKey",
|
||||||
CPTextFieldDrawsBackgroundKey = "CPTextFieldDrawsBackgroundKey",
|
CPTextFieldDrawsBackgroundKey = "CPTextFieldDrawsBackgroundKey",
|
||||||
CPTextFieldLineBreakModeKey = "CPTextFieldLineBreakModeKey",
|
CPTextFieldLineBreakModeKey = "CPTextFieldLineBreakModeKey",
|
||||||
CPTextFieldAlignmentKey = "CPTextFieldAlignmentKey",
|
|
||||||
CPTextFieldBackgroundColorKey = "CPTextFieldBackgroundColorKey",
|
CPTextFieldBackgroundColorKey = "CPTextFieldBackgroundColorKey",
|
||||||
CPTextFieldPlaceholderStringKey = "CPTextFieldPlaceholderStringKey";
|
CPTextFieldPlaceholderStringKey = "CPTextFieldPlaceholderStringKey";
|
||||||
|
|
||||||
@@ -1258,22 +1129,7 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
|||||||
|
|
||||||
[self setTextFieldBackgroundColor:[aCoder decodeObjectForKey:CPTextFieldBackgroundColorKey]];
|
[self setTextFieldBackgroundColor:[aCoder decodeObjectForKey:CPTextFieldBackgroundColorKey]];
|
||||||
|
|
||||||
[self setLineBreakMode:[aCoder decodeIntForKey:CPTextFieldLineBreakModeKey]];
|
|
||||||
[self setAlignment:[aCoder decodeIntForKey:CPTextFieldAlignmentKey]];
|
|
||||||
|
|
||||||
[self setPlaceholderString:[aCoder decodeObjectForKey:CPTextFieldPlaceholderStringKey]];
|
[self setPlaceholderString:[aCoder decodeObjectForKey:CPTextFieldPlaceholderStringKey]];
|
||||||
|
|
||||||
// Make sure the frame is big enough
|
|
||||||
var minSize = [self _minimumFrameSize];
|
|
||||||
minSize.width = MAX(CGRectGetWidth([self frame]), minSize.width);
|
|
||||||
minSize.height = MAX(CGRectGetHeight([self frame]), minSize.height);
|
|
||||||
|
|
||||||
// Only size multiline bezeled textfields if it's to small to fit the content
|
|
||||||
if ([self isBezeled])
|
|
||||||
if ([self lineBreakMode] === CPLineBreakByCharWrapping || [self lineBreakMode] == CPLineBreakByWordWrapping)
|
|
||||||
minSize.height = MAX(CGRectGetHeight([self frame]), minSize.height);
|
|
||||||
|
|
||||||
[self setFrameSize:minSize];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -1294,9 +1150,6 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
|||||||
|
|
||||||
[aCoder encodeObject:_textFieldBackgroundColor forKey:CPTextFieldBackgroundColorKey];
|
[aCoder encodeObject:_textFieldBackgroundColor forKey:CPTextFieldBackgroundColorKey];
|
||||||
|
|
||||||
[aCoder encodeInt:[self lineBreakMode] forKey:CPTextFieldLineBreakModeKey];
|
|
||||||
[aCoder encodeInt:[self alignment] forKey:CPTextFieldAlignmentKey];
|
|
||||||
|
|
||||||
[aCoder encodeObject:_placeholderString forKey:CPTextFieldPlaceholderStringKey];
|
[aCoder encodeObject:_placeholderString forKey:CPTextFieldPlaceholderStringKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-178
@@ -24,10 +24,8 @@
|
|||||||
@import <Foundation/CPString.j>
|
@import <Foundation/CPString.j>
|
||||||
@import <Foundation/CPKeyedUnarchiver.j>
|
@import <Foundation/CPKeyedUnarchiver.j>
|
||||||
|
|
||||||
|
var CPThemesByName = { },
|
||||||
var CPThemesByName = { },
|
CPThemeDefaultTheme = nil;
|
||||||
CPThemeDefaultTheme = nil,
|
|
||||||
CPThemeDefaultHudTheme = nil;
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -50,27 +48,6 @@ var CPThemesByName = { },
|
|||||||
return CPThemeDefaultTheme;
|
return CPThemeDefaultTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Set the default HUD theme. If set to nil, the default described in defaultHudTheme
|
|
||||||
will be used.
|
|
||||||
*/
|
|
||||||
+ (void)setDefaultHudTheme:(CPTheme)aTheme
|
|
||||||
{
|
|
||||||
CPThemeDefaultHudTheme = aTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
The default HUD theme is (sometimes) used for windows with the CPHUDBackgroundWindowMask
|
|
||||||
style mask. The default is theme with the name of the default theme with -HUD appended
|
|
||||||
at the end.
|
|
||||||
*/
|
|
||||||
+ (CPTheme)defaultHudTheme
|
|
||||||
{
|
|
||||||
if (!CPThemeDefaultHudTheme)
|
|
||||||
CPThemeDefaultHudTheme = [CPTheme themeNamed:[[self defaultTheme] name] + "-HUD"];
|
|
||||||
return CPThemeDefaultHudTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPTheme)themeNamed:(CPString)aName
|
+ (CPTheme)themeNamed:(CPString)aName
|
||||||
{
|
{
|
||||||
return CPThemesByName[aName];
|
return CPThemesByName[aName];
|
||||||
@@ -96,110 +73,9 @@ var CPThemesByName = { },
|
|||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
- (_CPThemeAttribute)_attributeWithName:(CPString)aName forClass:(CPString)aClass
|
||||||
Returns an array of names of themed classes defined in this theme, as found in its
|
|
||||||
ThemeDescriptors.j file.
|
|
||||||
|
|
||||||
NOTE: The names are not class names (such as "CPButton"), but the names returned
|
|
||||||
by the class' +defaultThemeClass method. For example, the name for CPCheckBox is "check-box",
|
|
||||||
as defined in CPCheckBox::themeClass.
|
|
||||||
*/
|
|
||||||
- (CPArray)classNames
|
|
||||||
{
|
{
|
||||||
return [_attributes allKeys];
|
var attributes = [_attributes objectForKey:aClass];
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a dictionary of all theme attributes defined for the given class, as found in the
|
|
||||||
theme's ThemeDescriptors.j file. The keys of the dictionary are attribute names, and the values
|
|
||||||
are instances of _CPThemeAttribute.
|
|
||||||
|
|
||||||
For a description of valid values for \c aClass, see \ref attributeNamesForClass:.
|
|
||||||
|
|
||||||
@param aClass The themed class whose attributes you want to retrieve
|
|
||||||
@return A dictionary of attributes or nil
|
|
||||||
*/
|
|
||||||
- (CPDictionary)attributesForClass:(id)aClass
|
|
||||||
{
|
|
||||||
if (!aClass)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
var className = nil;
|
|
||||||
|
|
||||||
if ([aClass isKindOfClass:[CPString class]])
|
|
||||||
{
|
|
||||||
// See if it is a class name
|
|
||||||
var theClass = CPClassFromString(aClass);
|
|
||||||
|
|
||||||
if (theClass)
|
|
||||||
aClass = theClass;
|
|
||||||
else
|
|
||||||
className = aClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!className)
|
|
||||||
{
|
|
||||||
if ([aClass isKindOfClass:[CPView class]])
|
|
||||||
{
|
|
||||||
if ([aClass respondsToSelector:@selector(defaultThemeClass)])
|
|
||||||
className = [aClass defaultThemeClass];
|
|
||||||
else if ([aClass respondsToSelector:@selector(themeClass)])
|
|
||||||
{
|
|
||||||
CPLog.warn(@"%@ themeClass is deprecated in favor of defaultThemeClass",CPStringFromClass([anObject class]));
|
|
||||||
className = [aClass themeClass];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
[CPException raise:CPInvalidArgumentException reason:@"aClass must be a class object or a string."];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [_attributes objectForKey:className];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns an array of names of all theme attributes defined for the given class, as found in the
|
|
||||||
theme's ThemeDescriptors.j file.
|
|
||||||
|
|
||||||
The \c aClass parameter can be one of the following:
|
|
||||||
|
|
||||||
- A class instance, for example the result of [CPCheckBox class]. The class must be a subclass
|
|
||||||
of CPView.
|
|
||||||
- A class name, for example "CPCheckBox".
|
|
||||||
- A themed class name, for example "check-box".
|
|
||||||
|
|
||||||
If \c aClass does not refer to a themed class in this theme, nil is returned.
|
|
||||||
|
|
||||||
@param aClass The themed class whose attributes you want to retrieve
|
|
||||||
@return An array of attribute names or nil
|
|
||||||
*/
|
|
||||||
- (CPDictionary)attributeNamesForClass:(id)aClass
|
|
||||||
{
|
|
||||||
var attributes = [self attributesForClass:aClass];
|
|
||||||
|
|
||||||
if (attributes)
|
|
||||||
return [attributes allKeys];
|
|
||||||
else
|
|
||||||
return [CPArray array];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns a theme attribute defined for the given class, as found in the
|
|
||||||
theme's ThemeDescriptors.j file.
|
|
||||||
|
|
||||||
\c aName should be the attribute name as you would pass to the method
|
|
||||||
CPView::valueForThemeAttribute:.
|
|
||||||
|
|
||||||
For a description of valid values for \c aClass, see \ref attributeNamesForClass:.
|
|
||||||
|
|
||||||
@param aName The name of the attribute you want to retrieve
|
|
||||||
@param aClass The themed class in which to look for the attribute
|
|
||||||
@return An instance of _CPThemeAttribute or nil
|
|
||||||
*/
|
|
||||||
- (_CPThemeAttribute)attributeWithName:(CPString)aName forClass:(id)aClass
|
|
||||||
{
|
|
||||||
var attributes = [self attributesForClass:aClass];
|
|
||||||
|
|
||||||
if (!attributes)
|
if (!attributes)
|
||||||
return nil;
|
return nil;
|
||||||
@@ -207,53 +83,12 @@ var CPThemesByName = { },
|
|||||||
return [attributes objectForKey:aName];
|
return [attributes objectForKey:aName];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the value for a theme attribute in its normal state, as defined for the given class
|
|
||||||
in the theme's ThemeDescriptors.j file.
|
|
||||||
|
|
||||||
\c aName should be the attribute name as you would pass to the method
|
|
||||||
CPView::valueForThemeAttribute:.
|
|
||||||
|
|
||||||
For a description of valid values for \c aClass, see \ref attributeNamesForClass:.
|
|
||||||
|
|
||||||
@param aName The name of the attribute whose value you want to retrieve
|
|
||||||
@param aClass The themed class in which to look for the attribute
|
|
||||||
@return A value or nil
|
|
||||||
*/
|
|
||||||
- (id)valueForAttributeWithName:(CPString)aName forClass:(id)aClass
|
|
||||||
{
|
|
||||||
return [self valueForAttributeWithName:aName inState:CPThemeStateNormal forClass:aClass];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the value for a theme attribute in a given state, as defined for the given class
|
|
||||||
in the theme's ThemeDescriptors.j file. This is the equivalent of the method
|
|
||||||
CPView::valueForThemeAttribute:inState:, but retrieves the value from the theme definition as
|
|
||||||
opposed to a single view's current theme state.
|
|
||||||
|
|
||||||
For a description of valid values for \c aClass, see \ref attributeNamesForClass:.
|
|
||||||
|
|
||||||
@param aName The name of the attribute whose value you want to retrieve
|
|
||||||
@param aState The state qualifier for the attribute
|
|
||||||
@param aClass The themed class in which to look for the attribute
|
|
||||||
@return A value or nil
|
|
||||||
*/
|
|
||||||
- (id)valueForAttributeWithName:(CPString)aName inState:(CPThemeState)aState forClass:(id)aClass
|
|
||||||
{
|
|
||||||
var attribute = [self attributeWithName:aName forClass:aClass];
|
|
||||||
|
|
||||||
if (!attribute)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
return [attribute valueForState:aState];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)takeThemeFromObject:(id)anObject
|
- (void)takeThemeFromObject:(id)anObject
|
||||||
{
|
{
|
||||||
var attributes = [anObject _themeAttributeDictionary],
|
var attributes = [anObject _themeAttributeDictionary],
|
||||||
attributeName = nil,
|
attributeName = nil,
|
||||||
attributeNames = [attributes keyEnumerator],
|
attributeNames = [attributes keyEnumerator],
|
||||||
objectThemeClass = [anObject themeClass];
|
objectThemeClass = [[anObject class] themeClass];
|
||||||
|
|
||||||
while (attributeName = [attributeNames nextObject])
|
while (attributeName = [attributeNames nextObject])
|
||||||
[self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass];
|
[self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass];
|
||||||
@@ -407,9 +242,6 @@ CPThemeStateNormal = CPThemeStates["normal"] = 0;
|
|||||||
CPThemeStateDisabled = CPThemeState("disabled");
|
CPThemeStateDisabled = CPThemeState("disabled");
|
||||||
CPThemeStateHighlighted = CPThemeState("highlighted");
|
CPThemeStateHighlighted = CPThemeState("highlighted");
|
||||||
CPThemeStateSelected = CPThemeState("selected");
|
CPThemeStateSelected = CPThemeState("selected");
|
||||||
CPThemeStateTableDataView = CPThemeState("tableDataView");
|
|
||||||
CPThemeStateSelectedDataView = CPThemeStateSelectedTableDataView = CPThemeState("selectedTableDataView");
|
|
||||||
CPThemeStateGroupRow = CPThemeState("CPThemeStateGroupRow");
|
|
||||||
CPThemeStateBezeled = CPThemeState("bezeled");
|
CPThemeStateBezeled = CPThemeState("bezeled");
|
||||||
CPThemeStateBordered = CPThemeState("bordered");
|
CPThemeStateBordered = CPThemeState("bordered");
|
||||||
CPThemeStateEditable = CPThemeState("editable");
|
CPThemeStateEditable = CPThemeState("editable");
|
||||||
@@ -422,10 +254,10 @@ CPThemeStateCircular = CPThemeState("circular");
|
|||||||
{
|
{
|
||||||
CPString _name;
|
CPString _name;
|
||||||
id _defaultValue;
|
id _defaultValue;
|
||||||
CPDictionary _values @accessors(readonly, getter=values);
|
CPDictionary _values;
|
||||||
|
|
||||||
JSObject _cache;
|
JSObject _cache;
|
||||||
_CPThemeAttribute _parentAttribute;
|
CPThemeAttribute _parentAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue
|
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue
|
||||||
@@ -546,7 +378,7 @@ CPThemeStateCircular = CPThemeState("circular");
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setParentAttribute:(_CPThemeAttribute)anAttribute
|
- (void)setParentAttribute:(CPThemeAttribute)anAttribute
|
||||||
{
|
{
|
||||||
if (_parentAttribute === anAttribute)
|
if (_parentAttribute === anAttribute)
|
||||||
return;
|
return;
|
||||||
@@ -555,7 +387,7 @@ CPThemeStateCircular = CPThemeState("circular");
|
|||||||
_parentAttribute = anAttribute;
|
_parentAttribute = anAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (_CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute
|
- (CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute
|
||||||
{
|
{
|
||||||
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue];
|
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue];
|
||||||
|
|
||||||
@@ -719,7 +551,7 @@ function CPThemeAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (aTheme && aClass)
|
if (aTheme && aClass)
|
||||||
[attribute setParentAttribute:[aTheme attributeWithName:anAttributeName forClass:aClass]];
|
[attribute setParentAttribute:[aTheme _attributeWithName:anAttributeName forClass:aClass]];
|
||||||
|
|
||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-31
@@ -22,10 +22,9 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
@import "CPTheme.j"
|
@import <AppKit/CPTheme.j>
|
||||||
@import "_CPCibCustomResource.j"
|
@import <AppKit/_CPCibCustomResource.j>
|
||||||
@import "_CPCibKeyedUnarchiver.j"
|
@import <AppKit/_CPCibKeyedUnarchiver.j>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -34,7 +33,7 @@
|
|||||||
@implementation CPThemeBlend : CPObject
|
@implementation CPThemeBlend : CPObject
|
||||||
{
|
{
|
||||||
CPBundle _bundle;
|
CPBundle _bundle;
|
||||||
CPArray _themes;
|
CPArray _themes @accessors(readonly, getter=themes);
|
||||||
id _loadDelegate;
|
id _loadDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,28 +49,6 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns an array of names of the keyed theme archives that make up this blend.
|
|
||||||
Each item in the array will have the extension ".keyedtheme".
|
|
||||||
*/
|
|
||||||
- (CPArray)themes
|
|
||||||
{
|
|
||||||
return _themes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns an array of names of the themes that make up this blend.
|
|
||||||
*/
|
|
||||||
- (CPArray)themeNames
|
|
||||||
{
|
|
||||||
var names = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < _themes.length; ++i)
|
|
||||||
names.push(_themes[i].substring(0, _themes[i].indexOf(".keyedtheme")));
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)loadWithDelegate:(id)aDelegate
|
- (void)loadWithDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
_loadDelegate = aDelegate;
|
_loadDelegate = aDelegate;
|
||||||
@@ -81,13 +58,12 @@
|
|||||||
|
|
||||||
- (void)bundleDidFinishLoading:(CPBundle)aBundle
|
- (void)bundleDidFinishLoading:(CPBundle)aBundle
|
||||||
{
|
{
|
||||||
_themes = [_bundle objectForInfoDictionaryKey:@"CPKeyedThemes"];
|
var themes = [_bundle objectForInfoDictionaryKey:@"CPKeyedThemes"],
|
||||||
|
count = themes.length;
|
||||||
var count = _themes.length;
|
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
var path = [aBundle pathForResource:_themes[count]],
|
var path = [aBundle pathForResource:themes[count]],
|
||||||
unarchiver = [[_CPThemeKeyedUnarchiver alloc]
|
unarchiver = [[_CPThemeKeyedUnarchiver alloc]
|
||||||
initForReadingWithData:[[CPURL URLWithString:path] staticResourceData]
|
initForReadingWithData:[[CPURL URLWithString:path] staticResourceData]
|
||||||
bundle:_bundle];
|
bundle:_bundle];
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+10
-21
@@ -28,6 +28,8 @@
|
|||||||
@import "CPPopUpButton.j"
|
@import "CPPopUpButton.j"
|
||||||
@import "CPToolbarItem.j"
|
@import "CPToolbarItem.j"
|
||||||
|
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@global
|
@global
|
||||||
@@ -327,11 +329,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
|
|||||||
return _itemsSortedByVisibilityPriority;
|
return _itemsSortedByVisibilityPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
- (void)validateVisibleToolbarItems
|
||||||
Validates the visible toolbar items by sending a validate message to
|
|
||||||
each visible toolbar item.
|
|
||||||
*/
|
|
||||||
- (void)validateVisibleItems
|
|
||||||
{
|
{
|
||||||
var toolbarItems = [self visibleItems],
|
var toolbarItems = [self visibleItems],
|
||||||
count = [toolbarItems count];
|
count = [toolbarItems count];
|
||||||
@@ -468,14 +466,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
|
|||||||
// specified, it will be read later and the resulting call to -setDelegate:
|
// specified, it will be read later and the resulting call to -setDelegate:
|
||||||
// will cause -_reloadToolbarItems] to run again :-(
|
// will cause -_reloadToolbarItems] to run again :-(
|
||||||
// FIXME: Can we make this better?
|
// FIXME: Can we make this better?
|
||||||
|
[self _reloadToolbarItems];
|
||||||
// Do this at the end of the run loop to allow all the cib-stuff to
|
|
||||||
// finish (establishing connections, etc.).
|
|
||||||
[[CPRunLoop currentRunLoop]
|
|
||||||
performSelector:@selector(_reloadToolbarItems)
|
|
||||||
target:self
|
|
||||||
argument:nil
|
|
||||||
order:0 modes:[CPDefaultRunLoopMode]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -568,7 +559,6 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
|
|||||||
|
|
||||||
[_additionalItemsButton setImagePosition:CPImageOnly];
|
[_additionalItemsButton setImagePosition:CPImageOnly];
|
||||||
[[_additionalItemsButton menu] setShowsStateColumn:NO];
|
[[_additionalItemsButton menu] setShowsStateColumn:NO];
|
||||||
[[_additionalItemsButton menu] setAutoenablesItems:NO];
|
|
||||||
|
|
||||||
[_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
|
[_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
|
||||||
}
|
}
|
||||||
@@ -799,13 +789,14 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
|
|||||||
|
|
||||||
hasNonSeparatorItem = YES;
|
hasNonSeparatorItem = YES;
|
||||||
|
|
||||||
var menuItem = [[CPMenuItem alloc] initWithTitle:[item label] action:[item action] keyEquivalent:nil];
|
[_additionalItemsButton addItemWithTitle:[item label]];
|
||||||
|
|
||||||
|
var menuItem = [_additionalItemsButton itemArray][index + 1];
|
||||||
|
|
||||||
[menuItem setImage:[item image]];
|
[menuItem setImage:[item image]];
|
||||||
[menuItem setTarget:[item target]];
|
|
||||||
[menuItem setEnabled:[item isEnabled]];
|
|
||||||
|
|
||||||
[_additionalItemsButton addItem:menuItem];
|
[menuItem setTarget:[item target]];
|
||||||
|
[menuItem setAction:[item action]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -979,7 +970,7 @@ var TOP_MARGIN = 5.0,
|
|||||||
{
|
{
|
||||||
_imageView = [[CPImageView alloc] initWithFrame:[self bounds]];
|
_imageView = [[CPImageView alloc] initWithFrame:[self bounds]];
|
||||||
|
|
||||||
[_imageView setImageScaling:CPScaleProportionally];
|
[_imageView setImageScaling:CPScaleNone];
|
||||||
|
|
||||||
[self addSubview:_imageView];
|
[self addSubview:_imageView];
|
||||||
}
|
}
|
||||||
@@ -1060,8 +1051,6 @@ var TOP_MARGIN = 5.0,
|
|||||||
[_imageView setAlphaValue:0.5];
|
[_imageView setAlphaValue:0.5];
|
||||||
[_labelField setAlphaValue:0.5];
|
[_labelField setAlphaValue:0.5];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_toolbar tile];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPColor)FIXME_labelColor
|
- (CPColor)FIXME_labelColor
|
||||||
|
|||||||
@@ -23,9 +23,8 @@
|
|||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
@import <Foundation/CPString.j>
|
@import <Foundation/CPString.j>
|
||||||
|
|
||||||
@import "CPImage.j"
|
@import <AppKit/CPImage.j>
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
|
|
||||||
|
|
||||||
CPToolbarItemVisibilityPriorityStandard = 0;
|
CPToolbarItemVisibilityPriorityStandard = 0;
|
||||||
CPToolbarItemVisibilityPriorityLow = -1000;
|
CPToolbarItemVisibilityPriorityLow = -1000;
|
||||||
@@ -450,9 +449,6 @@ CPToolbarItemVisibilityPriorityUser
|
|||||||
|
|
||||||
- (void)validate
|
- (void)validate
|
||||||
{
|
{
|
||||||
var action = [self action],
|
|
||||||
target = [self target];
|
|
||||||
|
|
||||||
// View items do not do any target-action analysis.
|
// View items do not do any target-action analysis.
|
||||||
if (_view)
|
if (_view)
|
||||||
{
|
{
|
||||||
@@ -462,9 +458,13 @@ CPToolbarItemVisibilityPriorityUser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var action = [self action];
|
||||||
|
|
||||||
if (!action)
|
if (!action)
|
||||||
return [self setEnabled:NO];
|
return [self setEnabled:NO];
|
||||||
|
|
||||||
|
var target = [self target];
|
||||||
|
|
||||||
if (target && ![target respondsToSelector:action])
|
if (target && ![target respondsToSelector:action])
|
||||||
return [self setEnabled:NO];
|
return [self setEnabled:NO];
|
||||||
|
|
||||||
|
|||||||
@@ -87,40 +87,6 @@
|
|||||||
[_childNodes[count] sortWithSortDescriptors:sortDescriptors recursively:YES];
|
[_childNodes[count] sortWithSortDescriptors:sortDescriptors recursively:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPEnumerator)preOrder
|
|
||||||
{
|
|
||||||
return [_CPTreeNodeEnumerator enumeratorWithTreeNode:self order:_CPTreeNodeEnumeratorPreOrder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPEnumerator)inOrder
|
|
||||||
{
|
|
||||||
return [_CPTreeNodeEnumerator enumeratorWithTreeNode:self order:_CPTreeNodeEnumeratorInOrder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPEnumerator)postOrder
|
|
||||||
{
|
|
||||||
return [_CPTreeNodeEnumerator enumeratorWithTreeNode:self order:_CPTreeNodeEnumeratorPostOrder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPEnumerator)levelOrder
|
|
||||||
{
|
|
||||||
return [_CPTreeNodeEnumerator enumeratorWithTreeNode:self order:_CPTreeNodeEnumeratorLevelOrder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int)countByEnumeratingWithState:(id)aState objects:(id)objects count:(id)aCount
|
|
||||||
{
|
|
||||||
if (aState.state !== 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// FIXME: Change this to inorder when implemented?
|
|
||||||
var count = [[self preOrder] countByEnumeratingWithState:aState objects:objects count:aCount];
|
|
||||||
|
|
||||||
// Dangerous?
|
|
||||||
aState.state = YES;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
||||||
@@ -151,166 +117,3 @@ var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var _CPTreeNodeEnumeratorPreOrder = 0,
|
|
||||||
_CPTreeNodeEnumeratorInOrder = 1,
|
|
||||||
_CPTreeNodeEnumeratorPostOrder = 2,
|
|
||||||
_CPTreeNodeEnumeratorLevelOrder = 3;
|
|
||||||
|
|
||||||
@implementation _CPTreeNodeEnumerator : CPEnumerator
|
|
||||||
{
|
|
||||||
int _order;
|
|
||||||
Object _state;
|
|
||||||
CPTreeNode _treeNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (_CPTreeNodeEnumerator)enumeratorWithTreeNode:(CPTreeNode)aTreeNode order:(int)anOrder
|
|
||||||
{
|
|
||||||
return [[self alloc] initWithTreeNode:aTreeNode order:anOrder];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithTreeNode:(CPTreeNode)aTreeNode order:(int)anOrder
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
_order = anOrder
|
|
||||||
_state = [self _newState];
|
|
||||||
_treeNode = aTreeNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_newState
|
|
||||||
{
|
|
||||||
return { stack:[_treeNode], visited:[CPSet set] };
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_preOrderFromState:(Object)state allObjects:(BOOL)shouldReturnAllObjects
|
|
||||||
{
|
|
||||||
var stack = state.stack;
|
|
||||||
|
|
||||||
if (stack.length <= 0)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
if (shouldReturnAllObjects)
|
|
||||||
var allObjects = [];
|
|
||||||
|
|
||||||
while (stack.length)
|
|
||||||
{
|
|
||||||
var currentNode = stack.pop(),
|
|
||||||
childNodes = currentNode._childNodes,
|
|
||||||
count = childNodes.length;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
stack.push(childNodes[count]);
|
|
||||||
|
|
||||||
if (shouldReturnAllObjects)
|
|
||||||
allObjects.push(currentNode);
|
|
||||||
else
|
|
||||||
return currentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return allObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_inOrderFromState:(Object)state allObjects:(BOOL)shouldReturnAllObjects
|
|
||||||
{
|
|
||||||
// Implement.
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_postOrderFromState:(Object)state allObjects:(BOOL)shouldReturnAllObjects
|
|
||||||
{
|
|
||||||
var stack = state.stack;
|
|
||||||
|
|
||||||
if (stack.length <= 0)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
var visited = state.visited;
|
|
||||||
|
|
||||||
if (shouldReturnAllObjects)
|
|
||||||
var allObjects = [];
|
|
||||||
|
|
||||||
while (stack.length)
|
|
||||||
{
|
|
||||||
var currentNode = [stack lastObject],
|
|
||||||
childNodes = currentNode._childNodes,
|
|
||||||
originalCount = stack.length,
|
|
||||||
count = childNodes.length;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
{
|
|
||||||
var treeNode = childNodes[count];
|
|
||||||
|
|
||||||
if ([visited containsObject:treeNode])
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
stack.push(treeNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (originalCount === stack.length)
|
|
||||||
{
|
|
||||||
[visited addObject:currentNode];
|
|
||||||
|
|
||||||
if (shouldReturnAllObjects)
|
|
||||||
allObjects.push(stack.pop());
|
|
||||||
else
|
|
||||||
return stack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return allObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)_levelOrderFromState:(Object)state allObjects:(BOOL)shouldReturnAllObjects
|
|
||||||
{
|
|
||||||
// Implement.
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)nextObject
|
|
||||||
{
|
|
||||||
if (_order === _CPTreeNodeEnumeratorPreOrder)
|
|
||||||
return [self _preOrderFromState:[self _newState] allObjects:NO];
|
|
||||||
|
|
||||||
else if (_order === _CPTreeNodeEnumeratorInOrder)
|
|
||||||
return [self _inOrderFromState:[self _newState] allObjects:NO];
|
|
||||||
|
|
||||||
else if (_order === _CPTreeNodeEnumeratorPostOrder)
|
|
||||||
return [self _postOrderFromState:[self _newState] allObjects:NO];
|
|
||||||
|
|
||||||
//else if (_order === _CPTreeNodeEnumeratorLevelOrder)
|
|
||||||
return [self _levelOrderFromState:[self _newState] allObjects:NO];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPArray)allObjects
|
|
||||||
{
|
|
||||||
if (_order === _CPTreeNodeEnumeratorPreOrder)
|
|
||||||
return [self _preOrderFromState:[self _newState] allObjects:YES];
|
|
||||||
|
|
||||||
else if (_order === _CPTreeNodeEnumeratorInOrder)
|
|
||||||
return [self _inOrderFromState:[self _newState] allObjects:YES];
|
|
||||||
|
|
||||||
else if (_order === _CPTreeNodeEnumeratorPostOrder)
|
|
||||||
return [self _postOrderFromState:[self _newState] allObjects:YES];
|
|
||||||
|
|
||||||
//else if (_order === _CPTreeNodeEnumeratorLevelOrder)
|
|
||||||
return [self _levelOrderFromState:[self _newState] allObjects:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int)countByEnumeratingWithState:(id)aState objects:(id)objects count:(id)aCount
|
|
||||||
{
|
|
||||||
if (aState.state !== 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
var count = [[self allObjects] countByEnumeratingWithState:aState objects:objects count:aCount];
|
|
||||||
|
|
||||||
// Dangerous?
|
|
||||||
aState.state = YES;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|||||||
+37
-148
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
@import <Foundation/CPArray.j>
|
@import <Foundation/CPArray.j>
|
||||||
@import <Foundation/CPObjJRuntime.j>
|
@import <Foundation/CPObjJRuntime.j>
|
||||||
@import <Foundation/CPSet.j>
|
|
||||||
|
|
||||||
@import "CGAffineTransform.j"
|
@import "CGAffineTransform.j"
|
||||||
@import "CGGeometry.j"
|
@import "CGGeometry.j"
|
||||||
@@ -35,6 +34,11 @@
|
|||||||
@import "_CPDisplayServer.j"
|
@import "_CPDisplayServer.j"
|
||||||
|
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
#include "CoreGraphics/CGAffineTransform.h"
|
||||||
|
#include "CoreGraphics/CGGeometry.h"
|
||||||
|
#include "Platform/DOM/CPDOMDisplayServer.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@global
|
@global
|
||||||
@group CPViewAutoresizingMasks
|
@group CPViewAutoresizingMasks
|
||||||
@@ -90,8 +94,7 @@ var DOMElementPrototype = nil,
|
|||||||
BackgroundTrivialColor = 0,
|
BackgroundTrivialColor = 0,
|
||||||
BackgroundVerticalThreePartImage = 1,
|
BackgroundVerticalThreePartImage = 1,
|
||||||
BackgroundHorizontalThreePartImage = 2,
|
BackgroundHorizontalThreePartImage = 2,
|
||||||
BackgroundNinePartImage = 3,
|
BackgroundNinePartImage = 3;
|
||||||
BackgroundTransparentColor = 4;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var CPViewFlags = { },
|
var CPViewFlags = { },
|
||||||
@@ -136,7 +139,6 @@ var CPViewFlags = { },
|
|||||||
|
|
||||||
BOOL _isHidden;
|
BOOL _isHidden;
|
||||||
BOOL _hitTests;
|
BOOL _hitTests;
|
||||||
BOOL _clipsToBounds;
|
|
||||||
|
|
||||||
BOOL _postsFrameChangedNotifications;
|
BOOL _postsFrameChangedNotifications;
|
||||||
BOOL _postsBoundsChangedNotifications;
|
BOOL _postsBoundsChangedNotifications;
|
||||||
@@ -174,7 +176,6 @@ var CPViewFlags = { },
|
|||||||
|
|
||||||
// Theming Support
|
// Theming Support
|
||||||
CPTheme _theme;
|
CPTheme _theme;
|
||||||
CPString _themeClass;
|
|
||||||
JSObject _themeAttributes;
|
JSObject _themeAttributes;
|
||||||
unsigned _themeState;
|
unsigned _themeState;
|
||||||
|
|
||||||
@@ -276,7 +277,6 @@ var CPViewFlags = { },
|
|||||||
|
|
||||||
_autoresizingMask = CPViewNotSizable;
|
_autoresizingMask = CPViewNotSizable;
|
||||||
_autoresizesSubviews = YES;
|
_autoresizesSubviews = YES;
|
||||||
_clipsToBounds = YES;
|
|
||||||
|
|
||||||
_opacity = 1.0;
|
_opacity = 1.0;
|
||||||
_isHidden = NO;
|
_isHidden = NO;
|
||||||
@@ -835,33 +835,28 @@ var CPViewFlags = { },
|
|||||||
|
|
||||||
if (_backgroundType !== BackgroundTrivialColor)
|
if (_backgroundType !== BackgroundTrivialColor)
|
||||||
{
|
{
|
||||||
if (_backgroundType === BackgroundTransparentColor)
|
var images = [[_backgroundColor patternImage] imageSlices];
|
||||||
|
|
||||||
|
if (_backgroundType === BackgroundVerticalThreePartImage)
|
||||||
{
|
{
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
else if (_backgroundType === BackgroundHorizontalThreePartImage)
|
||||||
{
|
{
|
||||||
var images = [[_backgroundColor patternImage] imageSlices];
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
|
||||||
|
}
|
||||||
|
|
||||||
if (_backgroundType === BackgroundVerticalThreePartImage)
|
else if (_backgroundType === BackgroundNinePartImage)
|
||||||
{
|
{
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
|
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
|
||||||
}
|
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
|
||||||
else if (_backgroundType === BackgroundHorizontalThreePartImage)
|
|
||||||
{
|
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
|
|
||||||
}
|
|
||||||
else if (_backgroundType === BackgroundNinePartImage)
|
|
||||||
{
|
|
||||||
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
|
|
||||||
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
|
|
||||||
|
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
|
||||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
|
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1000,7 +995,7 @@ var CPViewFlags = { },
|
|||||||
{
|
{
|
||||||
var mask = [self autoresizingMask];
|
var mask = [self autoresizingMask];
|
||||||
|
|
||||||
if (mask == CPViewNotSizable)
|
if(mask == CPViewNotSizable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var frame = _superview._frame,
|
var frame = _superview._frame,
|
||||||
@@ -1156,7 +1151,7 @@ var CPViewFlags = { },
|
|||||||
{
|
{
|
||||||
aFlag = !!aFlag;
|
aFlag = !!aFlag;
|
||||||
|
|
||||||
if (_isHidden === aFlag)
|
if(_isHidden === aFlag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// FIXME: Should we return to visibility? This breaks in FireFox, Opera, and IE.
|
// FIXME: Should we return to visibility? This breaks in FireFox, Opera, and IE.
|
||||||
@@ -1182,31 +1177,7 @@ var CPViewFlags = { },
|
|||||||
}
|
}
|
||||||
while (view = [view superview]);
|
while (view = [view superview]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _notifyViewDidHide];
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
[self _notifyViewDidUnhide];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_notifyViewDidHide
|
|
||||||
{
|
|
||||||
[self viewDidHide];
|
|
||||||
|
|
||||||
var count = [_subviews count];
|
|
||||||
while (count--)
|
|
||||||
[_subviews[count] _notifyViewDidHide];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_notifyViewDidUnhide
|
|
||||||
{
|
|
||||||
[self viewDidUnhide];
|
|
||||||
|
|
||||||
var count = [_subviews count];
|
|
||||||
while (count--)
|
|
||||||
[_subviews[count] _notifyViewDidUnhide];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1217,23 +1188,6 @@ var CPViewFlags = { },
|
|||||||
return _isHidden;
|
return _isHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setClipsToBounds:(BOOL)shouldClip
|
|
||||||
{
|
|
||||||
if (_clipsToBounds === shouldClip)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_clipsToBounds = shouldClip;
|
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
|
||||||
_DOMElement.style.overflow = _clipsToBounds ? "hidden" : "visible";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)clipsToBounds
|
|
||||||
{
|
|
||||||
return _clipsToBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the opacity of the receiver. The value must be in the range of 0.0 to 1.0, where 0.0 is
|
Sets the opacity of the receiver. The value must be in the range of 0.0 to 1.0, where 0.0 is
|
||||||
completely transparent and 1.0 is completely opaque.
|
completely transparent and 1.0 is completely opaque.
|
||||||
@@ -1284,34 +1238,6 @@ var CPViewFlags = { },
|
|||||||
return view !== nil;
|
return view !== nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Called when the return value of isHiddenOrHasHiddenAncestor becomes YES,
|
|
||||||
e.g. when this view becomes hidden due to a setHidden:YES message to
|
|
||||||
itself or to one of its superviews.
|
|
||||||
|
|
||||||
Note: in the current implementation, viewDidHide may be called multiple
|
|
||||||
times if additional superviews are hidden, even if
|
|
||||||
isHiddenOrHasHiddenAncestor was already YES.
|
|
||||||
*/
|
|
||||||
- (void)viewDidHide
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Called when the return value of isHiddenOrHasHiddenAncestor becomes NO,
|
|
||||||
e.g. when this view stops being hidden due to a setHidden:NO message to
|
|
||||||
itself or to one of its superviews.
|
|
||||||
|
|
||||||
Note: in the current implementation, viewDidUnhide may be called multiple
|
|
||||||
times if additional superviews are unhidden, even if
|
|
||||||
isHiddenOrHasHiddenAncestor was already NO.
|
|
||||||
*/
|
|
||||||
- (void)viewDidUnhide
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns whether the receiver should be sent a \c -mouseDown: message for \c anEvent.<br/>
|
Returns whether the receiver should be sent a \c -mouseDown: message for \c anEvent.<br/>
|
||||||
Returns \c YES by default.
|
Returns \c YES by default.
|
||||||
@@ -1348,7 +1274,7 @@ var CPViewFlags = { },
|
|||||||
*/
|
*/
|
||||||
- (CPView)hitTest:(CPPoint)aPoint
|
- (CPView)hitTest:(CPPoint)aPoint
|
||||||
{
|
{
|
||||||
if (_isHidden || !_hitTests || !CPRectContainsPoint(_frame, aPoint))
|
if(_isHidden || !_hitTests || !CPRectContainsPoint(_frame, aPoint))
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
var view = nil,
|
var view = nil,
|
||||||
@@ -1413,9 +1339,6 @@ var CPViewFlags = { },
|
|||||||
if (_backgroundColor == aColor)
|
if (_backgroundColor == aColor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (aColor == [CPNull null])
|
|
||||||
aColor = nil;
|
|
||||||
|
|
||||||
_backgroundColor = aColor;
|
_backgroundColor = aColor;
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
@@ -1438,7 +1361,7 @@ var CPViewFlags = { },
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
|
_backgroundType = BackgroundTrivialColor;
|
||||||
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
|
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1461,7 +1384,7 @@ var CPViewFlags = { },
|
|||||||
_DOMElement.removeChild(_DOMImageParts.pop());
|
_DOMElement.removeChild(_DOMImageParts.pop());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
|
if (_backgroundType === BackgroundTrivialColor)
|
||||||
{
|
{
|
||||||
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
|
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
|
||||||
|
|
||||||
@@ -1731,7 +1654,7 @@ setBoundsOrigin:
|
|||||||
var theWindow = [self window];
|
var theWindow = [self window];
|
||||||
|
|
||||||
[theWindow _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
|
[theWindow _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
|
||||||
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes];
|
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes]
|
||||||
[theWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
|
[theWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes];
|
||||||
|
|
||||||
_registeredDraggedTypesArray = nil;
|
_registeredDraggedTypesArray = nil;
|
||||||
@@ -1843,17 +1766,12 @@ setBoundsOrigin:
|
|||||||
|
|
||||||
- (void)displayRectIgnoringOpacity:(CGRect)aRect inContext:(CPGraphicsContext)aGraphicsContext
|
- (void)displayRectIgnoringOpacity:(CGRect)aRect inContext:(CPGraphicsContext)aGraphicsContext
|
||||||
{
|
{
|
||||||
if ([self isHidden])
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
|
||||||
[self lockFocus];
|
[self lockFocus];
|
||||||
|
|
||||||
CGContextClearRect([[CPGraphicsContext currentContext] graphicsPort], aRect);
|
CGContextClearRect([[CPGraphicsContext currentContext] graphicsPort], aRect);
|
||||||
|
|
||||||
[self drawRect:aRect];
|
[self drawRect:aRect];
|
||||||
[self unlockFocus];
|
[self unlockFocus];
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDraw
|
- (void)viewWillDraw
|
||||||
@@ -1956,7 +1874,7 @@ setBoundsOrigin:
|
|||||||
var superview = _superview,
|
var superview = _superview,
|
||||||
clipViewClass = [CPClipView class];
|
clipViewClass = [CPClipView class];
|
||||||
|
|
||||||
while (superview && ![superview isKindOfClass:clipViewClass])
|
while(superview && ![superview isKindOfClass:clipViewClass])
|
||||||
superview = superview._superview;
|
superview = superview._superview;
|
||||||
|
|
||||||
return superview;
|
return superview;
|
||||||
@@ -2052,7 +1970,7 @@ setBoundsOrigin:
|
|||||||
var superview = _superview,
|
var superview = _superview,
|
||||||
scrollViewClass = [CPScrollView class];
|
scrollViewClass = [CPScrollView class];
|
||||||
|
|
||||||
while (superview && ![superview isKindOfClass:scrollViewClass])
|
while(superview && ![superview isKindOfClass:scrollViewClass])
|
||||||
superview = superview._superview;
|
superview = superview._superview;
|
||||||
|
|
||||||
return superview;
|
return superview;
|
||||||
@@ -2248,29 +2166,11 @@ setBoundsOrigin:
|
|||||||
|
|
||||||
#pragma mark Theme Attributes
|
#pragma mark Theme Attributes
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)themeClass
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPString)themeClass
|
|
||||||
{
|
|
||||||
if (_themeClass)
|
|
||||||
return _themeClass;
|
|
||||||
|
|
||||||
return [[self class] defaultThemeClass];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setThemeClass:(CPString)theClass
|
|
||||||
{
|
|
||||||
_themeClass = theClass;
|
|
||||||
|
|
||||||
[self _loadThemeAttributes];
|
|
||||||
|
|
||||||
[self setNeedsLayout];
|
|
||||||
[self setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (CPDictionary)themeAttributes
|
+ (CPDictionary)themeAttributes
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
@@ -2329,7 +2229,7 @@ setBoundsOrigin:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var theme = [self theme],
|
var theme = [self theme],
|
||||||
themeClass = [self themeClass];
|
themeClass = [theClass themeClass];
|
||||||
|
|
||||||
_themeAttributes = {};
|
_themeAttributes = {};
|
||||||
|
|
||||||
@@ -2338,7 +2238,7 @@ setBoundsOrigin:
|
|||||||
var attributeName = attributes[count--],
|
var attributeName = attributes[count--],
|
||||||
attribute = [[_CPThemeAttribute alloc] initWithName:attributeName defaultValue:attributes[count]];
|
attribute = [[_CPThemeAttribute alloc] initWithName:attributeName defaultValue:attributes[count]];
|
||||||
|
|
||||||
[attribute setParentAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
|
[attribute setParentAttribute:[theme _attributeWithName:attributeName forClass:themeClass]];
|
||||||
|
|
||||||
_themeAttributes[attributeName] = attribute;
|
_themeAttributes[attributeName] = attribute;
|
||||||
}
|
}
|
||||||
@@ -2365,11 +2265,11 @@ setBoundsOrigin:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var theme = [self theme],
|
var theme = [self theme],
|
||||||
themeClass = [self themeClass];
|
themeClass = [[self class] themeClass];
|
||||||
|
|
||||||
for (var attributeName in _themeAttributes)
|
for (var attributeName in _themeAttributes)
|
||||||
if (_themeAttributes.hasOwnProperty(attributeName))
|
if (_themeAttributes.hasOwnProperty(attributeName))
|
||||||
[_themeAttributes[attributeName] setParentAttribute:[theme attributeWithName:attributeName forClass:themeClass]];
|
[_themeAttributes[attributeName] setParentAttribute:[theme _attributeWithName:attributeName forClass:themeClass]];
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
@@ -2495,14 +2395,6 @@ setBoundsOrigin:
|
|||||||
return _ephemeralSubviewsForNames[aViewName];
|
return _ephemeralSubviewsForNames[aViewName];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPView)ephemeralSubviewNamed:(CPString)aViewName
|
|
||||||
{
|
|
||||||
if (!_ephemeralSubviewsForNames)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
return (_ephemeralSubviewsForNames[aViewName] || nil);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||||
@@ -2516,7 +2408,6 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
|||||||
CPViewSubviewsKey = @"CPViewSubviewsKey",
|
CPViewSubviewsKey = @"CPViewSubviewsKey",
|
||||||
CPViewSuperviewKey = @"CPViewSuperviewKey",
|
CPViewSuperviewKey = @"CPViewSuperviewKey",
|
||||||
CPViewTagKey = @"CPViewTagKey",
|
CPViewTagKey = @"CPViewTagKey",
|
||||||
CPViewThemeClassKey = @"CPViewThemeClassKey",
|
|
||||||
CPViewThemeStateKey = @"CPViewThemeStateKey",
|
CPViewThemeStateKey = @"CPViewThemeStateKey",
|
||||||
CPViewWindowKey = @"CPViewWindowKey",
|
CPViewWindowKey = @"CPViewWindowKey",
|
||||||
CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
|
CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
|
||||||
@@ -2596,12 +2487,11 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
|||||||
[self setupViewFlags];
|
[self setupViewFlags];
|
||||||
|
|
||||||
_theme = [CPTheme defaultTheme];
|
_theme = [CPTheme defaultTheme];
|
||||||
_themeClass = [aCoder decodeObjectForKey:CPViewThemeClassKey];
|
|
||||||
_themeState = CPThemeState([aCoder decodeIntForKey:CPViewThemeStateKey]);
|
_themeState = CPThemeState([aCoder decodeIntForKey:CPViewThemeStateKey]);
|
||||||
_themeAttributes = {};
|
_themeAttributes = {};
|
||||||
|
|
||||||
var theClass = [self class],
|
var theClass = [self class],
|
||||||
themeClass = [self themeClass],
|
themeClass = [theClass themeClass],
|
||||||
attributes = [theClass _themeAttributes],
|
attributes = [theClass _themeAttributes],
|
||||||
count = attributes.length;
|
count = attributes.length;
|
||||||
|
|
||||||
@@ -2684,7 +2574,6 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
|||||||
if (previousKeyView !== nil)
|
if (previousKeyView !== nil)
|
||||||
[aCoder encodeConditionalObject:previousKeyView forKey:CPViewPreviousKeyViewKey];
|
[aCoder encodeConditionalObject:previousKeyView forKey:CPViewPreviousKeyViewKey];
|
||||||
|
|
||||||
[aCoder encodeObject:[self themeClass] forKey:CPViewThemeClassKey];
|
|
||||||
[aCoder encodeInt:CPThemeStateName(_themeState) forKey:CPViewThemeStateKey];
|
[aCoder encodeInt:CPThemeStateName(_themeState) forKey:CPViewThemeStateKey];
|
||||||
|
|
||||||
for (var attributeName in _themeAttributes)
|
for (var attributeName in _themeAttributes)
|
||||||
|
|||||||
+12
-13
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* CPViewAnimation.j
|
* CPFlashView.j
|
||||||
* AppKit
|
* AppKit
|
||||||
*
|
*
|
||||||
* Created by Klaas Pieter Annema on September 3, 2009.
|
* Created by Klaas Pieter Annema on September 3, 2009.
|
||||||
@@ -20,8 +20,7 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPAnimation.j"
|
@import <AppKit/CPAnimation.j>
|
||||||
|
|
||||||
|
|
||||||
CPViewAnimationTargetKey = @"CPViewAnimationTarget";
|
CPViewAnimationTargetKey = @"CPViewAnimationTarget";
|
||||||
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrame";
|
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrame";
|
||||||
@@ -70,7 +69,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
[super startAnimation];
|
[super startAnimation];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setCurrentProgress:(CPAnimationProgress)progress
|
- (void)setCurrentProgress:(NSAnimationProgress)progress
|
||||||
{
|
{
|
||||||
[super setCurrentProgress:progress];
|
[super setCurrentProgress:progress];
|
||||||
|
|
||||||
@@ -78,17 +77,17 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
while (animationIndex--)
|
while (animationIndex--)
|
||||||
{
|
{
|
||||||
var dictionary = [_viewAnimations objectAtIndex:animationIndex],
|
var dictionary = [_viewAnimations objectAtIndex:animationIndex],
|
||||||
view = [self _targetView:dictionary],
|
view = [self _targetView:dictionary]
|
||||||
startFrame = [self _startFrame:dictionary],
|
startFrame = [self _startFrame:dictionary]
|
||||||
endFrame = [self _endFrame:dictionary],
|
endFrame = [self _endFrame:dictionary]
|
||||||
differenceFrame = _CGRectMakeZero();
|
differenceFrame = CPRectMakeZero();
|
||||||
|
|
||||||
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
|
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
|
||||||
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
|
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
|
||||||
differenceFrame.size.width = endFrame.size.width - startFrame.size.width;
|
differenceFrame.size.width = endFrame.size.width - startFrame.size.width;
|
||||||
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
|
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
|
||||||
|
|
||||||
var intermediateFrame = _CGRectMakeZero();
|
var intermediateFrame = CPRectMakeZero();
|
||||||
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
|
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
|
||||||
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
|
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
|
||||||
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
|
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
|
||||||
@@ -104,7 +103,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
|
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
|
||||||
|
|
||||||
if (progress === 1.0)
|
if (progress === 1.0)
|
||||||
[view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
[view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +124,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
else if (effect === CPViewAnimationFadeOutEffect)
|
else if (effect === CPViewAnimationFadeOutEffect)
|
||||||
[view setAlphaValue:0.0];
|
[view setAlphaValue:0.0];
|
||||||
|
|
||||||
[view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
[view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[super stopAnimation];
|
[super stopAnimation];
|
||||||
@@ -140,7 +139,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
return targetView;
|
return targetView;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)_startFrame:(CPDictionary)dictionary
|
- (CPRect)_startFrame:(CPDictionary)dictionary
|
||||||
{
|
{
|
||||||
var startFrame = [dictionary valueForKey:CPViewAnimationStartFrameKey];
|
var startFrame = [dictionary valueForKey:CPViewAnimationStartFrameKey];
|
||||||
if (!startFrame)
|
if (!startFrame)
|
||||||
@@ -149,7 +148,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
return startFrame;
|
return startFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)_endFrame:(CPDictionary)dictionary
|
- (CPRect)_endFrame:(CPDictionary)dictionary
|
||||||
{
|
{
|
||||||
var endFrame = [dictionary valueForKey:CPViewAnimationEndFrameKey];
|
var endFrame = [dictionary valueForKey:CPViewAnimationEndFrameKey];
|
||||||
if (!endFrame)
|
if (!endFrame)
|
||||||
|
|||||||
+60
-26
@@ -20,12 +20,7 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import <Foundation/CPArray.j>
|
@import <AppKit/CPResponder.j>
|
||||||
|
|
||||||
@import "CPApplication.j"
|
|
||||||
@import "CPCib.j"
|
|
||||||
@import "CPResponder.j"
|
|
||||||
|
|
||||||
|
|
||||||
var CPViewControllerCachedCibs;
|
var CPViewControllerCachedCibs;
|
||||||
|
|
||||||
@@ -52,11 +47,10 @@ var CPViewControllerCachedCibs;
|
|||||||
*/
|
*/
|
||||||
@implementation CPViewController : CPResponder
|
@implementation CPViewController : CPResponder
|
||||||
{
|
{
|
||||||
CPView _view @accessors(property=view);
|
CPView _view;
|
||||||
BOOL _isLoading;
|
|
||||||
|
|
||||||
id _representedObject @accessors(property=representedObject);
|
id _representedObject @accessors(property=representedObject);
|
||||||
CPString _title @accessors(property=title);
|
CPString _title;
|
||||||
|
|
||||||
CPString _cibName @accessors(property=cibName, readonly);
|
CPString _cibName @accessors(property=cibName, readonly);
|
||||||
CPBundle _cibBundle @accessors(property=cibBundle, readonly);
|
CPBundle _cibBundle @accessors(property=cibBundle, readonly);
|
||||||
@@ -84,7 +78,9 @@ var CPViewControllerCachedCibs;
|
|||||||
|
|
||||||
- (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner
|
- (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner
|
||||||
{
|
{
|
||||||
return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
|
return [self initWithCibName:aCibNameOrNil
|
||||||
|
bundle:aCibBundleOrNil
|
||||||
|
externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -103,15 +99,34 @@ var CPViewControllerCachedCibs;
|
|||||||
{
|
{
|
||||||
// Don't load the cib until someone actually requests the view. The user may just be intending to use setView:.
|
// Don't load the cib until someone actually requests the view. The user may just be intending to use setView:.
|
||||||
_cibName = aCibNameOrNil;
|
_cibName = aCibNameOrNil;
|
||||||
_cibBundle = aCibBundleOrNil || [CPBundle mainBundle];
|
_cibBundle = aCibBundleOrNil;
|
||||||
_cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
|
|
||||||
|
|
||||||
_isLoading = NO;
|
if (!_cibBundle)
|
||||||
|
{
|
||||||
|
var owner = [anExternalNameTable objectForKey:CPCibOwner];
|
||||||
|
|
||||||
|
_cibBundle = owner ? [CPBundle bundleForClass:[owner class]] : [CPBundle mainBundle];
|
||||||
|
}
|
||||||
|
|
||||||
|
_cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setTitle:(CPString)aTitle
|
||||||
|
{
|
||||||
|
_title = aTitle;
|
||||||
|
|
||||||
|
if (self._navigationItem)
|
||||||
|
[_navigationItem setTitle:aTitle];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPString)title
|
||||||
|
{
|
||||||
|
return _title;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Programmatically creates the view that the controller manages.
|
Programmatically creates the view that the controller manages.
|
||||||
You should never call this method directly. The view controller calls this method when the view property is requested but is nil.
|
You should never call this method directly. The view controller calls this method when the view property is requested but is nil.
|
||||||
@@ -119,10 +134,10 @@ var CPViewControllerCachedCibs;
|
|||||||
If you create your views manually, you must override this method and use it to create your view and assign it to the view property.
|
If you create your views manually, you must override this method and use it to create your view and assign it to the view property.
|
||||||
The default implementation for programmatic views is to create a plain view. You can invoke super to utilize this view.
|
The default implementation for programmatic views is to create a plain view. You can invoke super to utilize this view.
|
||||||
|
|
||||||
If you use Interface Builder to create your views, you initialize the view using the
|
If you use Interface Builder to create your views and initialize the view controllerŃthat is, you initialize the view using the
|
||||||
initWithCibName:bundle: method then you must not override this method. The consequences risk shattering the space-time continuum.
|
initWithCibName:bundle: methodŃthen you must not override this method. The consequences risk shattering the space-time continuum.
|
||||||
|
|
||||||
Note: The cib loading system is currently synchronous.
|
Note: The cib loading system is currently asynchronous.
|
||||||
*/
|
*/
|
||||||
- (void)loadView
|
- (void)loadView
|
||||||
{
|
{
|
||||||
@@ -132,9 +147,9 @@ var CPViewControllerCachedCibs;
|
|||||||
// check if a cib is already cached for the current _cibName
|
// check if a cib is already cached for the current _cibName
|
||||||
var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
|
var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
|
||||||
|
|
||||||
|
// If the cib isn't cached yet : fetch it and cache it
|
||||||
if (!cib)
|
if (!cib)
|
||||||
{
|
{
|
||||||
// if the cib isn't cached yet : fetch it and cache it
|
|
||||||
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
|
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
|
||||||
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
|
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
|
||||||
}
|
}
|
||||||
@@ -151,8 +166,6 @@ var CPViewControllerCachedCibs;
|
|||||||
{
|
{
|
||||||
if (!_view)
|
if (!_view)
|
||||||
{
|
{
|
||||||
_isLoading = YES;
|
|
||||||
|
|
||||||
var cibOwner = [_cibExternalNameTable objectForKey:CPCibOwner];
|
var cibOwner = [_cibExternalNameTable objectForKey:CPCibOwner];
|
||||||
|
|
||||||
if ([cibOwner respondsToSelector:@selector(viewControllerWillLoadCib:)])
|
if ([cibOwner respondsToSelector:@selector(viewControllerWillLoadCib:)])
|
||||||
@@ -173,7 +186,6 @@ var CPViewControllerCachedCibs;
|
|||||||
if ([cibOwner respondsToSelector:@selector(viewControllerDidLoadCib:)])
|
if ([cibOwner respondsToSelector:@selector(viewControllerDidLoadCib:)])
|
||||||
[cibOwner viewControllerDidLoadCib:self];
|
[cibOwner viewControllerDidLoadCib:self];
|
||||||
|
|
||||||
_isLoading = NO;
|
|
||||||
[self viewDidLoad];
|
[self viewDidLoad];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +196,7 @@ var CPViewControllerCachedCibs;
|
|||||||
/*!
|
/*!
|
||||||
This method is called after the view controller has loaded its associated views into memory.
|
This method is called after the view controller has loaded its associated views into memory.
|
||||||
This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method.
|
This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method.
|
||||||
This method is most commonly used to perform additional initialization steps on views that are loaded from cib files.
|
This method is most commonly used to perform additional initialization steps on views that are loaded from nib files.
|
||||||
*/
|
*/
|
||||||
- (void)viewDidLoad
|
- (void)viewDidLoad
|
||||||
{
|
{
|
||||||
@@ -200,13 +212,35 @@ var CPViewControllerCachedCibs;
|
|||||||
*/
|
*/
|
||||||
- (void)setView:(CPView)aView
|
- (void)setView:(CPView)aView
|
||||||
{
|
{
|
||||||
var viewWasLoaded = !_view;
|
|
||||||
|
|
||||||
_view = aView;
|
_view = aView;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the viewDidLoad method is called if the view is set directly
|
- (CPNavigationItem)navigationItem
|
||||||
if (!_isLoading && viewWasLoaded)
|
{
|
||||||
[self viewDidLoad];
|
var navigationItem = self._navigationItem;
|
||||||
|
|
||||||
|
if (!navigationItem)
|
||||||
|
navigationItem = [[CPNavigationItem alloc] initWithTitle:[self title]];
|
||||||
|
|
||||||
|
self._navigationItem = navigationItem;
|
||||||
|
|
||||||
|
return navigationItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)isAnimated
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidAppear:(BOOL)isAnimated
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillDisappear:(BOOL)isAnimated
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidDisappear:(BOOL)isAnimated
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+9
-53
@@ -20,8 +20,9 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPView.j"
|
@import <AppKit/CPView.j>
|
||||||
@import "CPScrollView.j"
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
// FIXME: implement these where possible:
|
// FIXME: implement these where possible:
|
||||||
@@ -73,8 +74,6 @@ CPWebViewScrollNative = 2;
|
|||||||
|
|
||||||
int _scrollMode;
|
int _scrollMode;
|
||||||
CGSize _scrollSize;
|
CGSize _scrollSize;
|
||||||
|
|
||||||
int _loadHTMLStringTimer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
|
- (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
|
||||||
@@ -111,7 +110,6 @@ CPWebViewScrollNative = 2;
|
|||||||
_iframe.style.width = "100%";
|
_iframe.style.width = "100%";
|
||||||
_iframe.style.height = "100%";
|
_iframe.style.height = "100%";
|
||||||
_iframe.style.borderWidth = "0px";
|
_iframe.style.borderWidth = "0px";
|
||||||
_iframe.frameBorder = "0";
|
|
||||||
|
|
||||||
[self setDrawsBackground:YES];
|
[self setDrawsBackground:YES];
|
||||||
|
|
||||||
@@ -173,32 +171,7 @@ CPWebViewScrollNative = 2;
|
|||||||
[self _resizeWebFrame];
|
[self _resizeWebFrame];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_attachScrollEventIfNecessary
|
- (BOOL)_resizeWebFrame
|
||||||
{
|
|
||||||
if (_scrollMode !== CPWebViewScrollAppKit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var win = null;
|
|
||||||
try { win = [self DOMWindow]; } catch (e) {}
|
|
||||||
|
|
||||||
if (win && win.addEventListener)
|
|
||||||
{
|
|
||||||
var scrollEventHandler = function(anEvent)
|
|
||||||
{
|
|
||||||
var frameBounds = [self bounds],
|
|
||||||
frameCenter = CGPointMake(CGRectGetMidX(frameBounds), CGRectGetMidY(frameBounds)),
|
|
||||||
windowOrigin = [self convertPoint:frameCenter toView:nil],
|
|
||||||
globalOrigin = [[self window] convertBaseToBridge:windowOrigin];
|
|
||||||
|
|
||||||
anEvent._overrideLocation = globalOrigin;
|
|
||||||
[[[self window] platformWindow] scrollEvent:anEvent];
|
|
||||||
};
|
|
||||||
|
|
||||||
win.addEventListener("DOMMouseScroll", scrollEventHandler, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_resizeWebFrame
|
|
||||||
{
|
{
|
||||||
if (_scrollMode === CPWebViewScrollAppKit)
|
if (_scrollMode === CPWebViewScrollAppKit)
|
||||||
{
|
{
|
||||||
@@ -208,14 +181,13 @@ CPWebViewScrollNative = 2;
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var visibleRect = [_frameView visibleRect];
|
[_frameView setFrameSize:[_scrollView contentSize]];
|
||||||
[_frameView setFrameSize:CGSizeMake(CGRectGetMaxX(visibleRect), CGRectGetMaxY(visibleRect))];
|
|
||||||
|
|
||||||
// try to get the document size so we can correctly set the frame
|
// try to get the document size so we can correctly set the frame
|
||||||
var win = null;
|
var win = null;
|
||||||
try { win = [self DOMWindow]; } catch (e) {}
|
try { win = [self DOMWindow]; } catch (e) {}
|
||||||
|
|
||||||
if (win && win.document && win.document.body)
|
if (win && win.document)
|
||||||
{
|
{
|
||||||
var width = win.document.body.scrollWidth,
|
var width = win.document.body.scrollWidth,
|
||||||
height = win.document.body.scrollHeight;
|
height = win.document.body.scrollHeight;
|
||||||
@@ -231,8 +203,6 @@ CPWebViewScrollNative = 2;
|
|||||||
|
|
||||||
[_frameView setFrameSize:CGSizeMake(800, 1600)];
|
[_frameView setFrameSize:CGSizeMake(800, 1600)];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_frameView scrollRectToVisible:visibleRect];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,10 +217,7 @@ CPWebViewScrollNative = 2;
|
|||||||
|
|
||||||
- (void)_setScrollMode:(int)aScrollMode
|
- (void)_setScrollMode:(int)aScrollMode
|
||||||
{
|
{
|
||||||
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
|
_scrollMode = aScrollMode;
|
||||||
_scrollMode = CPWebViewScrollNative;
|
|
||||||
else
|
|
||||||
_scrollMode = aScrollMode;
|
|
||||||
|
|
||||||
_ignoreLoadStart = YES;
|
_ignoreLoadStart = YES;
|
||||||
_ignoreLoadEnd = YES;
|
_ignoreLoadEnd = YES;
|
||||||
@@ -289,8 +256,6 @@ CPWebViewScrollNative = 2;
|
|||||||
|
|
||||||
[self _setScrollMode:CPWebViewScrollAppKit];
|
[self _setScrollMode:CPWebViewScrollAppKit];
|
||||||
|
|
||||||
[_frameView setFrameSize:[_scrollView contentSize]];
|
|
||||||
|
|
||||||
[self _startedLoading];
|
[self _startedLoading];
|
||||||
|
|
||||||
_ignoreLoadStart = YES;
|
_ignoreLoadStart = YES;
|
||||||
@@ -328,19 +293,11 @@ CPWebViewScrollNative = 2;
|
|||||||
// clear the iframe
|
// clear the iframe
|
||||||
_iframe.src = "";
|
_iframe.src = "";
|
||||||
|
|
||||||
if (_loadHTMLStringTimer !== nil)
|
|
||||||
{
|
|
||||||
window.clearTimeout(_loadHTMLStringTimer);
|
|
||||||
_loadHTMLStringTimer = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document
|
// need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document
|
||||||
_loadHTMLStringTimer = window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
var win = [self DOMWindow];
|
var win = [self DOMWindow];
|
||||||
|
|
||||||
if (win)
|
win.document.write(_html);
|
||||||
win.document.write(_html);
|
|
||||||
|
|
||||||
window.setTimeout(_loadCallback, 1);
|
window.setTimeout(_loadCallback, 1);
|
||||||
}, 0);
|
}, 0);
|
||||||
@@ -358,7 +315,6 @@ CPWebViewScrollNative = 2;
|
|||||||
- (void)_finishedLoading
|
- (void)_finishedLoading
|
||||||
{
|
{
|
||||||
[self _resizeWebFrame];
|
[self _resizeWebFrame];
|
||||||
[self _attachScrollEventIfNecessary];
|
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
|
[[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
|
||||||
|
|
||||||
|
|||||||
+37
-211
@@ -26,9 +26,14 @@
|
|||||||
|
|
||||||
@import "CGGeometry.j"
|
@import "CGGeometry.j"
|
||||||
@import "CPAnimation.j"
|
@import "CPAnimation.j"
|
||||||
@import "CPPlatformWindow.j"
|
|
||||||
@import "CPResponder.j"
|
@import "CPResponder.j"
|
||||||
@import "CPScreen.j"
|
@import "CPScreen.j"
|
||||||
|
@import "CPPlatformWindow.j"
|
||||||
|
|
||||||
|
#include "../Platform/Platform.h"
|
||||||
|
#include "../Platform/DOM/CPDOMDisplayServer.h"
|
||||||
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -195,8 +200,6 @@ var SHADOW_MARGIN_LEFT = 20.0,
|
|||||||
var CPWindowSaveImage = nil,
|
var CPWindowSaveImage = nil,
|
||||||
CPWindowSavingImage = nil;
|
CPWindowSavingImage = nil;
|
||||||
|
|
||||||
var CPWindowResizeTime = 0.2;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPWindow
|
@class CPWindow
|
||||||
@@ -317,8 +320,6 @@ var CPWindowResizeTime = 0.2;
|
|||||||
CPDictionary _sheetContext;
|
CPDictionary _sheetContext;
|
||||||
CPWindow _parentView;
|
CPWindow _parentView;
|
||||||
BOOL _isSheet;
|
BOOL _isSheet;
|
||||||
|
|
||||||
_CPWindowFrameAnimation _frameAnimation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -371,15 +372,6 @@ CPTexturedBackgroundWindowMask
|
|||||||
[self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]];
|
[self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// give zero sized borderless bridge windows a default size if we're not in the browser so they show up in NativeHost.
|
|
||||||
if ((aStyleMask & CPBorderlessBridgeWindowMask) && aContentRect.size.width === 0 && aContentRect.size.height === 0)
|
|
||||||
{
|
|
||||||
var visibleFrame = [[[CPScreen alloc] init] visibleFrame];
|
|
||||||
_frame.size.height = MIN(768.0, visibleFrame.size.height);
|
|
||||||
_frame.size.width = MIN(1024.0, visibleFrame.size.width);
|
|
||||||
_frame.origin.x = (visibleFrame.size.width - _frame.size.width) / 2;
|
|
||||||
_frame.origin.y = (visibleFrame.size.height - _frame.size.height) / 2;
|
|
||||||
}
|
|
||||||
[self setPlatformWindow:[[CPPlatformWindow alloc] initWithContentRect:_frame]];
|
[self setPlatformWindow:[[CPPlatformWindow alloc] initWithContentRect:_frame]];
|
||||||
[self platformWindow]._only = self;
|
[self platformWindow]._only = self;
|
||||||
}
|
}
|
||||||
@@ -658,10 +650,9 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
if (shouldAnimate)
|
if (shouldAnimate)
|
||||||
{
|
{
|
||||||
[_frameAnimation stopAnimation];
|
var animation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
||||||
_frameAnimation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
|
||||||
|
|
||||||
[_frameAnimation startAnimation];
|
[animation startAnimation];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -742,10 +733,8 @@ CPTexturedBackgroundWindowMask
|
|||||||
*/
|
*/
|
||||||
- (void)orderFront:(id)aSender
|
- (void)orderFront:(id)aSender
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
|
||||||
[_platformWindow orderFront:self];
|
[_platformWindow orderFront:self];
|
||||||
[_platformWindow order:CPWindowAbove window:self relativeTo:nil];
|
[_platformWindow order:CPWindowAbove window:self relativeTo:nil];
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_firstResponder === self || !_firstResponder)
|
if (_firstResponder === self || !_firstResponder)
|
||||||
[self makeFirstResponder:[self initialFirstResponder]];
|
[self makeFirstResponder:[self initialFirstResponder]];
|
||||||
@@ -773,17 +762,13 @@ CPTexturedBackgroundWindowMask
|
|||||||
*/
|
*/
|
||||||
- (void)orderOut:(id)aSender
|
- (void)orderOut:(id)aSender
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
|
||||||
if ([self _sharesChromeWithPlatformWindow])
|
if ([self _sharesChromeWithPlatformWindow])
|
||||||
[_platformWindow orderOut:self];
|
[_platformWindow orderOut:self];
|
||||||
#endif
|
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:@selector(windowWillClose:)])
|
if ([_delegate respondsToSelector:@selector(windowWillClose:)])
|
||||||
[_delegate windowWillClose:self];
|
[_delegate windowWillClose:self];
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
|
||||||
[_platformWindow order:CPWindowOut window:self relativeTo:nil];
|
[_platformWindow order:CPWindowOut window:self relativeTo:nil];
|
||||||
#endif
|
|
||||||
|
|
||||||
[self _updateMainAndKeyWindows];
|
[self _updateMainAndKeyWindows];
|
||||||
}
|
}
|
||||||
@@ -795,9 +780,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
*/
|
*/
|
||||||
- (void)orderWindow:(CPWindowOrderingMode)aPlace relativeTo:(int)otherWindowNumber
|
- (void)orderWindow:(CPWindowOrderingMode)aPlace relativeTo:(int)otherWindowNumber
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
|
||||||
[_platformWindow order:aPlace window:self relativeTo:CPApp._windows[otherWindowNumber]];
|
[_platformWindow order:aPlace window:self relativeTo:CPApp._windows[otherWindowNumber]];
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -900,23 +883,6 @@ CPTexturedBackgroundWindowMask
|
|||||||
return _contentView;
|
return _contentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Applies an alpha value to the window.
|
|
||||||
@param aValue the alpha value to apply
|
|
||||||
*/
|
|
||||||
- (void)setAlphaValue:(float)aValue
|
|
||||||
{
|
|
||||||
[_windowView setAlphaValue:aValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the alpha value of the window.
|
|
||||||
*/
|
|
||||||
- (float)alphaValue
|
|
||||||
{
|
|
||||||
return [_windowView alphaValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the window's background color.
|
Sets the window's background color.
|
||||||
@param aColor the new color for the background
|
@param aColor the new color for the background
|
||||||
@@ -1359,21 +1325,10 @@ CPTexturedBackgroundWindowMask
|
|||||||
*/
|
*/
|
||||||
- (void)center
|
- (void)center
|
||||||
{
|
{
|
||||||
if (_isFullPlatformWindow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var size = [self frame].size,
|
var size = [self frame].size,
|
||||||
containerSize = [CPPlatform isBrowser] ? [_platformWindow contentBounds].size : [[self screen] visibleFrame].size;
|
containerSize = [CPPlatform isBrowser] ? [_platformWindow contentBounds].size : [[self screen] visibleFrame].size;
|
||||||
|
|
||||||
var origin = CGPointMake((containerSize.width - size.width) / 2.0, (containerSize.height - size.height) / 2.0);
|
[self setFrameOrigin:CGPointMake((containerSize.width - size.width) / 2.0, (containerSize.height - size.height) / 2.0)];
|
||||||
|
|
||||||
if (origin.x < 0.0)
|
|
||||||
origin.x = 0.0;
|
|
||||||
|
|
||||||
if (origin.y < 0.0)
|
|
||||||
origin.y = 0.0;
|
|
||||||
|
|
||||||
[self setFrameOrigin:origin];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1387,37 +1342,8 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case CPFlagsChanged: return [[self firstResponder] flagsChanged:anEvent];
|
|
||||||
|
|
||||||
case CPKeyUp: return [[self firstResponder] keyUp:anEvent];
|
case CPKeyUp: return [[self firstResponder] keyUp:anEvent];
|
||||||
|
case CPKeyDown: return [[self firstResponder] keyDown:anEvent];
|
||||||
case CPKeyDown: if ([anEvent charactersIgnoringModifiers] === CPTabCharacter)
|
|
||||||
{
|
|
||||||
if ([anEvent modifierFlags] & CPShiftKeyMask)
|
|
||||||
[self selectPreviousKeyView:self];
|
|
||||||
else
|
|
||||||
[self selectNextKeyView:self];
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ([anEvent charactersIgnoringModifiers] === CPBackTabCharacter)
|
|
||||||
return [self selectPreviousKeyView:self];
|
|
||||||
|
|
||||||
[[self firstResponder] keyDown:anEvent];
|
|
||||||
|
|
||||||
// Trigger the default button if needed
|
|
||||||
// FIXME: Is this only applicable in a sheet? See isse: #722.
|
|
||||||
if (![self disableKeyEquivalentForDefaultButton])
|
|
||||||
{
|
|
||||||
var defaultButton = [self defaultButton],
|
|
||||||
keyEquivalent = [defaultButton keyEquivalent],
|
|
||||||
modifierMask = [defaultButton keyEquivalentModifierMask];
|
|
||||||
|
|
||||||
if ([anEvent _triggersKeyEquivalent:keyEquivalent withModifierMask:modifierMask])
|
|
||||||
[[self defaultButton] performClick:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CPScrollWheel: return [[_windowView hitTest:point] scrollWheel:anEvent];
|
case CPScrollWheel: return [[_windowView hitTest:point] scrollWheel:anEvent];
|
||||||
|
|
||||||
@@ -1640,7 +1566,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
if (!pasteboardTypes)
|
if (!pasteboardTypes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[_inclusiveRegisteredDraggedTypes minusSet:pasteboardTypes];
|
[_inclusiveRegisteredDraggedTypes minusSet:pasteboardTypes]
|
||||||
|
|
||||||
if ([_inclusiveRegisteredDraggedTypes count] === 0)
|
if ([_inclusiveRegisteredDraggedTypes count] === 0)
|
||||||
_inclusiveRegisteredDraggedTypes = nil;
|
_inclusiveRegisteredDraggedTypes = nil;
|
||||||
@@ -1671,7 +1597,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
[self _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
|
[self _noteUnregisteredDraggedTypes:_registeredDraggedTypes];
|
||||||
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes];
|
[_registeredDraggedTypes addObjectsFromArray:pasteboardTypes]
|
||||||
[self _noteRegisteredDraggedTypes:_registeredDraggedTypes];
|
[self _noteRegisteredDraggedTypes:_registeredDraggedTypes];
|
||||||
|
|
||||||
_registeredDraggedTypesArray = nil;
|
_registeredDraggedTypesArray = nil;
|
||||||
@@ -1684,7 +1610,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
- (CPArray)registeredDraggedTypes
|
- (CPArray)registeredDraggedTypes
|
||||||
{
|
{
|
||||||
if (!_registeredDraggedTypesArray)
|
if (!_registeredDraggedTypesArray)
|
||||||
_registeredDraggedTypesArray = [_registeredDraggedTypes allObjects];
|
_registeredDraggedTypesArray = [_registeredDraggedTypes allObjects]
|
||||||
|
|
||||||
return _registeredDraggedTypesArray;
|
return _registeredDraggedTypesArray;
|
||||||
}
|
}
|
||||||
@@ -1981,17 +1907,10 @@ CPTexturedBackgroundWindowMask
|
|||||||
[keyWindow makeKeyWindow];
|
[keyWindow makeKeyWindow];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var mainMenu = [CPApp mainMenu],
|
var menuWindow = [CPApp mainMenu]._menuWindow;
|
||||||
menuBarClass = objj_getClass("_CPMenuBarWindow"),
|
|
||||||
menuWindow;
|
|
||||||
|
|
||||||
for (var i = 0; i < windowCount; i++)
|
for (var i = 0; i < windowCount; i++)
|
||||||
{
|
{
|
||||||
var currentWindow = allWindows[i];
|
var currentWindow = allWindows[i];
|
||||||
|
|
||||||
if ([currentWindow isKindOfClass:menuBarClass])
|
|
||||||
menuWindow = currentWindow;
|
|
||||||
|
|
||||||
if (currentWindow === self || currentWindow === menuWindow)
|
if (currentWindow === self || currentWindow === menuWindow)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -2016,17 +1935,10 @@ CPTexturedBackgroundWindowMask
|
|||||||
[mainWindow makeMainWindow];
|
[mainWindow makeMainWindow];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var mainMenu = [CPApp mainMenu],
|
var menuWindow = [CPApp mainMenu]._menuWindow;
|
||||||
menuBarClass = objj_getClass("_CPMenuBarWindow"),
|
|
||||||
menuWindow;
|
|
||||||
|
|
||||||
for (var i = 0; i < windowCount; i++)
|
for (var i = 0; i < windowCount; i++)
|
||||||
{
|
{
|
||||||
var currentWindow = allWindows[i];
|
var currentWindow = allWindows[i];
|
||||||
|
|
||||||
if ([currentWindow isKindOfClass:menuBarClass])
|
|
||||||
menuWindow = currentWindow;
|
|
||||||
|
|
||||||
if (currentWindow === self || currentWindow === menuWindow)
|
if (currentWindow === self || currentWindow === menuWindow)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -2106,17 +2018,11 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
- (void)_setFrame:(CGRect)aFrame delegate:(id)delegate duration:(int)duration curve:(CPAnimationCurve)curve
|
- (void)_setFrame:(CGRect)aFrame delegate:(id)delegate duration:(int)duration curve:(CPAnimationCurve)curve
|
||||||
{
|
{
|
||||||
[_frameAnimation stopAnimation];
|
var animation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
||||||
_frameAnimation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:aFrame];
|
[animation setDelegate:delegate];
|
||||||
[_frameAnimation setDelegate:delegate];
|
[animation setAnimationCurve:curve];
|
||||||
[_frameAnimation setAnimationCurve:curve];
|
[animation setDuration:duration];
|
||||||
[_frameAnimation setDuration:duration];
|
[animation startAnimation];
|
||||||
[_frameAnimation startAnimation];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CPTimeInterval)animationResizeTime:(CGRect)newWindowFrame
|
|
||||||
{
|
|
||||||
return CPWindowResizeTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @ignore */
|
/* @ignore */
|
||||||
@@ -2167,7 +2073,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
[aSheet setFrame:startFrame display:YES animate:NO];
|
[aSheet setFrame:startFrame display:YES animate:NO];
|
||||||
_sheetContext["opened"] = YES;
|
_sheetContext["opened"] = YES;
|
||||||
|
|
||||||
[aSheet _setFrame:endFrame delegate:self duration:[self animationResizeTime:endFrame] curve:CPAnimationEaseOut];
|
[aSheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseOut];
|
||||||
|
|
||||||
// Should run the main loop here until _isAnimating = FALSE
|
// Should run the main loop here until _isAnimating = FALSE
|
||||||
[aSheet becomeKeyWindow];
|
[aSheet becomeKeyWindow];
|
||||||
@@ -2188,7 +2094,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
[self _setUpMasksForView:sheetContent];
|
[self _setUpMasksForView:sheetContent];
|
||||||
|
|
||||||
_sheetContext["opened"] = NO;
|
_sheetContext["opened"] = NO;
|
||||||
[sheet _setFrame:endFrame delegate:self duration:[self animationResizeTime:endFrame] curve:CPAnimationEaseIn];
|
[sheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseIn];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @ignore */
|
/* @ignore */
|
||||||
@@ -2217,15 +2123,13 @@ CPTexturedBackgroundWindowMask
|
|||||||
[self _restoreMasksForView:sheetContent];
|
[self _restoreMasksForView:sheetContent];
|
||||||
|
|
||||||
var delegate = _sheetContext["modalDelegate"],
|
var delegate = _sheetContext["modalDelegate"],
|
||||||
endSelector = _sheetContext["endSelector"],
|
endSelector = _sheetContext["endSelector"];
|
||||||
returnCode = _sheetContext["returnCode"],
|
|
||||||
contextInfo = _sheetContext["contextInfo"];
|
if (delegate != nil && endSelector != nil)
|
||||||
|
objj_msgSend(delegate, endSelector, sheet, _sheetContext["returnCode"], _sheetContext["contextInfo"]);
|
||||||
|
|
||||||
_sheetContext = nil;
|
_sheetContext = nil;
|
||||||
sheet._parentView = nil;
|
sheet._parentView = nil;
|
||||||
|
|
||||||
if (delegate != nil && endSelector != nil)
|
|
||||||
objj_msgSend(delegate, endSelector, sheet, returnCode, contextInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_setUpMasksForView:(CPView)aView
|
- (void)_setUpMasksForView:(CPView)aView
|
||||||
@@ -2298,7 +2202,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
|
- (void)performKeyEquivalent:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
// FIXME: should we be starting at the root, in other words _windowView?
|
// FIXME: should we be starting at the root, in other words _windowView?
|
||||||
// The evidence seems to point to no...
|
// The evidence seems to point to no...
|
||||||
@@ -2309,92 +2213,19 @@ CPTexturedBackgroundWindowMask
|
|||||||
{
|
{
|
||||||
// It's not clear why we do performKeyEquivalent again here...
|
// It's not clear why we do performKeyEquivalent again here...
|
||||||
// Perhaps to allow something to happen between sendEvent: and keyDown:?
|
// Perhaps to allow something to happen between sendEvent: and keyDown:?
|
||||||
if ([anEvent _couldBeKeyEquivalent] && [self performKeyEquivalent:anEvent])
|
if (![anEvent _couldBeKeyEquivalent] || ![self performKeyEquivalent:anEvent])
|
||||||
return;
|
[self interpretKeyEvents:[anEvent]];
|
||||||
|
|
||||||
// Apple's documentation is inconsistent with their behavior here. According to the docs
|
|
||||||
// an event going of the responder chain is passed to the input system as a last resort.
|
|
||||||
// However, the only methods I could get Cocoa to call automatically are
|
|
||||||
// moveUp: moveDown: moveLeft: moveRight: pageUp: pageDown: and complete:
|
|
||||||
[self _processKeyboardUIKey:anEvent];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
- (void)insertNewline:(id)sender
|
||||||
@ignore
|
|
||||||
Interprets the key event for action messages and sends the action message down the responder chain
|
|
||||||
Cocoa only sends moveDown:, moveUp:, moveLeft:, moveRight:, pageUp:, pageDown: and complete: messages.
|
|
||||||
We deviate from this by sending (the default) scrollPageUp: scrollPageDown: for pageUp and pageDown keys.
|
|
||||||
@param anEvent the event to handle.
|
|
||||||
@return YES if the key event was handled, NO if no responder handled the key event
|
|
||||||
*/
|
|
||||||
- (BOOL)_processKeyboardUIKey:(CPEvent)anEvent
|
|
||||||
{
|
{
|
||||||
var character = [anEvent charactersIgnoringModifiers],
|
if (_defaultButton && _defaultButtonEnabled)
|
||||||
uiKeys = [CPLeftArrowFunctionKey, CPRightArrowFunctionKey, CPUpArrowFunctionKey, CPDownArrowFunctionKey, CPPageUpFunctionKey, CPPageDownFunctionKey, CPEscapeFunctionKey];
|
[_defaultButton performClick:nil];
|
||||||
|
|
||||||
if (![uiKeys containsObject:character])
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
var selectors = [CPKeyBinding selectorsForKey:character modifierFlags:0];
|
|
||||||
|
|
||||||
if ([selectors count] <= 0)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
if (character !== CPEscapeFunctionKey)
|
|
||||||
{
|
|
||||||
var selector = [selectors objectAtIndex:0];
|
|
||||||
return [[self firstResponder] tryToPerform:selector with:self];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Cocoa sends complete: for the escape key (in stead of the default cancelOperation:)
|
|
||||||
// This is also the only action that is not sent directly to the first responder, but through doCommandBySelector.
|
|
||||||
// The difference is that doCommandBySelector: will also send the action to the window and application delegates.
|
|
||||||
[[self firstResponder] doCommandBySelector:@selector(complete:)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
- (void)insertTab:(id)sender
|
||||||
@ignore
|
|
||||||
Interprets the key event for action messages and sends the action message down the responder chain
|
|
||||||
Cocoa only sends moveDown:, moveUp:, moveLeft:, moveRight:, pageUp:, pageDown: and complete: messages.
|
|
||||||
We deviate from this by sending (the default) scrollPageUp: scrollPageDown: for pageUp and pageDown keys.
|
|
||||||
@param anEvent the event to handle.
|
|
||||||
@return YES if the key event was handled, NO if no responder handled the key event
|
|
||||||
*/
|
|
||||||
- (BOOL)_processKeyboardUIKey:(CPEvent)anEvent
|
|
||||||
{
|
{
|
||||||
var character = [anEvent charactersIgnoringModifiers],
|
[self selectNextKeyView:nil];
|
||||||
uiKeys = [
|
|
||||||
CPLeftArrowFunctionKey,
|
|
||||||
CPRightArrowFunctionKey,
|
|
||||||
CPUpArrowFunctionKey,
|
|
||||||
CPDownArrowFunctionKey,
|
|
||||||
CPPageUpFunctionKey,
|
|
||||||
CPPageDownFunctionKey,
|
|
||||||
CPEscapeFunctionKey
|
|
||||||
];
|
|
||||||
|
|
||||||
if (![uiKeys containsObject:character])
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
var selectors = [CPKeyBinding selectorsForKey:character modifierFlags:0];
|
|
||||||
|
|
||||||
if ([selectors count] <= 0)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
if (character !== CPEscapeFunctionKey)
|
|
||||||
{
|
|
||||||
var selector = [selectors objectAtIndex:0];
|
|
||||||
return [[self firstResponder] tryToPerform:selector with:self];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Cocoa sends complete: for the escape key (in stead of the default cancelOperation:)
|
|
||||||
// This is also the only action that is not sent directly to the first responder, but through doCommandBySelector.
|
|
||||||
// The difference is that doCommandBySelector: will also send the action to the window and application delegates.
|
|
||||||
[[self firstResponder] doCommandBySelector:@selector(complete:)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_dirtyKeyViewLoop
|
- (void)_dirtyKeyViewLoop
|
||||||
@@ -2502,16 +2333,11 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
- (void)setDefaultButton:(CPButton)aButton
|
- (void)setDefaultButton:(CPButton)aButton
|
||||||
{
|
{
|
||||||
if (_defaultButton === aButton)
|
[_defaultButton setDefaultButton:NO];
|
||||||
return;
|
|
||||||
|
|
||||||
if ([_defaultButton keyEquivalent] === CPCarriageReturnCharacter)
|
|
||||||
[_defaultButton setKeyEquivalent:nil];
|
|
||||||
|
|
||||||
_defaultButton = aButton;
|
_defaultButton = aButton;
|
||||||
|
|
||||||
if ([_defaultButton keyEquivalent] !== CPCarriageReturnCharacter)
|
[_defaultButton setDefaultButton:YES];
|
||||||
[_defaultButton setKeyEquivalent:CPCarriageReturnCharacter];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPButton)defaultButton
|
- (CPButton)defaultButton
|
||||||
@@ -2772,7 +2598,7 @@ var interpolate = function(fromValue, toValue, progress)
|
|||||||
|
|
||||||
- (id)initWithWindow:(CPWindow)aWindow targetFrame:(CGRect)aTargetFrame
|
- (id)initWithWindow:(CPWindow)aWindow targetFrame:(CGRect)aTargetFrame
|
||||||
{
|
{
|
||||||
self = [super initWithDuration:[aWindow animationResizeTime:aTargetFrame] animationCurve:CPAnimationLinear];
|
self = [super initWithDuration:0.2 animationCurve:CPAnimationLinear];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,21 +43,21 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
|||||||
|
|
||||||
_CPHUDWindowViewBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
|
_CPHUDWindowViewBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
|
||||||
[
|
[
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground0.png"] size:CPSizeMake(7.0, 37.0)],
|
[[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, 37.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(7.0, 37.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(6.0, 78.0)],
|
||||||
|
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(7.0, 1.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(2.0, 2.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(7.0, 1.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(6.0, 1.0)],
|
||||||
|
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(7.0, 3.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(1.0, 3.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(7.0, 3.0)]
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground8.png"] size:CPSizeMake(6.0, 6.0)]
|
||||||
]]];
|
]]];
|
||||||
|
|
||||||
_CPHUDWindowViewCloseImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowClose.png"] size:CPSizeMake(18.0, 18.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(18.0, 18.0)];
|
_CPHUDWindowViewCloseActiveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowCloseActive.png"] size:CPSizeMake(20.0, 20.0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||||
@@ -148,7 +148,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
|||||||
{
|
{
|
||||||
var closeSize = [_CPHUDWindowViewCloseImage size];
|
var closeSize = [_CPHUDWindowViewCloseImage size];
|
||||||
|
|
||||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 5.0, closeSize.width, closeSize.height)];
|
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(4.0, 4.0, closeSize.width, closeSize.height)];
|
||||||
|
|
||||||
[_closeButton setBordered:NO];
|
[_closeButton setBordered:NO];
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
@import "_CPWindowView.j"
|
@import "_CPWindowView.j"
|
||||||
|
|
||||||
|
|
||||||
var GRADIENT_HEIGHT = 41.0;
|
var GRADIENT_HEIGHT = 41.0;
|
||||||
|
|
||||||
var _CPTexturedWindowHeadGradientColor = nil,
|
var _CPTexturedWindowHeadGradientColor = nil,
|
||||||
|
|||||||
@@ -20,8 +20,10 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CPImageView.j"
|
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
@import "CPImageView.j"
|
||||||
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
|
||||||
|
|
||||||
var _CPWindowViewResizeIndicatorImage = nil;
|
var _CPWindowViewResizeIndicatorImage = nil;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
@import "CPWindow.j"
|
@import "CPWindow.j"
|
||||||
@import "CPDocument.j"
|
@import "CPDocument.j"
|
||||||
|
|
||||||
|
#include "Platform/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@@ -131,7 +133,7 @@
|
|||||||
if (_window)
|
if (_window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[[CPBundle mainBundle] loadCibFile:[self windowCibPath] externalNameTable:[CPDictionary dictionaryWithObject:_cibOwner forKey:CPCibOwner]];
|
[[CPBundle bundleForClass:[_cibOwner class]] loadCibFile:[self windowCibPath] externalNameTable:[CPDictionary dictionaryWithObject:_cibOwner forKey:CPCibOwner]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -422,7 +424,7 @@
|
|||||||
if (_windowCibPath)
|
if (_windowCibPath)
|
||||||
return _windowCibPath;
|
return _windowCibPath;
|
||||||
|
|
||||||
return [[CPBundle mainBundle] pathForResource:_windowCibName + @".cib"];
|
return [[CPBundle bundleForClass:[_cibOwner class]] pathForResource:_windowCibName + @".cib"];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting and Getting Window Attributes
|
// Setting and Getting Window Attributes
|
||||||
|
|||||||
+1
-1
@@ -150,7 +150,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
|
|||||||
|
|
||||||
var topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
|
var topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
|
||||||
|
|
||||||
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects];
|
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects]
|
||||||
[objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
|
[objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
|
||||||
[objectData awakeWithOwner:owner topLevelObjects:topLevelObjects];
|
[objectData awakeWithOwner:owner topLevelObjects:topLevelObjects];
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,9 @@
|
|||||||
|
|
||||||
// Not having a selector is a fatal error.
|
// Not having a selector is a fatal error.
|
||||||
if (!selector)
|
if (!selector)
|
||||||
{
|
|
||||||
[CPException
|
[CPException
|
||||||
raise:CPInvalidArgumentException
|
raise:CPInvalidArgumentException
|
||||||
reason:@"-[" + [self className] + ' ' + _cmd + @"] selector " + selectorName + @" does not exist."];
|
reason:@"-[" + [self className] + ' ' + _cmd + @"] selector " + selectorName + @" does not exist."];
|
||||||
}
|
|
||||||
|
|
||||||
// If the destination doesn't respond to this selector, warn but don't die.
|
// If the destination doesn't respond to this selector, warn but don't die.
|
||||||
if (_destination && ![_destination respondsToSelector:selector])
|
if (_destination && ![_destination respondsToSelector:selector])
|
||||||
@@ -60,7 +58,7 @@
|
|||||||
else
|
else
|
||||||
[CPException
|
[CPException
|
||||||
raise:CPInvalidArgumentException
|
raise:CPInvalidArgumentException
|
||||||
reason:@"-[" + [self className] + ' ' + _cmd + @"] " + [_source description] + @" does not respond to setAction:"];
|
reason:@"-[" + [self className] + ' ' + _cmd + @"] " + [_source description] + " does not respond to setAction:"];
|
||||||
|
|
||||||
// Not being able to set the target is a fatal error.
|
// Not being able to set the target is a fatal error.
|
||||||
if ([_source respondsToSelector:@selector(setTarget:)])
|
if ([_source respondsToSelector:@selector(setTarget:)])
|
||||||
@@ -69,14 +67,10 @@
|
|||||||
else
|
else
|
||||||
[CPException
|
[CPException
|
||||||
raise:CPInvalidArgumentException
|
raise:CPInvalidArgumentException
|
||||||
reason:@"-[" + [self className] + ' ' + _cmd + @"] " + [_source description] + @" does not respond to setTarget:"];
|
reason:@"-[" + [self className] + ' ' + _cmd + @"] " + [_source description] + " does not respond to setTarget:"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation _CPCibControlConnector : CPCibControlConnector
|
@implementation _CPCibControlConnector : CPCibControlConnector { } @end
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -37,12 +37,12 @@ var CPCibOwner = @"CPCibOwner";
|
|||||||
|
|
||||||
@implementation CPBundle (CPCibLoading)
|
@implementation CPBundle (CPCibLoading)
|
||||||
|
|
||||||
+ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable
|
+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable
|
||||||
{
|
{
|
||||||
return [[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable];
|
[[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner
|
+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner
|
||||||
{
|
{
|
||||||
if (![aName hasSuffix:@".cib"])
|
if (![aName hasSuffix:@".cib"])
|
||||||
aName = [aName stringByAppendingString:@".cib"];
|
aName = [aName stringByAppendingString:@".cib"];
|
||||||
@@ -51,24 +51,24 @@ var CPCibOwner = @"CPCibOwner";
|
|||||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
||||||
path = [bundle pathForResource:aName];
|
path = [bundle pathForResource:aName];
|
||||||
|
|
||||||
return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
|
[self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
|
- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
|
||||||
{
|
{
|
||||||
return [[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable];
|
[[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
|
+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
|
||||||
{
|
{
|
||||||
return ([[CPCib alloc]
|
[[CPCib alloc]
|
||||||
initWithContentsOfURL:anAbsolutePath
|
initWithContentsOfURL:anAbsolutePath
|
||||||
loadDelegate:[[_CPCibLoadDelegate alloc]
|
loadDelegate:[[_CPCibLoadDelegate alloc]
|
||||||
initWithLoadDelegate:aDelegate
|
initWithLoadDelegate:aDelegate
|
||||||
externalNameTable:aNameTable]]);
|
externalNameTable:aNameTable]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
|
+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
if (![aName hasSuffix:@".cib"])
|
if (![aName hasSuffix:@".cib"])
|
||||||
aName = [aName stringByAppendingString:@".cib"];
|
aName = [aName stringByAppendingString:@".cib"];
|
||||||
@@ -77,17 +77,17 @@ var CPCibOwner = @"CPCibOwner";
|
|||||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
||||||
path = [bundle pathForResource:aName];
|
path = [bundle pathForResource:aName];
|
||||||
|
|
||||||
return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
|
[self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
|
- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
return ([[CPCib alloc]
|
[[CPCib alloc]
|
||||||
initWithCibNamed:aFileName
|
initWithCibNamed:aFileName
|
||||||
bundle:self
|
bundle:self
|
||||||
loadDelegate:[[_CPCibLoadDelegate alloc]
|
loadDelegate:[[_CPCibLoadDelegate alloc]
|
||||||
initWithLoadDelegate:aDelegate
|
initWithLoadDelegate:aDelegate
|
||||||
externalNameTable:aNameTable]]);
|
externalNameTable:aNameTable]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -112,14 +112,4 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned)loadStatus
|
|
||||||
{
|
|
||||||
return CPImageLoadStatusCompleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)delegate
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
@import "CGGeometry.j"
|
|
||||||
@import "CPWindow.j"
|
|
||||||
|
|
||||||
|
|
||||||
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
|
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
|
||||||
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
|
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
|
||||||
|
|||||||
@@ -22,10 +22,13 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
@import "CABackingStore.j"
|
@import <AppKit/CABackingStore.j>
|
||||||
|
|
||||||
@import "CGContext.j"
|
@import <AppKit/CGContext.j>
|
||||||
@import "CGGeometry.j"
|
@import <AppKit/CGGeometry.j>
|
||||||
|
|
||||||
|
#include "../CoreGraphics/CGGeometry.h"
|
||||||
|
#include "../CoreGraphics/CGAffineTransform.j"
|
||||||
|
|
||||||
|
|
||||||
#define DOM(aLayer) aLayer._DOMElement
|
#define DOM(aLayer) aLayer._DOMElement
|
||||||
|
|||||||
@@ -20,11 +20,14 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CGGeometry.j"
|
#include "CGGeometry.h"
|
||||||
|
#include "CGAffineTransform.h"
|
||||||
|
|
||||||
#define _function(inline) function inline { return _##inline; }
|
#define _function(inline) function inline { return _##inline; }
|
||||||
|
|
||||||
|
@import "CGGeometry.j"
|
||||||
|
|
||||||
|
|
||||||
_function(CGAffineTransformMake(a, b, c, d, tx, ty))
|
_function(CGAffineTransformMake(a, b, c, d, tx, ty))
|
||||||
_function(CGAffineTransformMakeIdentity())
|
_function(CGAffineTransformMakeIdentity())
|
||||||
_function(CGAffineTransformMakeCopy(anAffineTransform))
|
_function(CGAffineTransformMakeCopy(anAffineTransform))
|
||||||
|
|||||||
@@ -20,11 +20,12 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "CGAffineTransform.j"
|
#include "CGGeometry.h"
|
||||||
@import "CPCompatibility.j"
|
#include "CGAffineTransform.h"
|
||||||
@import "CGGeometry.j"
|
|
||||||
@import "CGPath.j"
|
|
||||||
|
|
||||||
|
@import "CGGeometry.j"
|
||||||
|
@import "CGAffineTransform.j"
|
||||||
|
@import "CGPath.j"
|
||||||
|
|
||||||
kCGLineCapButt = 0;
|
kCGLineCapButt = 0;
|
||||||
kCGLineCapRound = 1;
|
kCGLineCapRound = 1;
|
||||||
|
|||||||
@@ -63,7 +63,6 @@
|
|||||||
#define _CGInsetMakeCopy(anInset) _CGInsetMake(anInset.top, anInset.right, anInset.bottom, anInset.left)
|
#define _CGInsetMakeCopy(anInset) _CGInsetMake(anInset.top, anInset.right, anInset.bottom, anInset.left)
|
||||||
#define _CGInsetMakeZero() _CGInsetMake(0, 0, 0, 0)
|
#define _CGInsetMakeZero() _CGInsetMake(0, 0, 0, 0)
|
||||||
#define _CGInsetIsEmpty(anInset) ((anInset).top === 0 && (anInset).right === 0 && (anInset).bottom === 0 && (anInset).left === 0)
|
#define _CGInsetIsEmpty(anInset) ((anInset).top === 0 && (anInset).right === 0 && (anInset).bottom === 0 && (anInset).left === 0)
|
||||||
#define _CGInsetEqualToInset(lhsInset, rhsInset) ((lhsInset).top === (rhsInset).top && (lhsInset).right === (rhsInset).right && (lhsInset).bottom === (rhsInset).bottom && (lhsInset).left === (rhsInset).left)
|
|
||||||
|
|
||||||
// DEPRECATED
|
// DEPRECATED
|
||||||
#define _CGPointCreateCopy(aPoint) _CGPointMake(aPoint.x, aPoint.y)
|
#define _CGPointCreateCopy(aPoint) _CGPointMake(aPoint.x, aPoint.y)
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "CGGeometry.h"
|
||||||
|
|
||||||
#define _function(inline) function inline { return _##inline; }
|
#define _function(inline) function inline { return _##inline; }
|
||||||
|
|
||||||
_function(CGPointMake(x, y))
|
_function(CGPointMake(x, y))
|
||||||
@@ -67,12 +69,6 @@ _function(CGInsetMake(top, right, bottom, left))
|
|||||||
_function(CGInsetMakeZero())
|
_function(CGInsetMakeZero())
|
||||||
_function(CGInsetMakeCopy(anInset))
|
_function(CGInsetMakeCopy(anInset))
|
||||||
_function(CGInsetIsEmpty(anInset))
|
_function(CGInsetIsEmpty(anInset))
|
||||||
_function(CGInsetEqualToInset(lhsInset, rhsInset))
|
|
||||||
|
|
||||||
CGMinXEdge = 0;
|
|
||||||
CGMinYEdge = 1;
|
|
||||||
CGMaxXEdge = 2;
|
|
||||||
CGMaxYEdge = 3;
|
|
||||||
|
|
||||||
CGRectNull = _CGRectMake(Infinity, Infinity, 0.0, 0.0);
|
CGRectNull = _CGRectMake(Infinity, Infinity, 0.0, 0.0);
|
||||||
|
|
||||||
@@ -81,50 +77,6 @@ CGRectNull = _CGRectMake(Infinity, Infinity, 0.0, 0.0);
|
|||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
Creates two rectangles -- slice and rem -- from inRect, by dividing inRect
|
|
||||||
with a line that's parallel to the side of inRect specified by edge.
|
|
||||||
The size of slice is determined by amount, which specifies the distance from edge.
|
|
||||||
|
|
||||||
slice and rem must not be NULL, must not be the same object, and must not be the
|
|
||||||
same object as inRect.
|
|
||||||
|
|
||||||
@group CGRect
|
|
||||||
*/
|
|
||||||
function CGRectDivide(inRect, slice, rem, amount, edge)
|
|
||||||
{
|
|
||||||
slice.origin = _CGPointMakeCopy(inRect.origin);
|
|
||||||
slice.size = _CGSizeMakeCopy(inRect.size);
|
|
||||||
rem.origin = _CGPointMakeCopy(inRect.origin);
|
|
||||||
rem.size = _CGSizeMakeCopy(inRect.size);
|
|
||||||
|
|
||||||
switch (edge)
|
|
||||||
{
|
|
||||||
case CGMinXEdge:
|
|
||||||
slice.size.width = amount;
|
|
||||||
rem.origin.x += amount;
|
|
||||||
rem.size.width -= amount;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CGMaxXEdge:
|
|
||||||
slice.origin.x = _CGRectGetMaxX(slice) - amount;
|
|
||||||
slice.size.width = amount;
|
|
||||||
rem.size.width -= amount;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CGMinYEdge:
|
|
||||||
slice.size.height = amount;
|
|
||||||
rem.origin.y += amount;
|
|
||||||
rem.size.height -= amount;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CGMaxYEdge:
|
|
||||||
slice.origin.y = _CGRectGetMaxY(slice) - amount;
|
|
||||||
slice.size.height = amount;
|
|
||||||
rem.size.height -= amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a \c BOOL indicating whether CGRect \c lhsRect
|
Returns a \c BOOL indicating whether CGRect \c lhsRect
|
||||||
contains CGRect \c rhsRect.
|
contains CGRect \c rhsRect.
|
||||||
|
|||||||
@@ -29,9 +29,6 @@ kCGGradientDrawsAfterEndLocation = 1 << 1;
|
|||||||
|
|
||||||
function CGGradientCreateWithColorComponents(aColorSpace, components, locations, count)
|
function CGGradientCreateWithColorComponents(aColorSpace, components, locations, count)
|
||||||
{
|
{
|
||||||
if (arguments["locations"] == NULL)
|
|
||||||
var locations = [0.0, 1.0];
|
|
||||||
|
|
||||||
if (arguments["count"] == NULL)
|
if (arguments["count"] == NULL)
|
||||||
var count = locations.length;
|
var count = locations.length;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user