Merge branch 'master' of https://github.com/cappuccino/cappuccino into binding_support_popup_button

Conflicts:
	AppKit/CPKeyValueBinding.j
	AppKit/CPPopUpButton.j
	Tests/AppKit/CPPopUpButtonTest.j
This commit is contained in:
Martin Carlberg
2012-07-23 11:19:21 +02:00
243 changed files with 22298 additions and 17365 deletions
+5 -4
View File
@@ -20,7 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPToolTip.j"
@import "CALayer.j"
@import "CGGeometry.j"
@import "CPAccordionView.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@@ -36,10 +38,10 @@
@import "CPCibBindingConnector.j"
@import "CPCibConnector.j"
@import "CPCibControlConnector.j"
@import "CPCibHelpConnector.j"
@import "CPCibLoading.j"
@import "CPCibOutletConnector.j"
@import "CPCibRuntimeAttributesConnector.j"
@import "CPCibHelpConnector.j"
@import "CPClipView.j"
@import "CPCollectionView.j"
@import "CPCollectionViewItem.j"
@@ -47,6 +49,7 @@
@import "CPColorPanel.j"
@import "CPColorSpace.j"
@import "CPColorWell.j"
@import "CPComboBox.j"
@import "CPCompatibility.j"
@import "CPControl.j"
@import "CPController.j"
@@ -59,7 +62,6 @@
@import "CPFlashView.j"
@import "CPFont.j"
@import "CPFontManager.j"
@import "CPGeometry.j"
@import "CPGradient.j"
@import "CPGraphics.j"
@import "CPImage.j"
@@ -98,13 +100,12 @@
@import "CPTokenField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
@import "_CPToolTip.j"
@import "CPTreeNode.j"
@import "CPUserDefaultsController.j"
@import "CPView.j"
@import "CPViewAnimation.j"
@import "CPViewController.j"
@import "CPWebView.j"
@import "CPWorkspace.j"
@import "CPWindow.j"
@import "CPWindowController.j"
@import "CPWorkspace.j"
+13 -3
View File
@@ -254,7 +254,7 @@ CPRunContinuesResponse = -1002;
count = [URLStrings count];
for (; index < count; ++index)
needsUntitled = ![self _openURL:[CPURL URLWithString:URLStrings[index]]] || needsUntitled;
needsUntitled = ![self _openURL:[CPURL URLWithString:URLStrings[index]]] && needsUntitled;
if (needsUntitled && [_delegate respondsToSelector:@selector(applicationShouldOpenUntitledFile:)])
needsUntitled = [_delegate applicationShouldOpenUntitledFile:self];
@@ -373,7 +373,7 @@ CPRunContinuesResponse = -1002;
standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
// FIXME move this into the CIB eventually
[applicationLabel setFont:[CPFont boldSystemFontOfSize:14.0]];
[applicationLabel setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 2]];
[applicationLabel setAlignment:CPCenterTextAlignment];
[versionLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setAlignment:CPCenterTextAlignment];
@@ -576,27 +576,33 @@ CPRunContinuesResponse = -1002;
{
_currentEvent = anEvent;
#if PLATFORM(DOM)
var willPropagate = [[[anEvent window] platformWindow] _willPropagateCurrentDOMEvent];
// temporarily pretend we won't propagate the event. we'll restore the saved value later
// we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
{
#if PLATFORM(DOM)
var characters = [anEvent characters],
modifierFlags = [anEvent modifierFlags];
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
#endif
return;
}
#if PLATFORM(DOM)
// if we make it this far, then restore the original willPropagate value
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:willPropagate];
#endif
if (_eventListeners.length)
{
@@ -1180,7 +1186,11 @@ _CPRunModalLoop = function(anEvent)
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
if (theWindow == modalSession._window || [theWindow worksWhenModal])
// The special case for popovers here is not clear. In Cocoa the popover window does not respond YES to worksWhenModal,
// yet it works when there is a modal window. Maybe it starts its own modal session, but interaction with the original
// modal window seems to continue working as well. Regardless of correctness, this solution beats popovers not working
// at all from sheets.
if (theWindow == modalSession._window || [theWindow worksWhenModal] || ([theWindow isKindOfClass:_CPAttachedWindow] && [[theWindow targetView] window] === modalSession._window))
[theWindow sendEvent:anEvent];
};
+3
View File
@@ -879,6 +879,9 @@
[_arrangedObjects removeObjectAtIndex:pos];
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
// This will automatically handle the avoidsEmptySelection case.
[self __setSelectionIndexes:_selectionIndexes];
}
[self didChangeValueForKey:@"content"];
+17 -33
View File
@@ -29,20 +29,21 @@
/* @group CPBezelStyle */
CPRoundedBezelStyle = 1;
CPRegularSquareBezelStyle = 2;
// IB style
CPRoundedBezelStyle = 1; // Push
CPRegularSquareBezelStyle = 2; // Bevel
CPThickSquareBezelStyle = 3;
CPThickerSquareBezelStyle = 4;
CPDisclosureBezelStyle = 5;
CPShadowlessSquareBezelStyle = 6;
CPCircularBezelStyle = 7;
CPTexturedSquareBezelStyle = 8;
CPHelpButtonBezelStyle = 9;
CPSmallSquareBezelStyle = 10;
CPTexturedRoundedBezelStyle = 11;
CPRoundRectBezelStyle = 12;
CPRecessedBezelStyle = 13;
CPRoundedDisclosureBezelStyle = 14;
CPDisclosureBezelStyle = 5; // Disclosure triangle
CPShadowlessSquareBezelStyle = 6; // Square
CPCircularBezelStyle = 7; // Round
CPTexturedSquareBezelStyle = 8; // Textured
CPHelpButtonBezelStyle = 9; // Help
CPSmallSquareBezelStyle = 10; // Gradient
CPTexturedRoundedBezelStyle = 11; // Round Textured
CPRoundRectBezelStyle = 12; // Round Rect
CPRecessedBezelStyle = 13; // Recessed
CPRoundedDisclosureBezelStyle = 14; // Disclosure
CPHUDBezelStyle = -1;
@@ -576,35 +577,18 @@ CPButtonImageOffset = 3.0;
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
if (_CGInsetIsEmpty(contentInset))
return bounds;
bounds = _CGRectMakeCopy(bounds);
bounds.origin.x += contentInset.left;
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
// Is this necessary? The theme itself can just change its inset to a zero inset when !CPThemeStateBordered.
if (![self isBordered])
return _CGRectMakeZero();
return bounds;
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (_CGInsetIsEmpty(bezelInset))
return bounds;
bounds = _CGRectMakeCopy(bounds);
bounds.origin.x += bezelInset.left;
bounds.origin.y += bezelInset.top;
bounds.size.width -= bezelInset.left + bezelInset.right;
bounds.size.height -= bezelInset.top + bezelInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGSize)_minimumFrameSize
+37 -36
View File
@@ -144,7 +144,7 @@ CPColorPickerViewHeight = 370;
- (void)setColor:(CPColor)aColor
{
_color = aColor;
[_previewView setBackgroundColor: _color];
[_previewView setBackgroundColor:_color];
[CPApp sendAction:@selector(changeColor:) to:nil from:self];
@@ -299,7 +299,7 @@ CPColorPickerViewHeight = 370;
bounds = [contentView bounds];
_toolbar = [[CPView alloc] initWithFrame:CGRectMake(0, 6, CGRectGetWidth(bounds), TOOLBAR_HEIGHT)];
[_toolbar setAutoresizingMask: CPViewWidthSizable];
[_toolbar setAutoresizingMask:CPViewWidthSizable];
var totalToolbarWidth = count * ICON_WIDTH + (count - 1) * ICON_PADDING,
leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
@@ -339,7 +339,7 @@ CPColorPickerViewHeight = 370;
[previewBox addSubview:_previewView];
var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
var _previewLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
[_previewLabel setStringValue:"Preview:"];
[_previewLabel setTextColor:[CPColor blackColor]];
[_previewLabel setAlignment:CPRightTextAlignment];
@@ -357,14 +357,14 @@ CPColorPickerViewHeight = 370;
[swatchBox addSubview:_swatchView];
var _swatchLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue: "Swatches:"];
var _swatchLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue:"Swatches:"];
[_swatchLabel setTextColor:[CPColor blackColor]];
[_swatchLabel setAlignment:CPRightTextAlignment];
var opacityLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue: "Opacity:"];
var opacityLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue:"Opacity:"];
[opacityLabel setTextColor:[CPColor blackColor]];
[opacityLabel setAlignment:CPRightTextAlignment];
@@ -389,7 +389,7 @@ CPColorPickerViewHeight = 370;
_action = nil;
_activePicker = nil;
[_previewView setBackgroundColor: _color];
[_previewView setBackgroundColor:_color];
if (buttonForLater)
[self _setPicker:buttonForLater];
@@ -407,12 +407,13 @@ CPColorPickerViewHeight = 370;
CPColorDragType = "CPColorDragType";
var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
/* @ignore */
@implementation _CPColorPanelSwatches : CPView
{
CPView[] _swatches;
CPArray _swatches;
CPColor _dragColor;
CPColorPanel _colorPanel;
CPCookie _swatchCookie;
@@ -422,13 +423,13 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
self = [super initWithFrame:aFrame];
[self setBackgroundColor: [CPColor grayColor]];
[self setBackgroundColor:[CPColor grayColor]];
[self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
var whiteColor = [CPColor whiteColor];
_swatchCookie = [[CPCookie alloc] initWithName: CPColorPanelSwatchesCookie];
_swatchCookie = [[CPCookie alloc] initWithName:CPColorPanelSwatchesCookie];
var colorList = [self startingColorList];
_swatches = [];
@@ -436,15 +437,15 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
for (var i = 0; i < 50; i++)
{
// 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)];
[view setBackgroundColor:whiteColor];
[fillView setBackgroundColor: (i < colorList.length) ? colorList[i] : whiteColor];
[fillView setBackgroundColor:(i < colorList.length) ? colorList[i] : whiteColor];
[view addSubview:fillView];
[self addSubview: view];
[self addSubview:view];
_swatches.push(view);
}
@@ -461,7 +462,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
var cookieValue = [_swatchCookie value];
if (cookieValue == "")
if (!cookieValue)
{
return [
[CPColor blackColor],
@@ -480,7 +481,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
result = [];
for (var i = 0; i < cookieValue.length; i++)
result.push([CPColor colorWithHexString: cookieValue[i]]);
result.push([CPColor colorWithHexString:cookieValue[i]]);
return result;
}
@@ -495,7 +496,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var future = new Date();
future.setYear(2019);
[_swatchCookie setValue: JSON.stringify(result) expires:future domain: nil];
[_swatchCookie setValue:JSON.stringify(result) expires:future domain:nil];
}
- (void)setColorPanel:(CPColorPanel)panel
@@ -528,7 +529,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if (!CGRectContainsPoint(bounds, point) || point.x > [self bounds].size.width - 1 || point.x < 1)
return NO;
[_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
[_colorPanel setColor:[self colorAtIndex:FLOOR(point.x / 13)] updatePicker:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
@@ -545,10 +546,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
_dragColor = [[swatch subviews][0] backgroundColor];
var bounds = CPRectCreateCopy([swatch bounds]);
var bounds = CGRectMakeCopy([swatch bounds]);
// 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)];
[dragView setBackgroundColor:[CPColor blackColor]];
@@ -556,13 +557,13 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
[self dragView: dragView
at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset: CPPointMake(0.0, 0.0)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
[self dragView:dragView
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:nil
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
@@ -580,7 +581,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if (![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
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)];
}
@end
@@ -635,7 +636,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var bounds = CPRectMake(0, 0, 15, 15);
// 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)];
[dragView setBackgroundColor:[CPColor blackColor]];
@@ -643,13 +644,13 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
[self dragView: dragView
at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset: CPPointMake(0.0, 0.0)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
[self dragView:dragView
at:CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CPPointMake(0.0, 0.0)
event:anEvent
pasteboard:nil
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
+40 -36
View File
@@ -44,10 +44,11 @@
*/
- (id)initWithPickerMask:(int)aMask colorPanel:(CPColorPanel)aPanel
{
self = [super init];
_panel = aPanel;
_mask = aMask;
if (self = [super init])
{
_panel = aPanel;
_mask = aMask;
}
return self;
}
@@ -76,7 +77,6 @@
*/
- (void)setMode:(CPColorPanelMode)mode
{
return;
}
/*!
@@ -85,7 +85,6 @@
*/
- (void)setColor:(CPColor)aColor
{
return;
}
@end
@@ -110,12 +109,12 @@
- (id)initView
{
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = _CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_pickerView = [[CPView alloc] initWithFrame:aFrame];
[_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)];
[_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"];
[_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"];
@@ -128,9 +127,9 @@
[_brightnessSlider setAction:@selector(brightnessSliderDidChange:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable | CPViewMinYMargin];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate: self];
[_hueSaturationView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame:_CGRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate:self];
[_hueSaturationView setAutoresizingMask:(CPViewWidthSizable | CPViewHeightSizable)];
[_pickerView addSubview:_hueSaturationView];
[_pickerView addSubview:_brightnessSlider];
@@ -225,46 +224,49 @@
- (id)initWithFrame:(CPRect)aFrame
{
self = [super initWithFrame:aFrame];
var path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel.png"];
_wheelImage = new Image();
_wheelImage.src = path;
_wheelImage.style.position = "absolute";
path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel_black.png"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
if (self = [super initWithFrame:aFrame])
{
#if PLATFORM(DOM)
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
var path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel.png"];
_wheelImage = new Image();
_wheelImage.src = path;
_wheelImage.style.position = "absolute";
path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel_black.png"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
#endif
[self setWheelSize:aFrame.size];
[self setWheelSize:aFrame.size];
_crosshair = [[CPView alloc] initWithFrame:CPRectMake(_radius - 2, _radius - 2, 4, 4)];
[_crosshair setBackgroundColor:[CPColor blackColor]];
_crosshair = [[CPView alloc] initWithFrame:CGRectMake(_radius - 2, _radius - 2, 4, 4)];
[_crosshair setBackgroundColor:[CPColor blackColor]];
var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
[view setBackgroundColor:[CPColor whiteColor]];
var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
[view setBackgroundColor:[CPColor whiteColor]];
[_crosshair addSubview:view];
[_crosshair addSubview:view];
[self addSubview:_crosshair];
[self addSubview:_crosshair];
}
return self;
}
- (void)setWheelBrightness:(float)brightness
{
#if PLATFORM(DOM)
_blackWheelImage.style.opacity = 1.0 - brightness;
_blackWheelImage.style.filter = "alpha(opacity=" + (1.0 - brightness) * 100 + ")"
#endif
}
- (void)setFrameSize:(CPSize)aSize
@@ -277,6 +279,7 @@
{
var min = MIN(aSize.width, aSize.height);
#if PLATFORM(DOM)
_blackWheelImage.style.width = min;
_blackWheelImage.style.height = min;
_blackWheelImage.width = min;
@@ -290,6 +293,7 @@
_wheelImage.height = min;
_wheelImage.style.top = (aSize.height - min) / 2.0 + "px";
_wheelImage.style.left = (aSize.width - min) / 2.0 + "px";
#endif
_radius = min / 2.0;
+97 -78
View File
@@ -43,7 +43,6 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
BOOL _bordered;
CPColor _color;
CPView _wellView;
}
+ (Class)_binderClassForBinding:(CPString)theBinding
@@ -54,6 +53,17 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return [super _binderClassForBinding:theBinding];
}
+ (CPString)defaultThemeClass
{
return @"colorwell";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), [CPNull null], _CGInsetMake(3.0, 3.0, 3.0, 3.0), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"bezel-inset", @"bezel-color", @"content-inset", @"content-border-inset", @"content-border-color"]];
}
- (void)_reverseSetBinding
{
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
@@ -69,11 +79,8 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
if (self)
{
_active = NO;
_bordered = YES;
_color = [CPColor whiteColor];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setBordered:YES];
[self _registerForNotifications];
}
@@ -98,25 +105,23 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
/*!
Sets whether the color well is bordered.
*/
- (void)setBordered:(BOOL)shouldBeBordered
{
if (shouldBeBordered)
[self setThemeState:CPThemeStateBordered];
else
[self unsetThemeState:CPThemeStateBordered];
}
/*!
Returns whether the color well is bordered
*/
- (BOOL)isBordered
{
return _bordered;
}
/*!
Sets the color well's current color.
*/
- (void)setBordered:(BOOL)bordered
{
if (_bordered == bordered)
return;
_bordered = bordered;
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
return [self hasThemeState:CPThemeStateBordered];
}
// Managing Color From Color Wells
@@ -139,7 +144,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
_color = aColor;
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setNeedsLayout];
}
/*!
@@ -202,31 +207,6 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return _active;
}
// Drawing a Color Well
- (void)drawBezelWithHighlight:(BOOL)shouldHighlight
{
}
/*!
Draws the colored area inside the color well without borders.
@param aRect the location at which to draw
*/
- (void)drawWellInside:(CGRect)aRect
{
if (!_wellView)
{
_wellView = [[CPView alloc] initWithFrame:aRect];
[_wellView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self addSubview:_wellView];
}
else
[_wellView setFrame:aRect];
[_wellView setBackgroundColor:_color];
}
- (void)colorPanelDidChangeColor:(CPNotification)aNotification
{
[self takeColorFrom:[aNotification object]];
@@ -245,27 +225,11 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[self deactivate];
}
- (void)mouseDown:(CPEvent)anEvent
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
if (![self isEnabled])
return;
[self highlight:NO];
[self drawBezelWithHighlight:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
if (![self isEnabled])
return;
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
}
- (void)mouseUp:(CPEvent)anEvent
{
[self drawBezelWithHighlight:NO];
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled])
if (!mouseIsUp || !CGRectContainsPoint([self bounds], aPoint) || ![self isEnabled])
return;
[self activate:YES];
@@ -276,6 +240,73 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[colorPanel orderFront:self];
}
- (CGRect)contentRectForBounds:(CGRect)bounds
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)contentBorderRectForBounds:(CGRect)bounds
{
var contentBorderInset = [self currentValueForThemeAttribute:@"content-border-inset"];
return _CGRectInsetByInset(bounds, contentBorderInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
switch (aName)
{
case "bezel-view":
return [self bezelRectForBounds:[self bounds]];
case "content-view":
return [self contentRectForBounds:[self bounds]];
case "content-border-view":
return [self contentBorderRectForBounds:[self bounds]];
}
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"content-view"];
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var contentView = [self layoutEphemeralSubviewNamed:@"content-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"bezel-view"];
[contentView setBackgroundColor:_color];
var contentBorderView = [self layoutEphemeralSubviewNamed:@"content-border-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"content-view"];
[contentBorderView setBackgroundColor:[self currentValueForThemeAttribute:@"content-border-color"]];
}
@end
@implementation CPColorWellValueBinder : CPBinder
@@ -336,11 +367,8 @@ var CPColorWellColorKey = "CPColorWellColorKey",
if (self)
{
_active = NO;
_bordered = [aCoder decodeBoolForKey:CPColorWellBorderedKey];
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
[self _registerForNotifications];
}
@@ -354,19 +382,10 @@ var CPColorWellColorKey = "CPColorWellColorKey",
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
// We do this in order to avoid encoding the _wellView, which
// should just automatically be created programmatically as needed.
var actualSubviews = _subviews;
_subviews = [_subviews copy];
[_subviews removeObjectIdenticalTo:_wellView];
[super encodeWithCoder:aCoder];
_subviews = actualSubviews;
[aCoder encodeObject:_color forKey:CPColorWellColorKey];
[aCoder encodeObject:_bordered forKey:CPColorWellBorderedKey];
[aCoder encodeObject:[self isBordered] forKey:CPColorWellBorderedKey];
}
@end
+1192
View File
File diff suppressed because it is too large Load Diff
+14 -10
View File
@@ -112,7 +112,7 @@ var CPControlBlackColor = [CPColor blackColor];
CPTopVerticalTextAlignment,
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPFont systemFontOfSize:CPFontCurrentSystemSize],
[CPNull null],
_CGSizeMakeZero(),
CPImageLeft,
@@ -867,15 +867,14 @@ var CPControlBlackColor = [CPColor blackColor];
@end
var CPControlValueKey = "CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = "CPControlIsEnabledKey",
CPControlTargetKey = "CPControlTargetKey",
CPControlActionKey = "CPControlActionKey",
CPControlSendActionOnKey = "CPControlSendActionOnKey",
CPControlSendsActionOnEndEditingKey = "CPControlSendsActionOnEndEditingKey",
var CPControlValueKey = @"CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlActionKey = @"CPControlActionKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlFormatterKey = @"CPControlFormatterKey",
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@@ -900,6 +899,8 @@ var CPControlValueKey = "CPControlValueKey",
[self sendActionOn:[aCoder decodeIntForKey:CPControlSendActionOnKey]];
[self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]];
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
}
return self;
@@ -929,6 +930,9 @@ var CPControlValueKey = "CPControlValueKey",
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
if (_formatter !== nil)
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
}
@end
+172 -72
View File
@@ -28,46 +28,85 @@
CPFontDefaultSystemFontFace = @"Arial, sans-serif";
CPFontDefaultSystemFontSize = 12;
var _CPFonts = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
/*!
To create a font of a size that will dynamically reflect the current
system font size, use this for the size argument.
*/
CPFontCurrentSystemSize = -1;
// For internal use only by this class and subclasses
_CPFontSystemFacePlaceholder = "_CPFontSystemFacePlaceholder";
var _CPFontCache = {},
_CPSystemFontCache = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
#define _CPRealFontSize(aSize) (aSize <= 0 ? _CPFontSystemFontSize : aSize)
#define _CPFontNormalizedNames(aName) _CPFontNormalizedNameArray(aName).join(", ")
#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFonts[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFontCache[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
#define _CPUserFont(aName, aSize, isBold, isItalic) _CPCachedFont(aName, aSize, isBold, isItalic) || [[CPFont alloc] _initWithName:aName size:aSize bold:isBold italic:isItalic system:NO]
#define _CPSystemFontCacheKey(aSize, isBold) (String(aSize) + (isBold ? "b" : ""))
#define _CPCachedSystemFont(aSize, isBold) _CPSystemFontCache[_CPSystemFontCacheKey(aSize, isBold)]
#define _CPSystemFont(aSize, isBold) (_CPCachedSystemFont(aSize, isBold) || [[CPFont alloc] _initWithName:_CPFontSystemFacePlaceholder size:aSize bold:isBold italic:NO system:YES])
/*!
@ingroup appkit
@class CPFont
@ingroup appkit
@class CPFont
The CPFont class allows control of the fonts used for displaying text anywhere on the screen.
The primary method for getting a particular font is through one of the class methods that take
a name and/or size as arguments, and return the appropriate CPFont.
The CPFont class allows control of the fonts used for displaying text anywhere on the screen.
The primary method for getting a particular font is through one of the class methods that take
a name and/or size as arguments, and return the appropriate CPFont.
By default the system font face/size is Arial 12px, with a fallback to sans-serif. You may
configure this at runtime in two ways:
### System fonts
When you create a font using \c -systemFontOfSize: or \c -boldSystemFontOfSize:, a proxy font is
created that always refers to the current system font face and size. By default the system
font face/size is Arial 12px, with a fallback to sans-serif 12px. You may configure this at
runtime in two ways:
- By sending [CPFont @link CPFont::setSystemFontFace: setSystemFontFace:@endlink] and/or [CPFont @link CPFont::setSystemFontSize: setSystemFontSize:@endlink].
- By configuring Info.plist for your application or for AppKit. You can set the font face
by adding a CPSystemFontFace string item to the Info.plist, and you can set the font size
by adding a CPSystemFontSize integer item to the Info.plist.
- By sending [CPFont setSystemFontFace:<face>] and/or [CPFont setSystemFontSize:<size>].
Note that if you change the system font face or size during runtime, the next time
any view using a system font is redrawn, it will show the new font.
- By configuring Info.plist for your application or for AppKit. You can set the font face
by adding a CPSystemFontFace string item to the Info.plist, and you can set the font size
by adding a CPSystemFontSize integer item to the Info.plist.
Note that in either case, you can specify a comma-delimited list of fonts as the font face.
The browser will use the first available font in the list. CPFont always ensures that Arial
and sans-serif are in the generated CSS string, so there is no need to add them to the end
of your font list.
Note that in either case, you can specify a comma-delimited list of fonts as the font face.
Do not quote enclose font faces that contain spaces, that is done automatically when a CSS
representation of a font is requested.
If you are using nib2cib, you should use the second method (using Info.plist),
and be sure to run nib2cib again any time you modify the CPSystemFontFace or CPSystemFontSize items.
For example, you might add this to your application's Info.plist to set the system font to Lucida Grande,
with an automatic fallback to Arial or sans-serif:
The browser will use the first available font in the list you supply. CPFont always ensures
that Arial and sans-serif are in the CSS representation of a font as a fallback, so there is
no need to add them to the end of your font list.
@code
### nib2cib conversion
Fonts are converted by nib2cib according to the following algorithm:
- If the font family is Lucida Grande, then a system font will be created.
- If the font is Lucida Grande 13 (plain), the "default" font will be used at runtime.
The default font is taken from the "font" theme attribute if one exists,
otherwise from the current system font face and size.
- Lucida Grande of any size other than 13 will retain its size.
- Fonts using any family other than Lucida Grande will be used as is, including the size.
### Using custom web fonts
The configurability of CPFont makes it easy to use a custom web font as the system font.
For example, if you want to use the google font Asap as the system font, you would do the
following:
- Add a <link> to the <head> of index-debug.html and index.html:
@code
<link href='http://fonts.googleapis.com/css?family=Asap:400,700' rel='stylesheet' type='text/css'>
@endcode
- Specify Asap as the system font in Info.plist by adding the following item:
@code
<key>CPSystemFontFace</key>
<string>Lucida Grande</string>
@endcode
<string>Asap</string>
@endcode
*/
@implementation CPFont : CPObject
{
@@ -78,6 +117,7 @@ var _CPFonts = {},
float _lineHeight;
BOOL _isBold @accessors(readonly, getter=isBold);
BOOL _isItalic @accessors(readonly, getter=isItalic);
BOOL _isSystem @accessors(readonly, getter=isSystem);
CPString _cssString;
}
@@ -93,7 +133,7 @@ var _CPFonts = {},
systemFontFace = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:@"CPSystemFontFace"];
if (systemFontFace)
[self setSystemFontFace:systemFontFace];
_CPFontSystemFontFace = _CPFontNormalizedNames(systemFontFace);
var systemFontSize = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontSize"];
@@ -117,7 +157,13 @@ var _CPFonts = {},
*/
+ (CPString)setSystemFontFace:(CPString)aFace
{
_CPFontSystemFontFace = _CPFontNormalizedNames(aFace);
var normalizedFaces = _CPFontNormalizedNames(aFace);
if (normalizedFaces === _CPFontSystemFontFace)
return;
[self _invalidateSystemFontCache]
_CPFontSystemFontFace = aFace;
}
/*!
@@ -133,101 +179,136 @@ var _CPFonts = {},
*/
+ (float)setSystemFontSize:(float)size
{
if (size > 0)
if (size > 0 && size !== _CPFontSystemFontSize)
{
[self _invalidateSystemFontCache];
_CPFontSystemFontSize = size;
}
}
+ (void)_invalidateSystemFontCache
{
var systemSize = String(_CPFontSystemFontSize),
currentSize = String(CPFontCurrentSystemSize);
for (key in _CPSystemFontCache)
{
if (_CPSystemFontCache.hasOwnProperty(key) &&
(key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
{
delete _CPSystemFontCache[key];
}
}
}
/*!
Returns a font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@return the requested font
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize
{
return [CPFont fontWithName:aName size:aSize bold:NO italic:NO];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, NO);
}
/*!
Returns a font with the specified name, size and style.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@param italic whether the font should be italicized
@return the requested font
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return [CPFont fontWithName:aName size:aSize bold:NO italic:italic];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, italic);
}
/*!
Returns a bold font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@return the requested bold font
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize
{
return [CPFont fontWithName:aName size:aSize bold:YES italic:NO];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, NO);
}
/*!
Returns a bold font with the specified name, size and style.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@param italic whether the font should be italicized
@return the requested font
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return [CPFont fontWithName:aName size:aSize bold:YES italic:italic];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, italic);
}
/*!
Internal font getter like fontWithName:size:italic: with a bold selector.
*/
+ (CPFont)_fontWithName:(CPString)aName size:(float)aSize bold:(BOOL)bold italic:(BOOL)italic
{
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, bold, italic);
}
/*!
Returns the system font scaled to the specified size
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 creates a static font
in the current system font size. Negative creates a font
that dynamically tracks the current system font size.
@return the requested system font
*/
+ (CPFont)systemFontOfSize:(CPSize)aSize
{
return [CPFont fontWithName:_CPFontSystemFontFace size:aSize bold:NO italic:NO];
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
}
/*!
Returns the bold system font scaled to the specified size
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 creates a static font
in the current system font size. Negative creates a font
that dynamically tracks the current system font size.
@return the requested bold system font
*/
+ (CPFont)boldSystemFontOfSize:(CPSize)aSize
{
return [CPFont fontWithName:_CPFontSystemFontFace size:aSize bold:YES italic:NO];
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
}
/* FIXME Font Descriptor
@ignore
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize bold:(BOOL)bold italic:(BOOL)italic
{
return _CPCachedFont(aName, aSize, bold, italic) || [[CPFont alloc] _initWithName:aName size:aSize bold:bold italic:italic];
}
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic system:(BOOL)isSystem
{
self = [super init];
if (self)
{
_name = _CPFontNormalizedNames(aName);
_size = aSize;
_ascender = 0;
_descender = 0;
_lineHeight = 0;
_isBold = isBold;
_isItalic = isItalic;
_isSystem = isSystem;
_cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
_CPFonts[_cssString] = self;
if (isSystem)
{
_name = aName;
_cssString = _CPFontCreateCSSString(_CPFontSystemFontFace, _size, _isBold, _isItalic);
_CPSystemFontCache[_CPSystemFontCacheKey(_size, _isBold)] = self;
}
else
{
_name = _CPFontNormalizedNames(aName);
_cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
_CPFontCache[_cssString] = self;
}
}
return self;
@@ -238,10 +319,12 @@ var _CPFonts = {},
*/
- (float)ascender
{
if (!_ascender)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _ascender;
if (!font._ascender)
[font _getMetrics];
return font._ascender;
}
/*!
@@ -250,10 +333,12 @@ var _CPFonts = {},
*/
- (float)descender
{
if (!_descender)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _descender;
if (!font._descender)
[font _getMetrics];
return font._descender;
}
/*!
@@ -263,10 +348,12 @@ var _CPFonts = {},
*/
- (float)defaultLineHeightForFont
{
if (!_lineHeight)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _lineHeight;
if (!font._lineHeight)
[font _getMetrics];
return font._lineHeight;
}
/*!
@@ -274,7 +361,7 @@ var _CPFonts = {},
*/
- (float)size
{
return _size;
return _CPRealFontSize(_size);
}
/*!
@@ -282,7 +369,9 @@ var _CPFonts = {},
*/
- (CPString)cssString
{
return _cssString;
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return font._cssString;
}
/*!
@@ -290,9 +379,17 @@ var _CPFonts = {},
*/
- (CPString)familyName
{
if (_isSystem)
return _CPFontSystemFontFace;
return _name;
}
- (BOOL)isSystemSize
{
return _size <= 0;
}
- (BOOL)isEqual:(id)anObject
{
return [anObject isKindOfClass:[CPFont class]] && [anObject cssString] === _cssString;
@@ -305,7 +402,7 @@ var _CPFonts = {},
- (id)copy
{
return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic];
return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic system:_isSystem];
}
- (void)_getMetrics
@@ -322,7 +419,8 @@ var _CPFonts = {},
var CPFontNameKey = @"CPFontNameKey",
CPFontSizeKey = @"CPFontSizeKey",
CPFontIsBoldKey = @"CPFontIsBoldKey",
CPFontIsItalicKey = @"CPFontIsItalicKey";
CPFontIsItalicKey = @"CPFontIsItalicKey",
CPFontIsSystemKey = @"CPFontIsSystemKey";
@implementation CPFont (CPCoding)
@@ -336,9 +434,10 @@ var CPFontNameKey = @"CPFontNameKey",
var fontName = [aCoder decodeObjectForKey:CPFontNameKey],
size = [aCoder decodeFloatForKey:CPFontSizeKey],
isBold = [aCoder decodeBoolForKey:CPFontIsBoldKey],
isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey];
isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey],
isSystem = [aCoder decodeBoolForKey:CPFontIsSystemKey];
return [self _initWithName:fontName size:size bold:isBold italic:isItalic];
return [self _initWithName:fontName size:size bold:isBold italic:isItalic system:isSystem];
}
/*!
@@ -351,6 +450,7 @@ var CPFontNameKey = @"CPFontNameKey",
[aCoder encodeFloat:_size forKey:CPFontSizeKey];
[aCoder encodeBool:_isBold forKey:CPFontIsBoldKey];
[aCoder encodeBool:_isItalic forKey:CPFontIsItalicKey];
[aCoder encodeBool:_isSystem forKey:CPFontIsSystemKey];
}
@end
@@ -359,7 +459,7 @@ var CPFontNameKey = @"CPFontNameKey",
// aName must be normalized
var _CPFontCreateCSSString = function(aName, aSize, isBold, isItalic)
{
var properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + aSize + "px ";
var properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + _CPRealFontSize(aSize) + "px ";
return properties + _CPFontConcatNameWithFallback(aName);
};
+145 -27
View File
@@ -24,6 +24,19 @@
@import "CPFont.j"
CPItalicFontMask = 1 << 0;
CPBoldFontMask = 1 << 1;
CPUnboldFontMask = 1 << 2;
CPNonStandardCharacterSetFontMask = 1 << 3;
CPNarrowFontMask = 1 << 4;
CPExpandedFontMask = 1 << 5;
CPCondensedFontMask = 1 << 6;
CPSmallCapsFontMask = 1 << 7;
CPPosterFontMask = 1 << 8;
CPCompressedFontMask = 1 << 9;
CPFixedPitchFontMask = 1 << 10;
CPUnitalicFontMask = 1 << 24;
var CPSharedFontManager = nil,
CPFontManagerFactory = Nil;
@@ -33,7 +46,17 @@ var CPSharedFontManager = nil,
*/
@implementation CPFontManager : CPObject
{
CPArray _availableFonts;
CPArray _availableFonts;
id _target @accessors(property=target);
SEL _action @accessors(property=action);
id _delegate @accessors(property=delegate);
CPFont _selectedFont;
BOOL _multiple @accessors;
CPDictionary _activeChange;
}
// Getting the Shared Font Manager
@@ -59,6 +82,16 @@ var CPSharedFontManager = nil,
CPFontManagerFactory = aClass;
}
- (id)init
{
if (self = [super init])
{
_action = @selector(changeFont:);
}
return self;
}
/*!
Returns an array of the available fonts
*/
@@ -97,43 +130,128 @@ var CPSharedFontManager = nil,
return _CPFontDetectFontAvailable(aFontName);
}
- (void)setSelectedFont:(CPFont)aFont isMultiple:(BOOL)aFlag
{
_selectedFont = aFont;
_isMultiple = aFlag;
// TODO Notify CPFontPanel when it exists.
}
- (CPFont)selectedFont
{
return _selectedFont;
}
- (BOOL)isMultiple
{
return _isMultiple;
}
- (int)weightOfFont:(CPFont)aFont
{
// TODO Weight 5 is a normal of book weight and 9 and above is bold, but it would be nice to be more
// precise than that.
return [aFont isBold] ? 9 : 5;
}
- (CPFontTraitMask)traitsOfFont:(CPFont)aFont
{
return ([aFont isBold] ? CPBoldFontMask : 0) | ([aFont isItalic] ? CPItalicFontMask : 0);
}
- (CPFont)convertFont:(CPFont)aFont
{
if (!_activeChange)
return aFont;
var addTraits = [_activeChange valueForKey:@"addTraits"];
if (addTraits)
aFont = [self convertFont:aFont toHaveTrait:addTraits];
return aFont;
}
- (CPFont)convertFont:(CPFont)aFont toHaveTrait:(CPFontTraitMask)addTraits
{
if (!aFont)
return nil;
var shouldBeBold = ([aFont isBold] || (addTraits & CPBoldFontMask)) && !(addTraits & CPUnboldFontMask),
shouldBeItalic = ([aFont isItalic] || (addTraits & CPItalicFontMask)) && !(addTraits & CPUnitalicFontMask),
shouldBeSize = [aFont size];
// XXX On the current platform there will always be a bold/italic version of each font, but still leave
// || aFont in here for future platforms.
aFont = [CPFont _fontWithName:[aFont familyName] size:shouldBeSize bold:shouldBeBold italic:shouldBeItalic] || aFont;
return aFont;
}
- (CPFont)convertFont:(CPFont)aFont toFace:(CPString)aTypeface
{
if (!aFont)
return nil;
var shouldBeBold = [aFont isBold],
shouldBeItalic = [aFont isItalic],
shouldBeSize = [aFont size];
aFont = [CPFont _fontWithName:aTypeface size:shouldBeSize bold:shouldBeBold italic:shouldBeItalic] || aFont;
return aFont;
}
- (@action)addFontTrait:(id)sender
{
_activeChange = [CPDictionary dictionaryWithObject:[sender tag] forKey:@"addTraits"];
[self sendAction];
}
- (BOOL)sendAction
{
return [CPApp sendAction:_action to:_target from:self];
}
@end
var _CPFontDetectSpan,
_CPFontDetectReferenceFonts,
_CPFontDetectAllFonts = [
/* "04b_21","A Charming Font","Abadi MT Condensed","Abadi MT Condensed Extra Bold","Abadi MT Condensed Light","Academy Engraved LET","Agency FB","Alba","Alba Matter","Alba Super","Algerian",*/
/* "04b_21", "A Charming Font", "Abadi MT Condensed", "Abadi MT Condensed Extra Bold", "Abadi MT Condensed Light", "Academy Engraved LET", "Agency FB", "Alba", "Alba Matter", "Alba Super", "Algerian",*/
"American Typewriter",
/* "Andale Mono","Andale Mono IPA","Andy", */
"Apple Chancery","Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS",
/* "Avant Garde","Avantgarde","Baby Kruffy","Base 02","Baskerville","Baskerville Old Face","Bauhaus 93","Beesknees ITC","Bell MT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","Bickley Script",*/
"Big Caslon","Bitstream Vera Sans","Bitstream Vera Sans Mono","Bitstream Vera Serif",
/* "Blackadder ITC","Blackletter686 BT","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Book Antiqua","Bookman","Bookman Old Style","Bradley Hand ITC","Braggadocio","Britannic Bold","Broadway","Broadway BT",*/
/* "Andale Mono", "Andale Mono IPA", "Andy", */
"Apple Chancery", "Arial", "Arial Black", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS",
/* "Avant Garde", "Avantgarde", "Baby Kruffy", "Base 02", "Baskerville", "Baskerville Old Face", "Bauhaus 93", "Beesknees ITC", "Bell MT", "Berlin Sans FB", "Berlin Sans FB Demi", "Bernard MT Condensed", "Bickley Script",*/
"Big Caslon", "Bitstream Vera Sans", "Bitstream Vera Sans Mono", "Bitstream Vera Serif",
/* "Blackadder ITC", "Blackletter686 BT", "Bodoni MT", "Bodoni MT Black", "Bodoni MT Condensed", "Bodoni MT Poster Compressed", "Book Antiqua", "Bookman", "Bookman Old Style", "Bradley Hand ITC", "Braggadocio", "Britannic Bold", "Broadway", "Broadway BT",*/
"Brush Script MT",
/* "BudHand","CAMPBELL","Calibri","Californian FB","Calisto MT","Calligraph421 BT",*/
/* "BudHand", "CAMPBELL", "Calibri", "Californian FB", "Calisto MT", "Calligraph421 BT",*/
"Cambria",
/* "Candara","Capitals",*/
"Caslon","Castellar","Cataneo BT","Centaur","Century Gothic","Century Schoolbook","Century Schoolbook L",
/* "Champignon","Charcoal","Charter","Charter BT","Chicago","Chick","Chiller","ClearlyU","Colonna MT",*/
"Comic Sans", "Comic Sans MS","Consolas","Constantia","Cooper Black","Copperplate","Copperplate Gothic Bold","Copperplate Gothic Light","Corbel","Courier","Courier New",
/* "Croobie","Curlz MT","Desdemona","Didot","DomBold BT","Edwardian Script ITC","Engravers MT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","Eurostile","FIRSTHOME","Fat","Felix Titling","Fine Hand","Fixed","Footlight MT Light","Forte","Franklin Gothic Book","Franklin Gothic Demi","Franklin Gothic Demi Cond","Franklin Gothic Heavy","Franklin Gothic Medium","Franklin Gothic Medium Cond","Freestyle Script","French Script MT","Freshbot","Frosty",*/
/* "Candara", "Capitals",*/
"Caslon", "Castellar", "Cataneo BT", "Centaur", "Century Gothic", "Century Schoolbook", "Century Schoolbook L",
/* "Champignon", "Charcoal", "Charter", "Charter BT", "Chicago", "Chick", "Chiller", "ClearlyU", "Colonna MT",*/
"Comic Sans", "Comic Sans MS", "Consolas", "Constantia", "Cooper Black", "Copperplate", "Copperplate Gothic Bold", "Copperplate Gothic Light", "Corbel", "Courier", "Courier New",
/* "Croobie", "Curlz MT", "Desdemona", "Didot", "DomBold BT", "Edwardian Script ITC", "Engravers MT", "Eras Bold ITC", "Eras Demi ITC", "Eras Light ITC", "Eras Medium ITC", "Eurostile", "FIRSTHOME", "Fat", "Felix Titling", "Fine Hand", "Fixed", "Footlight MT Light", "Forte", "Franklin Gothic Book", "Franklin Gothic Demi", "Franklin Gothic Demi Cond", "Franklin Gothic Heavy", "Franklin Gothic Medium", "Franklin Gothic Medium Cond", "Freestyle Script", "French Script MT", "Freshbot", "Frosty",*/
"Futura",
/* "GENUINE","Gadget","Garamond",*/
"Geneva","Georgia","Georgia Ref", "Geeza Pro", "Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed",
/* "GlooGun","Gloucester MT Extra Condensed","Goudy Old Style","Goudy Stout","Haettenschweiler","Harlow Solid Italic","Harrington",*/
"Helvetica","Helvetica Narrow","Helvetica Neue","Herculanum","High Tower Text","Highlight LET","Hoefler Text","Impact","Imprint MT Shadow",
/* "Informal Roman","Jenkins v2.0","John Handy LET","Jokerman","Jokerman LET","Jokewood","Juice ITC","Kabel Ult BT","Kartika","Kino MT","Kristen ITC","Kunstler Script","La Bamba LET", */
"Lucida","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","Lucida Grande","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode",
/* "Luxi Mono","Luxi Sans","Luxi Serif","MARKETPRO","MS Reference Sans Serif","MS Reference Serif","Magneto","Maiandra GD", */
/* "GENUINE", "Gadget", "Garamond",*/
"Geneva", "Georgia", "Georgia Ref", "Geeza Pro", "Gigi", "Gill Sans", "Gill Sans MT", "Gill Sans MT Condensed", "Gill Sans MT Ext Condensed Bold", "Gill Sans Ultra Bold", "Gill Sans Ultra Bold Condensed",
/* "GlooGun", "Gloucester MT Extra Condensed", "Goudy Old Style", "Goudy Stout", "Haettenschweiler", "Harlow Solid Italic", "Harrington",*/
"Helvetica", "Helvetica Narrow", "Helvetica Neue", "Herculanum", "High Tower Text", "Highlight LET", "Hoefler Text", "Impact", "Imprint MT Shadow",
/* "Informal Roman", "Jenkins v2.0", "John Handy LET", "Jokerman", "Jokerman LET", "Jokewood", "Juice ITC", "Kabel Ult BT", "Kartika", "Kino MT", "Kristen ITC", "Kunstler Script", "La Bamba LET", */
"Lucida", "Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "Lucida Grande", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode",
/* "Luxi Mono", "Luxi Sans", "Luxi Serif", "MARKETPRO", "MS Reference Sans Serif", "MS Reference Serif", "Magneto", "Maiandra GD", */
"Marker Felt",
/* "Matisse ITC","Matura MT Script Capitals","Mead Bold","Mekanik LET","Mercurius Script MT Bold", */
"Microsoft Sans Serif","Milano LET","Minion Web","MisterEarl BT","Mistral","Monaco","Monotype Corsiva","Monotype.com","New Century Schoolbook","New York","News Gothic MT",
/* "Niagara Engraved","Niagara Solid","Nimbus Mono L","Nimbus Roman No9 L","OCR A Extended","OCRB","Odessa LET","Old English Text MT","OldDreadfulNo7 BT","One Stroke Script LET","Onyx","Optima","Orange LET","Palace Script MT","Palatino","Palatino Linotype", */
/* "Matisse ITC", "Matura MT Script Capitals", "Mead Bold", "Mekanik LET", "Mercurius Script MT Bold", */
"Microsoft Sans Serif", "Milano LET", "Minion Web", "MisterEarl BT", "Mistral", "Monaco", "Monotype Corsiva", "Monotype.com", "New Century Schoolbook", "New York", "News Gothic MT",
/* "Niagara Engraved", "Niagara Solid", "Nimbus Mono L", "Nimbus Roman No9 L", "OCR A Extended", "OCRB", "Odessa LET", "Old English Text MT", "OldDreadfulNo7 BT", "One Stroke Script LET", "Onyx", "Optima", "Orange LET", "Palace Script MT", "Palatino", "Palatino Linotype", */
"Papyrus",
/* "ParkAvenue BT","Pepita MT","Perpetua","Perpetua Titling MT","Placard Condensed","Playbill","Poornut","Pristina","Pump Demi Bold LET","Pussycat","Quixley LET","Rage Italic","Rage Italic LET","Ravie","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Ruach LET","Runic MT Condensed","Sand","Script MT Bold","Scruff LET","Segoe UI","Showcard Gothic","Skia","Smudger LET","Snap ITC","Square721 BT","Staccato222 BT","Stencil","Sylfaen", */
"Tahoma","Techno","Tempus Sans ITC","Terminal","Textile","Times","Times New Roman","Tiranti Solid LET","Trebuchet MS",
/* "Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","URW Antiqua T","URW Bookman L","URW Chancery L","URW Gothic L","URW Palladio L","Univers","University Roman LET","Utopia", */
"Verdana","Verdana Ref", /* "Victorian LET","Viner Hand ITC","Vivaldi","Vladimir Script","Vrinda","Weltron Urban","Westwood LET","Wide Latin","Zapf Chancery", */
/* "ParkAvenue BT", "Pepita MT", "Perpetua", "Perpetua Titling MT", "Placard Condensed", "Playbill", "Poornut", "Pristina", "Pump Demi Bold LET", "Pussycat", "Quixley LET", "Rage Italic", "Rage Italic LET", "Ravie", "Rockwell", "Rockwell Condensed", "Rockwell Extra Bold", "Ruach LET", "Runic MT Condensed", "Sand", "Script MT Bold", "Scruff LET", "Segoe UI", "Showcard Gothic", "Skia", "Smudger LET", "Snap ITC", "Square721 BT", "Staccato222 BT", "Stencil", "Sylfaen", */
"Tahoma", "Techno", "Tempus Sans ITC", "Terminal", "Textile", "Times", "Times New Roman", "Tiranti Solid LET", "Trebuchet MS",
/* "Tw Cen MT", "Tw Cen MT Condensed", "Tw Cen MT Condensed Extra Bold", "URW Antiqua T", "URW Bookman L", "URW Chancery L", "URW Gothic L", "URW Palladio L", "Univers", "University Roman LET", "Utopia", */
"Verdana", "Verdana Ref", /* "Victorian LET", "Viner Hand ITC", "Vivaldi", "Vladimir Script", "Vrinda", "Weltron Urban", "Westwood LET", "Wide Latin", "Zapf Chancery", */
"Zapfino"];
// Compare against the reference fonts. Return true if it produces a different size than at least one of them.
+1 -2
View File
@@ -21,13 +21,12 @@
*/
@import <Foundation/CPBundle.j>
@import <Foundation/CPGeometry.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@import <Foundation/CPString.j>
@import "CPGeometry.j"
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
+3
View File
@@ -557,6 +557,7 @@ CPContentBinding = @"content";
CPContentObjectBinding = @"contentObject";
CPContentObjectsBinding = @"contentObjects";
CPContentValuesBinding = @"contentValues";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
CPFontNameBinding = @"fontName";
@@ -572,7 +573,9 @@ CPSelectedTagBinding = @"selectedTag";
CPSelectedValueBinding = @"selectedValue";
CPSelectedValuesBinding = @"selectedValues";
CPSelectionIndexesBinding = @"selectionIndexes";
CPTextColorBinding = @"textColor";
CPTitleBinding = @"title";
CPToolTipBinding = @"toolTip";
CPValueBinding = @"value";
CPValueURLBinding = @"valueURL";
CPValuePathBinding = @"valuePath";
+1 -1
View File
@@ -806,7 +806,7 @@ var _CPMenuBarVisible = NO,
[aMenu _menuWillOpen];
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
aFont = [CPFont systemFontOfSize:[CPFont systemFontSize]];
var theWindow = [aView window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:aMenu font:aFont];
+3 -3
View File
@@ -39,7 +39,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:12.0];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:[CPFont systemFontSize]];
}
+ (CPFont)font
@@ -74,7 +74,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:13.0]];
[_titleField setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 1]];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowOffset:CGSizeMake(0, 1)];
@@ -335,7 +335,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
- (CPFont)font
{
[CPFont systemFontOfSize:12.0];
[CPFont systemFontOfSize:[CPFont systemFontSize]];
}
- (void)tile
+1 -1
View File
@@ -281,7 +281,7 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
*/
- (void)setFont:(CPFont)aFont
{
if (_font == aFont)
if ([_font isEqual:aFont])
return;
_font = aFont;
+1 -1
View File
@@ -176,7 +176,7 @@ var _CPMenuItemSelectionColor = nil,
- (void)setFont:(CPFont)aFont
{
if (_font === aFont)
if ([_font isEqual:aFont])
return;
_font = aFont;
+2 -1
View File
@@ -711,7 +711,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return _CGRectMakeZero();
var dataViewFrame = [self _frameOfOutlineDataViewAtRow:aRow],
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - 10, _CGRectGetMinY(dataViewFrame), 10, _CGRectGetHeight(dataViewFrame));
disclosureWidth = _CGRectGetWidth([_disclosureControlPrototype frame]),
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - disclosureWidth, _CGRectGetMinY(dataViewFrame), disclosureWidth, _CGRectGetHeight(dataViewFrame));
return frame;
}
+18 -9
View File
@@ -20,11 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPButton.j>
@import <AppKit/CPGeometry.j>
@import <AppKit/CPKeyValueBinding.j>
@import <AppKit/CPMenu.j>
@import <AppKit/CPMenuItem.j>
@import <Foundation/CPGeometry.j>
@import "CPButton.j"
@import "CPKeyValueBinding.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
var VISIBLE_MARGIN = 7.0;
@@ -571,10 +572,18 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([indexes containsIndex:0] && [self pullsDown])
[self _firstItemDidChange];
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
if (![self pullsDown] && [indexes containsIndex:indexOfSelectedItem])
{
// If the selected item is removed the first item becomes selected.
indexOfSelectedItem = 0;
}
else
{
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
}
[self selectItemAtIndex:indexOfSelectedItem];
}
@@ -686,6 +686,7 @@ CPTransformableAttributeType = 1800;
[textField setBordered:YES];
[textField setEditable:YES];
[textField setFont:[CPFont systemFontOfSize:10]];
[textField setSendsActionOnEndEditing:YES];
return textField;
}
+31 -30
View File
@@ -402,13 +402,16 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
if (_stringsFilename !== stringsFilename)
{
_stringsFilename = stringsFilename;
// Convert an empty string to nil
_stringsFilename = stringsFilename || nil;
if (stringsFilename !== nil)
{
if (![stringsFilename hasSuffix:@".strings"])
stringsFilename = stringsFilename + @".strings";
var path = [[CPBundle mainBundle] pathForResource:stringsFilename];
if (path !== nil)
[_standardLocalizer loadContentOfURL:[CPURL URLWithString:path]];
}
@@ -504,7 +507,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
- (int)parentRowForRow:(int)rowIndex
{
if (rowIndex < 0 || rowIndex >= [self numberOfRows])
[CPException raise:CPRangeException reason:_cmd+@" row " + rowIndex + " is out of range"];
[CPException raise:CPRangeException reason:_cmd + @" row " + rowIndex + " is out of range"];
var targetObject = [[self _rowCacheForIndex:rowIndex] rowObject];
@@ -545,7 +548,7 @@ TODO: implement
- (CPRuleEditorRowType)rowTypeForRow:(int)rowIndex
{
if (rowIndex < 0 || rowIndex > [self numberOfRows])
[CPException raise:CPRangeException reason:_cmd+@"row " + rowIndex + " is out of range"];
[CPException raise:CPRangeException reason:_cmd + @"row " + rowIndex + " is out of range"];
var rowcache = [self _rowCacheForIndex:rowIndex];
if (rowcache)
@@ -585,7 +588,7 @@ TODO: implement
if (indexInSubrows !== CPNotFound)
{
[indexes addIndex:i];
objectsCount --;
objectsCount--;
if ([self rowTypeForRow:i] === CPRuleEditorRowTypeCompound)
i += [[self subrowIndexesForRow:i] count];
@@ -845,7 +848,7 @@ TODO: implement
}
catch(error)
{
CPLogConsole(@"Compound predicate error: [%@]\npredicateType:%i",[error description],compoundType);
CPLogConsole(@"Compound predicate error: [%@]\npredicateType:%i", [error description], compoundType);
compoundPredicate = nil;
}
finally
@@ -890,23 +893,21 @@ TODO: implement
try
{
if (selector !== nil)
predicate = [CPComparisonPredicate
predicateWithLeftExpression:lhs
rightExpression:rhs
customSelector:selector
predicate = [CPComparisonPredicate predicateWithLeftExpression:lhs
rightExpression:rhs
customSelector:selector
];
else
predicate = [CPComparisonPredicate
predicateWithLeftExpression:lhs
rightExpression:rhs
modifier:(modifier || CPDirectPredicateModifier)
type:operator
options:(options || CPCaseInsensitivePredicateOption)
predicate = [CPComparisonPredicate predicateWithLeftExpression:lhs
rightExpression:rhs
modifier:(modifier || CPDirectPredicateModifier)
type:operator
options:(options || CPCaseInsensitivePredicateOption)
];
}
catch(error)
{
CPLogConsole(@"Row predicate error: ["+[error description]+"] for row "+aRow);
CPLogConsole(@"Row predicate error: [" + [error description] + "] for row " + aRow);
predicate = nil;
}
finally
@@ -1132,7 +1133,7 @@ TODO: implement
- (_CPRuleEditorViewSliceDropSeparator)_createSliceDropSeparator
{
var view = [[_CPRuleEditorViewSliceDropSeparator alloc] initWithFrame:CGRectMake(0,-10, [self frame].size.width, 2)];
var view = [[_CPRuleEditorViewSliceDropSeparator alloc] initWithFrame:CGRectMake(0, -10, [self frame].size.width, 2)];
[view setAutoresizingMask:CPViewWidthSizable];
return view;
}
@@ -1313,7 +1314,7 @@ TODO: implement
return [_boundArrayOwner mutableArrayValueForKey:_boundArrayKeyPath];
}
- (BOOL)_nextUnusedItems:({CPArray})items andValues:({CPArray})values forRow:(int)rowIndex forRowType:(unsigned int)type
- (BOOL)_nextUnusedItems:(CPArray)items andValues:(CPArray)values forRow:(int)rowIndex forRowType:(unsigned int)type
{
var parentItem = [items lastObject], // if empty items array, this is NULL aka the root item;
childrenCount = [self _queryNumberOfChildrenOfItem:parentItem withRowType:type],
@@ -1395,7 +1396,7 @@ TODO: implement
{
var item = [items objectAtIndex:i],
value = [values objectAtIndex:i],
itemAndValue = [CPDictionary dictionaryWithObjects:[item,value] forKeys:["item","value"]];
itemAndValue = [CPDictionary dictionaryWithObjects:[item, value] forKeys:["item", "value"]];
[itemsAndValues addObject:itemAndValue];
}
@@ -2106,9 +2107,9 @@ TODO: implement
mainRowIndex = [slice rowIndex],
draggingRows = [CPIndexSet indexSetWithIndex:mainRowIndex],
selected_indices = [self _selectedSliceIndices],
pasteboard = [CPPasteboard pasteboardWithName: CPDragPboard];
pasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];
[pasteboard declareTypes:[CPArray arrayWithObjects: CPRuleEditorItemPBoardType, nil] owner: self];
[pasteboard declareTypes:[CPArray arrayWithObjects:CPRuleEditorItemPBoardType, nil] owner: self];
if ([selected_indices containsIndex:mainRowIndex])
[draggingRows addIndexes:selected_indices];
@@ -2311,7 +2312,7 @@ TODO: implement
{
var rowObject = [[self _rowCacheForIndex:current_index] rowObject],
subrows = [self _subrowObjectsOfObject:rowObject],
subIndexes = [self _globalIndexesForSubrowIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0,[subrows count])] ofParentObject:rowObject];
subIndexes = [self _globalIndexesForSubrowIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [subrows count])] ofParentObject:rowObject];
numberOfChildrenOfPreviousBrother = [subIndexes count];
}
@@ -2413,17 +2414,17 @@ var CPRuleEditorAlignmentGridWidthKey = @"CPRuleEditorAlignmentGridWidth",
if (self !== nil)
{
[self setFormattingStringsFilename:[coder decodeObjectForKey:CPRuleEditorStringsFilenameKey]];
_alignmentGridWidth = [coder decodeFloatForKey:CPRuleEditorAlignmentGridWidthKey];
_sliceHeight = [coder decodeDoubleForKey:CPRuleEditorSliceHeightKey];
_alignmentGridWidth = [coder decodeFloatForKey:CPRuleEditorAlignmentGridWidthKey];
_sliceHeight = [coder decodeDoubleForKey:CPRuleEditorSliceHeightKey];
_editable = [coder decodeBoolForKey:CPRuleEditorEditableKey];
_allowsEmptyCompoundRows = [coder decodeBoolForKey:CPRuleEditorAllowsEmptyCompoundRowsKey];
_disallowEmpty = [coder decodeBoolForKey:CPRuleEditorDisallowEmptyKey];
_nestingMode = [coder decodeIntForKey:CPRuleEditorNestingModeKey];
_typeKeyPath = [coder decodeObjectForKey:CPRuleEditorRowTypeKeyPathKey];
_itemsKeyPath = [coder decodeObjectForKey:CPRuleEditorItemsKeyPathKey];
_valuesKeyPath = [coder decodeObjectForKey:CPRuleEditorValuesKeyPathKey];
_subrowsArrayKeyPath = [coder decodeObjectForKey:CPRuleEditorSubrowsArrayKeyPathKey];
_boundArrayKeyPath = [coder decodeObjectForKey:CPRuleEditorBoundArrayKeyPathKey];
_nestingMode = [coder decodeIntForKey:CPRuleEditorNestingModeKey];
_typeKeyPath = [coder decodeObjectForKey:CPRuleEditorRowTypeKeyPathKey];
_itemsKeyPath = [coder decodeObjectForKey:CPRuleEditorItemsKeyPathKey];
_valuesKeyPath = [coder decodeObjectForKey:CPRuleEditorValuesKeyPathKey];
_subrowsArrayKeyPath = [coder decodeObjectForKey:CPRuleEditorSubrowsArrayKeyPathKey];
_boundArrayKeyPath = [coder decodeObjectForKey:CPRuleEditorBoundArrayKeyPathKey];
_slicesHolder = [[self subviews] objectAtIndex:0];
_boundArrayOwner = [coder decodeObjectForKey:CPRuleEditorBoundArrayOwnerKey];
+13 -9
View File
@@ -7,7 +7,7 @@
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
@implementation _CPRuleEditorLocalizer : CPObject
{
@@ -24,9 +24,10 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
- (void)reloadIfNeeded
{
if (connection != nil) // Connection waiting
if (connection !== nil) // Connection waiting
{
connection = nil;
var data = [CPURLConnection sendSynchronousRequest:request returningResponse:NULL];
[self loadContent:[data rawString]];
}
@@ -34,7 +35,7 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)rawString
{
if (connection != nil && rawString != nil)
if (connection !== nil && rawString !== nil)
[self loadContent:rawString];
connection = nil;
@@ -49,10 +50,12 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
for (var i = 0 ; i < count ; i++)
{
var line = [lines objectAtIndex:i];
if (line.length > 1)
{
var match = regex.exec(line);
if (match.length >= 3)
var match = LocalizerStringsRegex.exec(line);
if (match && match.length >= 3)
[dict setObject:match[2] forKey:match[1]];
}
}
@@ -64,12 +67,13 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
{
[self reloadIfNeeded];
if (_dictionary != nil && aString != nil)
if (_dictionary !== nil && aString !== nil)
{
var localized = [_dictionary objectForKey:aString];
if (localized != nil)
return localized;
if (localized !== nil)
return localized;
}
return aString;
}
}
+141 -141
View File
@@ -60,7 +60,7 @@
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
{
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
return [super initWithPickerMask:mask colorPanel:owningColorPanel];
}
- (id)initView
@@ -70,156 +70,156 @@
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_rgbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue: "Red, Green, Blue"];
_rgbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue:"Red, Green, Blue"];
[_rgbLabel setTextColor:[CPColor blackColor]];
_redLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue: "R"];
_redLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue:"R"];
[_redLabel setTextColor:[CPColor blackColor]];
_redSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue: 1.0];
[_redSlider setMinValue: 0.0];
[_redSlider setTarget: self];
[_redSlider setAction: @selector(sliderChanged:)];
[_redSlider setAutoresizingMask: CPViewWidthSizable];
_redSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue:1.0];
[_redSlider setMinValue:0.0];
[_redSlider setTarget:self];
[_redSlider setAction:@selector(sliderChanged:)];
[_redSlider setAutoresizingMask:CPViewWidthSizable];
// red value input box
_redValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask: CPViewMinXMargin];
[_redValue setEditable: YES];
[_redValue setBezeled: YES];
[_redValue setDelegate: self];
[_contentView addSubview: _redValue];
_redValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask:CPViewMinXMargin];
[_redValue setEditable:YES];
[_redValue setBezeled:YES];
[_redValue setDelegate:self];
[_contentView addSubview:_redValue];
_greenLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue: "G"];
_greenLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue:"G"];
[_greenLabel setTextColor:[CPColor blackColor]];
_greenSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue: 1.0];
[_greenSlider setMinValue: 0.0];
[_greenSlider setTarget: self];
[_greenSlider setAction: @selector(sliderChanged:)];
[_greenSlider setAutoresizingMask: CPViewWidthSizable];
_greenSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue:1.0];
[_greenSlider setMinValue:0.0];
[_greenSlider setTarget:self];
[_greenSlider setAction:@selector(sliderChanged:)];
[_greenSlider setAutoresizingMask:CPViewWidthSizable];
// green value input box
_greenValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask: CPViewMinXMargin];
[_greenValue setEditable: YES];
[_greenValue setBezeled: YES];
[_greenValue setDelegate: self];
[_contentView addSubview: _greenValue];
_greenValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask:CPViewMinXMargin];
[_greenValue setEditable:YES];
[_greenValue setBezeled:YES];
[_greenValue setDelegate:self];
[_contentView addSubview:_greenValue];
_blueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue: "B"];
_blueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue:"B"];
[_blueLabel setTextColor:[CPColor blackColor]];
_blueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue: 1.0];
[_blueSlider setMinValue: 0.0];
[_blueSlider setTarget: self];
[_blueSlider setAction: @selector(sliderChanged:)];
[_blueSlider setAutoresizingMask: CPViewWidthSizable];
_blueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue:1.0];
[_blueSlider setMinValue:0.0];
[_blueSlider setTarget:self];
[_blueSlider setAction:@selector(sliderChanged:)];
[_blueSlider setAutoresizingMask:CPViewWidthSizable];
// blue value input box
_blueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask: CPViewMinXMargin];
[_blueValue setEditable: YES];
[_blueValue setBezeled: YES];
[_blueValue setDelegate: self];
[_contentView addSubview: _blueValue];
_blueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask:CPViewMinXMargin];
[_blueValue setEditable:YES];
[_blueValue setBezeled:YES];
[_blueValue setDelegate:self];
[_contentView addSubview:_blueValue];
_hsbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
_hsbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue:"Hue, Saturation, Brightness"];
[_hsbLabel setTextColor:[CPColor blackColor]];
_hueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue: "H"];
_hueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue:"H"];
[_hueLabel setTextColor:[CPColor blackColor]];
_hueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue: 359.0];
[_hueSlider setMinValue: 0.0];
[_hueSlider setTarget: self];
[_hueSlider setAction: @selector(sliderChanged:)];
[_hueSlider setAutoresizingMask: CPViewWidthSizable];
_hueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue:359.0];
[_hueSlider setMinValue:0.0];
[_hueSlider setTarget:self];
[_hueSlider setAction:@selector(sliderChanged:)];
[_hueSlider setAutoresizingMask:CPViewWidthSizable];
// hue value input box
_hueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask: CPViewMinXMargin];
[_hueValue setEditable: YES];
[_hueValue setBezeled: YES];
[_hueValue setDelegate: self];
[_contentView addSubview: _hueValue];
_hueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask:CPViewMinXMargin];
[_hueValue setEditable:YES];
[_hueValue setBezeled:YES];
[_hueValue setDelegate:self];
[_contentView addSubview:_hueValue];
_saturationLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue: "S"];
_saturationLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue:"S"];
[_saturationLabel setTextColor:[CPColor blackColor]];
_saturationSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue: 100.0];
[_saturationSlider setMinValue: 0.0];
[_saturationSlider setTarget: self];
[_saturationSlider setAction: @selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask: CPViewWidthSizable];
_saturationSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue:100.0];
[_saturationSlider setMinValue:0.0];
[_saturationSlider setTarget:self];
[_saturationSlider setAction:@selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask:CPViewWidthSizable];
// saturation value input box
_saturationValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask: CPViewMinXMargin];
[_saturationValue setEditable: YES];
[_saturationValue setBezeled: YES];
[_saturationValue setDelegate: self];
[_contentView addSubview: _saturationValue];
_saturationValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask:CPViewMinXMargin];
[_saturationValue setEditable:YES];
[_saturationValue setBezeled:YES];
[_saturationValue setDelegate:self];
[_contentView addSubview:_saturationValue];
_brightnessLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue: "B"];
_brightnessLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue:"B"];
[_brightnessLabel setTextColor:[CPColor blackColor]];
_brightnessSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue: 100.0];
[_brightnessSlider setMinValue: 0.0];
[_brightnessSlider setTarget: self];
[_brightnessSlider setAction: @selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask: CPViewWidthSizable];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue:100.0];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setTarget:self];
[_brightnessSlider setAction:@selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable];
// brightness value input box
_brightnessValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask: CPViewMinXMargin];
[_brightnessValue setEditable: YES];
[_brightnessValue setBezeled: YES];
[_brightnessValue setDelegate: self];
[_contentView addSubview: _brightnessValue];
_brightnessValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask:CPViewMinXMargin];
[_brightnessValue setEditable:YES];
[_brightnessValue setBezeled:YES];
[_brightnessValue setDelegate:self];
[_contentView addSubview:_brightnessValue];
_hexLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue: "Hex"];
_hexLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue:"Hex"];
[_hexLabel setTextColor:[CPColor blackColor]];
//hex input box
_hexValue = [[CPTextField alloc] initWithFrame: CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable: YES];
[_hexValue setBezeled: YES];
[_hexValue setDelegate: self];
[_contentView addSubview: _hexValue];
_hexValue = [[CPTextField alloc] initWithFrame:CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable:YES];
[_hexValue setBezeled:YES];
[_hexValue setDelegate:self];
[_contentView addSubview:_hexValue];
[_contentView addSubview: _rgbLabel];
[_contentView addSubview: _redLabel];
[_contentView addSubview: _greenLabel];
[_contentView addSubview: _blueLabel];
[_contentView addSubview: _redSlider];
[_contentView addSubview: _greenSlider];
[_contentView addSubview: _blueSlider];
[_contentView addSubview:_rgbLabel];
[_contentView addSubview:_redLabel];
[_contentView addSubview:_greenLabel];
[_contentView addSubview:_blueLabel];
[_contentView addSubview:_redSlider];
[_contentView addSubview:_greenSlider];
[_contentView addSubview:_blueSlider];
[_contentView addSubview: _hsbLabel];
[_contentView addSubview: _hueLabel];
[_contentView addSubview: _saturationLabel];
[_contentView addSubview: _brightnessLabel];
[_contentView addSubview: _hueSlider];
[_contentView addSubview: _saturationSlider];
[_contentView addSubview: _brightnessSlider];
[_contentView addSubview:_hsbLabel];
[_contentView addSubview:_hueLabel];
[_contentView addSubview:_saturationLabel];
[_contentView addSubview:_brightnessLabel];
[_contentView addSubview:_hueSlider];
[_contentView addSubview:_saturationSlider];
[_contentView addSubview:_brightnessSlider];
[_contentView addSubview: _hexLabel];
[_contentView addSubview:_hexLabel];
}
- (CPView)provideNewView:(BOOL)initialRequest
@@ -250,35 +250,35 @@
{
case _hueSlider:
case _saturationSlider:
case _brightnessSlider: newColor = [CPColor colorWithHue: [_hueSlider floatValue]
saturation: [_saturationSlider floatValue]
brightness: [_brightnessSlider floatValue]
alpha: alpha];
case _brightnessSlider: newColor = [CPColor colorWithHue:[_hueSlider floatValue]
saturation:[_saturationSlider floatValue]
brightness:[_brightnessSlider floatValue]
alpha:alpha];
[self updateRGBSliders: newColor];
[self updateRGBSliders:newColor];
break;
case _redSlider:
case _greenSlider:
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider floatValue]
green: [_greenSlider floatValue]
blue: [_blueSlider floatValue]
alpha: alpha];
case _blueSlider: newColor = [CPColor colorWithCalibratedRed:[_redSlider floatValue]
green:[_greenSlider floatValue]
blue:[_blueSlider floatValue]
alpha:alpha];
[self updateHSBSliders: newColor];
[self updateHSBSliders:newColor];
break;
}
[self updateLabels];
[self updateHex: newColor];
[colorPanel setColor: newColor];
[self updateHex:newColor];
[colorPanel setColor:newColor];
}
- (void)setColor:(CPColor)aColor
{
[self updateRGBSliders: aColor];
[self updateHSBSliders: aColor];
[self updateHex: aColor];
[self updateRGBSliders:aColor];
[self updateHSBSliders:aColor];
[self updateHex:aColor];
[self updateLabels];
}
@@ -307,13 +307,13 @@
- (void)updateLabels
{
[_hueValue setStringValue: ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue: ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue: ROUND([_brightnessSlider floatValue])];
[_hueValue setStringValue:ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue:ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue])];
[_redValue setStringValue: ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue: ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue: ROUND([_blueSlider floatValue] * 255)];
[_redValue setStringValue:ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue:ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue:ROUND([_blueSlider floatValue] * 255)];
}
- (CPImage)provideNewButtonImage
@@ -333,12 +333,12 @@
if (field === _hexValue)
{
var newColor = [CPColor colorWithHexString: value];
var newColor = [CPColor colorWithHexString:value];
if (newColor)
{
[self setColor: newColor];
[[self colorPanel] setColor: newColor];
[self setColor:newColor];
[[self colorPanel] setColor:newColor];
}
}
else
@@ -346,27 +346,27 @@
switch (field)
{
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _redSlider];
[self sliderChanged:_redSlider];
break;
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _greenSlider];
[self sliderChanged:_greenSlider];
break;
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _blueSlider];
[self sliderChanged:_blueSlider];
break;
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360), 0)];
[self sliderChanged: _hueSlider];
[self sliderChanged:_hueSlider];
break;
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
[self sliderChanged: _saturationSlider];
[self sliderChanged:_saturationSlider];
break;
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
[self sliderChanged: _brightnessSlider];
[self sliderChanged:_brightnessSlider];
break;
}
}
+93 -24
View File
@@ -89,7 +89,7 @@ var CPSplitViewHorizontalImage = nil,
CPString _autosaveName;
BOOL _shouldAutosave;
BOOL _needsRestoreFromAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
@@ -452,9 +452,13 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseUp)
{
// We disabled autosaving during tracking.
_shouldAutosave = YES;
if (_currentDivider != CPNotFound)
{
_currentDivider = CPNotFound;
[self _autosave];
[self _updateResizeCursor:anEvent];
}
@@ -481,19 +485,19 @@ var CPSplitViewHorizontalImage = nil,
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
_preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i]])
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:minPosition ofDividerAtIndex: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]])
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:maxPosition ofDividerAtIndex:i];
}
@@ -503,6 +507,8 @@ var CPSplitViewHorizontalImage = nil,
_currentDivider = i;
_initialOffset = startPosition - point[_originComponent];
// Don't autosave during a resize. We'll wait until it's done.
_shouldAutosave = NO;
[self _postNotificationWillResize];
}
}
@@ -717,6 +723,10 @@ var CPSplitViewHorizontalImage = nil,
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
// Any manual changes to the divider position should override anything we are restoring from
// autosave.
_shouldRestoreFromAutosaveUnlessFrameSize = nil;
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(YES);
[self _adjustSubviewsWithCalculatedSize];
@@ -725,13 +735,13 @@ var CPSplitViewHorizontalImage = nil,
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame],
_preCollapsePosition = 0,
preCollapsePosition = 0,
preSize = frameA.size[_sizeComponent];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
preCollapsePosition = preSize;
if (preSize !== frameA.size[_sizeComponent])
{
@@ -746,7 +756,7 @@ var CPSplitViewHorizontalImage = nil,
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
if (preSize !== 0 && frameB.size[_sizeComponent] === 0)
_preCollapsePosition = frameB.origin[_originComponent];
preCollapsePosition = frameB.origin[_originComponent];
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
@@ -757,8 +767,8 @@ var CPSplitViewHorizontalImage = nil,
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
if (_preCollapsePosition)
[_preCollapsePositions setObject:_preCollapsePosition forKey:"" + dividerIndex];
if (preCollapsePosition)
[_preCollapsePositions setObject:preCollapsePosition forKey:"" + dividerIndex];
[self setNeedsDisplay:YES];
@@ -770,19 +780,15 @@ var CPSplitViewHorizontalImage = nil,
- (void)setFrameSize:(CGSize)aSize
{
if (_needsRestoreFromAutosave)
if (_shouldRestoreFromAutosaveUnlessFrameSize)
_shouldAutosave = NO;
else
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
if (_needsRestoreFromAutosave)
{
_needsRestoreFromAutosave = NO;
[self _restoreFromAutosave];
if (_shouldRestoreFromAutosaveUnlessFrameSize)
_shouldAutosave = YES;
}
[self setNeedsDisplay:YES];
}
@@ -1028,13 +1034,31 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationWillResize
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self];
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
object:self
userInfo:userInfo];
}
- (void)_postNotificationDidResize
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
object:self
userInfo:userInfo];
// TODO Cocoa always autosaves on "viewDidEndLiveResize". If Cappuccino adds support for this we
// should do the same.
[self _autosave];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
}
/*!
@@ -1053,7 +1077,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
/*!
Get the name under which the split view divider position is automatically saved to CPUserDefaults.
@return the name to save under or nil if no auto save is active
@return the name to save under or nil if no autosave is active
*/
- (CPString)autosaveName
{
@@ -1065,7 +1089,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
*/
- (void)_autosave
{
if (!_shouldAutosave || !_autosaveName)
if (_shouldRestoreFromAutosaveUnlessFrameSize || !_shouldAutosave || !_autosaveName)
return;
var userDefaults = [CPUserDefaults standardUserDefaults],
@@ -1086,6 +1110,22 @@ The sum of the views and the sum of the dividers should be equal to the size of
[userDefaults setObject:preCollapseArray forKey:autosavePrecollapseName];
}
/*!
This is called sometime later after a split view has been restored from a Cib.
See notes in initWithCoder.
@ignore
*/
- (void)_restoreFromAutosaveIfNeeded
{
if (_shouldRestoreFromAutosaveUnlessFrameSize && !_CGSizeEqualToSize([self frameSize], _shouldRestoreFromAutosaveUnlessFrameSize))
{
[self _restoreFromAutosave];
}
_shouldRestoreFromAutosaveUnlessFrameSize = nil;
}
/*!
@ignore
*/
@@ -1167,6 +1207,34 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
*/
- (id)initWithCoder:(CPCoder)aCoder
{
// We need to restore this property before calling super's initWithCoder:.
_autosaveName = [aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey];
/*
It is common for the main window of a Cappuccino app window to be resized to match the browser
window size at the end of the UI being loaded from a cib. But at decoding time (now) whatever
window size was originally saved will be in place, so if we try to restore the autosaved divider
positions now they might be constrained to the wrong positions due to the difference in frame size,
and in addition they might move later when the window is resized.
The workaround is to restore the position once now (so it's approximately correct during loading),
and then once more in the next runloop cycle when any `setFullPlatformWindow` calls are done.
(However if the frame size doesn't change before the next cycle, we should not restore the position
again because that would overwrite any changes the app developer might have made in user code.)
The other consideration is that any parent split views need to be restored before any child
subviews, otherwise the parent restore will also change the positioning of the child.
*/
if (_autosaveName)
{
// Schedule /before/ [super initWithCoder:]. This way this instance's _restoreFromAutosaveIfNeeded
// will happen before that of any subviews loaded by [super initWithCoder:].
[[CPRunLoop currentRunLoop] performSelector:@selector(_restoreFromAutosaveIfNeeded) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
self = [super initWithCoder:aCoder];
if (self)
@@ -1186,12 +1254,13 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
[self setAutosaveName:[aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey]];
// We have to wait until we know our frame size before restoring, or the frame resize later will throw
// away the restored size.
if (_autosaveName)
_needsRestoreFromAutosave = YES;
{
[self _restoreFromAutosave];
// Remember the frame size we had at this point so that we can restore again if it changes
// before the next runloop cycle. See above notes.
_shouldRestoreFromAutosaveUnlessFrameSize = [self frameSize];
}
}
return self;
+3 -2
View File
@@ -498,12 +498,13 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
If NO the tablecolumn will no longer be visible in the tableview
If YES the tablecolumn will be visible in the tableview.
If YES the tablecolumn will no longer be visible in the tableview.
If NO the tablecolumn will be visible in the tableview.
*/
- (void)setHidden:(BOOL)shouldBeHidden
{
shouldBeHidden = !!shouldBeHidden
if (_isHidden === shouldBeHidden)
return;
+3 -3
View File
@@ -40,7 +40,7 @@
+ (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"]];
forKeys:[@"background-color", @"text-alignment", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
}
- (void)initWithFrame:(CGRect)frame
@@ -74,7 +74,7 @@
[_textField setFrame:_CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
[_textField setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
[_textField setFont:[self currentValueForThemeAttribute:@"text-font"]];
[_textField setFont:[self currentValueForThemeAttribute:@"font"]];
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
[_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
@@ -102,7 +102,7 @@
- (void)setFont:(CPFont)aFont
{
[self setValue:aFont forThemeAttribute:"text-font"];
[self setValue:aFont forThemeAttribute:"font"];
}
- (void)_setIndicatorImage:(CPImage)anImage
+79 -20
View File
@@ -239,6 +239,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap;
BOOL _implementsCustomDrawRow;
BOOL _contentBindingExpicitelySet;
CPTableColumn _draggedColumn;
CPArray _differedColumnDataToRemove;
@@ -305,6 +306,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil;
_dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
_contentBindingExpicitelySet = NO;
[self setBackgroundColor:[CPColor whiteColor]];
[self _init];
@@ -344,6 +346,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_exposedRows = [CPIndexSet indexSet];
_exposedColumns = [CPIndexSet indexSet];
_cachedDataViews = { };
_cachedRowHeights = [];
_groupRows = [CPIndexSet indexSet];
@@ -723,7 +726,7 @@ NOT YET IMPLEMENTED
- (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors
{
[self setValue:alternatingRowBackgroundColors forThemeAttribute:"alternating-row-colors"];
[self setValue:alternatingRowBackgroundColors forThemeAttribute:@"alternating-row-colors"];
[self setNeedsDisplay:YES];
}
@@ -781,7 +784,7 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionHighlightColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:"selection-color"];
[self setValue:aColor forThemeAttribute:@"selection-color"];
[self setNeedsDisplay:YES];
}
@@ -807,7 +810,7 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionGradientColors:(CPDictionary)aDictionary
{
[self setValue:aDictionary forThemeAttribute:"sourcelist-selection-color"];
[self setValue:aDictionary forThemeAttribute:@"sourcelist-selection-color"];
[self setNeedsDisplay:YES];
}
@@ -831,7 +834,7 @@ NOT YET IMPLEMENTED
*/
- (void)setGridColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:"grid-color"];
[self setValue:aColor forThemeAttribute:@"grid-color"];
[self setNeedsDisplay:YES];
}
@@ -975,6 +978,13 @@ NOT YET IMPLEMENTED
columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)];
[self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
// Notify even if programmatically moving a column as in Cocoa.
// TODO Only notify when a column drag operation ends, not each time a column reaches a new slot?
[[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewColumnDidMoveNotification
object:self
userInfo:[CPDictionary dictionaryWithObjects:[fromIndex, toIndex]
forKeys:[@"CPOldColumn", @"CPNewColumn"]]];
}
/*!
@@ -2725,7 +2735,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)_tableHeaderSortImage
{
return [self currentValueForThemeAttribute:"sort-image"];
return [self currentValueForThemeAttribute:@"sort-image"];
}
/*!
@@ -2733,7 +2743,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)_tableHeaderReverseSortImage
{
return [self currentValueForThemeAttribute:"sort-image-reversed"];
return [self currentValueForThemeAttribute:@"sort-image-reversed"];
}
/*!
@@ -2823,11 +2833,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn];
[dataView setFrame:[self frameOfDataViewAtColumn:columnIndex row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
// If the column uses content bindings, allow them to override the objectValueForTableColumn.
[tableColumn _prepareDataView:dataView forRow:row];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
[view addSubview:dataView];
row = [theDraggedRows indexGreaterThanIndex:row];
@@ -2868,7 +2875,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
[dataView setFrame:dataViewFrame];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
[dragView addSubview:dataView];
row = [_exposedRows indexGreaterThanIndex:row];
@@ -3267,11 +3274,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
isTextField = [dataView isKindOfClass:[CPTextField class]];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
[tableColumn _prepareDataView:dataView forRow:row];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
if (isColumnSelected || [self isRowSelected:row])
[dataView setThemeState:CPThemeStateSelectedDataView];
@@ -3329,6 +3333,30 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
}
- (void)_setObjectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(CPView)aDataView
{
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_)
[aDataView setObjectValue:[self _objectValueForTableColumn:aTableColumn row:aRow]];
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
if (_contentBindingExpicitelySet)
[self _prepareContentBindedDataView:aDataView forRow:aRow];
else
// For both cell-based and view-based
[aTableColumn _prepareDataView:aDataView forRow:aRow];
}
- (void)_prepareContentBindedDataView:(CPView)dataView forRow:(CPInteger)aRow
{
var binder = [CPTableContentBinder getBinding:@"content" forObject:self],
content = [binder content],
rowContent = [content objectAtIndex:aRow];
[dataView setObjectValue:rowContent];
}
/*!
@ignore
*/
@@ -3374,7 +3402,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
If the dataview resigning triggers the action (as CPTextField does), we come right
back here and start an infinite loop. So we have to check this flag first.
*/
if (_editingCellIndex === nil)
if ([sender respondsToSelector:@selector(sendsActionOnEndEditing)] && [sender sendsActionOnEndEditing] && _editingCellIndex === nil)
return;
_editingCellIndex = nil;
@@ -3840,7 +3868,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
CGContextClosePath(context);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:"highlighted-grid-color"]);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"highlighted-grid-color"]);
CGContextStrokePath(context);
}
@@ -4730,6 +4758,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
@implementation CPTableView (Bindings)
+ (id)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == @"content")
return [CPTableContentBinder class];
return [super _binderClassForBinding:aBinding];
}
/*!
@ignore
*/
@@ -4747,7 +4783,10 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
- (void)_establishBindingsIfUnbound:(id)destination
{
if ([[self infoForBinding:@"content"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
{
[super bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
_contentBindingExpicitelySet = NO;
}
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
@@ -4755,9 +4794,29 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
//[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
}
- (void)setContent:(CPArray)content
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
[self reloadData];
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (aBinding == @"content")
_contentBindingExpicitelySet = YES;
}
@end
@implementation CPTableContentBinder : CPBinder
{
id _content @accessors(property=content);
}
- (void)setValueFor:(id)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey];
_content = [destination valueForKey:keyPath];
[_source reloadData];
}
@end
+18 -29
View File
@@ -486,10 +486,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#if PLATFORM(DOM)
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont];
element.value = _stringValue;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
@@ -511,26 +509,26 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
switch (verticalAlign)
{
case CPTopVerticalTextAlignment:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px"; // for the same reason we have a -1 for the left, we also have a + 1 here
var topPoint = _CGRectGetMinY(contentRect) + "px";
break;
case CPCenterVerticalTextAlignment:
var topPoint = (_CGRectGetMidY(contentRect) - (font._lineHeight / 2) + 1) + "px";
var topPoint = (_CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
break;
case CPBottomVerticalTextAlignment:
var topPoint = (_CGRectGetMaxY(contentRect) - font._lineHeight) + "px";
var topPoint = (_CGRectGetMaxY(contentRect) - lineHeight) + "px";
break;
default:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px";
var topPoint = _CGRectGetMinY(contentRect) + "px";
break;
}
element.style.top = topPoint;
element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // why -1?
element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // -1 because input element seems to have 1px left inset
element.style.width = _CGRectGetWidth(contentRect) + "px";
element.style.height = font._lineHeight + "px"; // private ivar for the line height of the DOM text at this particular size
element.style.height = lineHeight + "px";
_DOMElement.appendChild(element);
@@ -1044,8 +1042,16 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
textSize = [text sizeWithFont:font inWidth:textSize.width];
}
else
{
textSize = [text sizeWithFont:font];
// Account for possible fractional pixels at right edge
textSize.width += 1;
}
// Account for possible fractional pixels at bottom edge
textSize.height += 1;
frameSize.height = textSize.height + contentInset.top + contentInset.bottom;
if ([self isBezeled])
@@ -1315,30 +1321,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
if (!contentInset)
return bounds;
bounds.origin.x += contentInset.left;
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (_CGInsetIsEmpty(bezelInset))
return bounds;
bounds.origin.x += bezelInset.left;
bounds.origin.y += bezelInset.top;
bounds.size.width -= bezelInset.left + bezelInset.right;
bounds.size.height -= bezelInset.top + bezelInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
@@ -1365,7 +1355,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
else
{
var view = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
//[view setImagePosition:CPNoImage];
[view setHitTests:NO];
+35 -8
View File
@@ -90,6 +90,11 @@ var CPScrollDestinationNone = 0,
return "tokenfield";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObject:_CGInsetMakeZero() forKey:@"editor-inset"];
}
- (id)initWithFrame:(CPRect)frame
{
if (self = [super initWithFrame:frame])
@@ -179,6 +184,7 @@ var CPScrollDestinationNone = 0,
// Give the delegate a chance to confirm, replace or add to the list of tokens being added.
var delegateApprovedObjects = [self _shouldAddObjects:[CPArray arrayWithObject:token] atIndex:_selectedRange.location],
delegateApprovedObjectsCount = [delegateApprovedObjects count];
if (delegateApprovedObjects)
{
for (var i = 0; i < delegateApprovedObjectsCount; i++)
@@ -313,11 +319,12 @@ var CPScrollDestinationNone = 0,
#if PLATFORM(DOM)
var string = [self stringValue],
element = [self _inputElement];
element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
element.value = nil;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [[self currentValueForThemeAttribute:@"font"] cssString];
element.style.font = [font cssString];
element.style.zIndex = 1000;
switch ([self alignment])
@@ -332,9 +339,9 @@ var CPScrollDestinationNone = 0,
var contentRect = [self contentRectForBounds:[self bounds]];
element.style.top = CGRectGetMinY(contentRect) + "px";
element.style.left = (CGRectGetMinX(contentRect) - 1) + "px"; // why -1?
element.style.left = (CGRectGetMinX(contentRect) - 1) + "px"; // <input> element effectively imposes a 1px left margin
element.style.width = CGRectGetWidth(contentRect) + "px";
element.style.height = CGRectGetHeight(contentRect) + "px";
element.style.height = [font defaultLineHeightForFont] + "px";
[_tokenScrollView documentView]._DOMElement.appendChild(element);
@@ -472,6 +479,7 @@ var CPScrollDestinationNone = 0,
- (id)objectValue
{
var objectValue = [];
for (var i = 0, count = [[self _tokens] count]; i < count; i++)
{
var token = [[self _tokens] objectAtIndex:i];
@@ -570,6 +578,20 @@ var CPScrollDestinationNone = 0,
[self setNeedsDisplay:YES];
}
- (void)setEnabled:(BOOL)shouldBeEnabled
{
[super setEnabled:shouldBeEnabled];
// Set the enabled state of the tokens
for (var i = 0, count = [[self _tokens] count]; i < count; i++)
{
var token = [[self _tokens] objectAtIndex:i];
if ([token respondsToSelector:@selector(setEnabled:)])
[token setEnabled:shouldBeEnabled];
}
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
_shouldNotifyTarget = NO;
@@ -962,7 +984,10 @@ var CPScrollDestinationNone = 0,
offset = CPPointMake(contentOrigin.x, contentOrigin.y),
spaceBetweenTokens = CPSizeMake(2.0, 2.0),
isEditing = [[self window] firstResponder] == self,
tokenToken = [_CPTokenFieldToken new];
tokenToken = [_CPTokenFieldToken new],
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont],
editorInset = [self currentValueForThemeAttribute:@"editor-inset"];
// Get the height of a typical token, or a token token if you will.
[tokenToken sizeToFit];
@@ -1001,15 +1026,17 @@ var CPScrollDestinationNone = 0,
// XXX The "X" here is used to estimate the space needed to fit the next character
// without clipping. Since different fonts might have different sizes of "X" this
// solution is not ideal, but it works.
textWidth = [(element.value || @"") + "X" sizeWithFont:[self font]].width;
textWidth = [(element.value || @"") + "X" sizeWithFont:font].width;
if (useRemainingWidth)
textWidth = MAX(contentSize.width - offset.x - 1, textWidth);
}
_inputFrame = fitAndFrame(textWidth, tokenHeight);
_inputFrame.size.height = lineHeight;
element.style.left = _inputFrame.origin.x + "px";
element.style.top = _inputFrame.origin.y + "px";
element.style.left = (_inputFrame.origin.x + editorInset.left) + "px";
element.style.top = (_inputFrame.origin.y + editorInset.top) + "px";
element.style.width = _inputFrame.size.width + "px";
element.style.height = _inputFrame.size.height + "px";
+15 -6
View File
@@ -21,14 +21,14 @@
*/
@import <Foundation/CPArray.j>
@import <Foundation/CPGeometry.j>
@import <Foundation/CPObjJRuntime.j>
@import <Foundation/CPSet.j>
@import "CGAffineTransform.j"
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPGeometry.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@import "CPTheme.j"
@@ -246,8 +246,8 @@ var CPCurrentToolTip,
- (void)_setupToolTipHandlers
{
_toolTipInstalled = NO;
_toolTipFunctionIn = function(e){[self _fireToolTip];}
_toolTipFunctionOut = function(e){[self _invalidateToolTip];};
_toolTipFunctionIn = function(e) { [self _fireToolTip]; }
_toolTipFunctionOut = function(e) { [self _invalidateToolTip]; };
}
+ (CPSet)keyPathsForValuesAffectingFrame
@@ -353,6 +353,7 @@ var CPCurrentToolTip,
if (_toolTipInstalled)
return;
#if PLATFORM(DOM)
if (_DOMElement.addEventListener)
{
_DOMElement.addEventListener("mouseover", _toolTipFunctionIn, NO);
@@ -365,6 +366,8 @@ var CPCurrentToolTip,
_DOMElement.attachEvent("onkeypress", _toolTipFunctionOut);
_DOMElement.attachEvent("onmouseout", _toolTipFunctionOut);
}
#endif
_toolTipInstalled = YES;
}
@@ -377,6 +380,7 @@ var CPCurrentToolTip,
if (!_toolTipInstalled)
return;
#if PLATFORM(DOM)
if (_DOMElement.removeEventListener)
{
_DOMElement.removeEventListener("mouseover", _toolTipFunctionIn, NO);
@@ -389,6 +393,8 @@ var CPCurrentToolTip,
_DOMElement.detachEvent("onkeypress", _toolTipFunctionOut);
_DOMElement.detachEvent("onmouseout", _toolTipFunctionOut);
}
#endif
_toolTipInstalled = NO;
}
@@ -400,8 +406,10 @@ var CPCurrentToolTip,
if (CPCurrentToolTipTimer)
{
[CPCurrentToolTipTimer invalidate];
if (CPCurrentToolTip)
[CPCurrentToolTip close];
CPCurrentToolTip = nil;
}
@@ -434,6 +442,7 @@ var CPCurrentToolTip,
{
if (CPCurrentToolTip)
[CPCurrentToolTip close];
CPCurrentToolTip = [_CPToolTip toolTipWithString:_toolTip];
}
@@ -769,7 +778,7 @@ var CPCurrentToolTip,
}
/*!
Called when the receiver is about to be remove one of its subviews.
Called when the receiver is about to remove one of its subviews.
@param aView the view that will be removed
*/
- (void)willRemoveSubview:(CPView)aView
@@ -840,7 +849,7 @@ var CPCurrentToolTip,
/*!
Sets the frame size of the receiver to the dimensions and origin of the provided rectangle in the coordinate system
of the superview. The method also posts an CPViewFrameDidChangeNotification to the notification
of the superview. The method also posts a CPViewFrameDidChangeNotification to the notification
center if the receiver is configured to do so. If the frame is the same as the current frame, the method simply
returns (and no notification is posted).
@param aFrame the rectangle specifying the new origin and size of the receiver
+1 -1
View File
@@ -127,7 +127,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setHitTests:NO];
[_titleField setFont:[CPFont systemFontOfSize:11.0]];
[_titleField setFont:[CPFont systemFontOfSize:[CPFont systemFontSize] - 1]];
[_titleField setTextColor:[CPColor whiteColor]];
[_titleField setTextShadowColor:[CPColor blackColor]];
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
+1 -1
View File
@@ -244,7 +244,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:12.0]];
[_titleField setFont:[CPFont boldSystemFontOfSize:CPFontCurrentSystemSize]];
[_titleField setAutoresizingMask:CPViewWidthSizable];
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
+69 -13
View File
@@ -33,7 +33,7 @@
@class CPWindowController
An instance of a CPWindowController manages a CPWindow. Windows are typically loaded via a cib,
but they can also manage windows created in code. A CPWindowController can manage a window by
but they can also manage windows created in code. A CPWindowController can manage a window by
itself or work with AppKits's document-based architecture.
In a Document based app, a CPWindowController instance is created and managed by a CPDocument subclass.
@@ -333,6 +333,38 @@
- (void)setViewControllerContainerView:(CPView)aView
{
if (!_viewControllerContainerView && !aView)
return;
var viewControllerView = [[self viewController] view],
contentView = [[self window] contentView];
if (aView)
{
[aView setFrame:[contentView frame]];
[aView setAutoresizingMask:[contentView autoresizingMask]];
if (viewControllerView)
{
[viewControllerView removeFromSuperview];
[aView addSubview:viewControllerView];
}
[[self window] setContentView:aView];
}
else if (viewControllerView)
{
[viewControllerView removeFromSuperview];
[viewControllerView setFrame:[contentView frame]];
[viewControllerView setAutoresizingMask:[contentView autoresizingMask]]
[[self window] setContentView:viewControllerView];
}
else
{
var view = [[CPView alloc] init];
[view setFrame:[contentView frame]];
[view setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:view]
}
_viewControllerContainerView = aView;
}
@@ -343,21 +375,45 @@
- (void)setViewController:(CPViewController)aViewController
{
var containerView = [self viewControllerContainerView] || [[self window] contentView],
view = [_viewController view],
frame = view ? [view frame] : [containerView bounds];
if (!_viewController && !aViewController)
return;
[view removeFromSuperview];
var containerView = [self viewControllerContainerView],
newView = [aViewController view];
if (containerView)
{
var oldView = [_viewController view];
if (oldView)
{
[newView setFrame:[oldView frame]];
[newView setAutoresizingMask:[oldView autoresizingMask]];
}
if (oldView && newView)
[containerView replaceSubview:oldView with:newView];
else if (oldView)
[oldView removeFromSuperview];
else if (newView)
[containerView addSubview:newView];
}
else if (newView)
{
var contentView = [[self window] contentView];
[newView setFrame:[contentView frame]];
[newView setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:newView];
}
else
{
var view = [[CPView alloc] init],
contentView = [[self window] contentView];
[view setFrame:[contentView frame]];
[view setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:view]
}
_viewController = aViewController;
view = [_viewController view];
if (view)
{
[view setFrame:frame];
[containerView addSubview:view];
}
}
- (CPViewController)viewController
+1 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGGeometry.h"
#include "../../Foundation/_CGGeometry.h"
#define _CGAffineTransformMake(a_, b_, c_, d_, tx_, ty_) { a:a_, b:b_, c:c_, d:d_, tx:tx_, ty:ty_ }
#define _CGAffineTransformMakeIdentity() _CGAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
+3 -292
View File
@@ -2,8 +2,8 @@
* CGGeometry.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
* Created by Alexander Ljungberg.
* Copyright 2012, SlevenBits Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,293 +20,4 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _function(inline) function inline { return _##inline; }
_function(CGPointMake(x, y))
_function(CGPointMakeZero())
_function(CGPointMakeCopy(aPoint))
_function(CGPointCreateCopy(aPoint))
_function(CGPointEqualToPoint(lhsPoint, rhsPoint))
_function(CGStringFromPoint(aPoint))
_function(CGSizeMake(width, height))
_function(CGSizeMakeZero())
_function(CGSizeMakeCopy(aSize))
_function(CGSizeCreateCopy(aSize))
_function(CGSizeEqualToSize(lhsSize, rhsSize))
_function(CGStringFromSize(aSize))
_function(CGRectMake(x, y, width, height))
_function(CGRectMakeZero())
_function(CGRectMakeCopy(aRect))
_function(CGRectCreateCopy(aRect))
_function(CGRectEqualToRect(lhsRect, rhsRect))
_function(CGStringFromRect(aRect))
_function(CGRectOffset(aRect, dX, dY))
_function(CGRectInset(aRect, dX, dY))
_function(CGRectGetHeight(aRect))
_function(CGRectGetMaxX(aRect))
_function(CGRectGetMaxY(aRect))
_function(CGRectGetMidX(aRect))
_function(CGRectGetMidY(aRect))
_function(CGRectGetMinX(aRect))
_function(CGRectGetMinY(aRect))
_function(CGRectGetWidth(aRect))
_function(CGRectIsEmpty(aRect))
_function(CGRectIsNull(aRect))
_function(CGRectContainsPoint(aRect, aPoint))
_function(CGInsetMake(top, right, bottom, left))
_function(CGInsetMakeZero())
_function(CGInsetMakeCopy(anInset))
_function(CGInsetIsEmpty(anInset))
_function(CGInsetEqualToInset(lhsInset, rhsInset))
CGMinXEdge = 0;
CGMinYEdge = 1;
CGMaxXEdge = 2;
CGMaxYEdge = 3;
CGRectNull = _CGRectMake(Infinity, Infinity, 0.0, 0.0);
/*!
@addtogroup appkit
@{
*/
/*!
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
contains CGRect \c rhsRect.
@group CGRect
@param lhsRect the CGRect to test if \c rhsRect is inside of
@param rhsRect the CGRect to test if it fits inside \c lhsRect.
@return BOOL \c YES if \c rhsRect fits inside \c lhsRect.
*/
function CGRectContainsRect(lhsRect, rhsRect)
{
var union = CGRectUnion(lhsRect, rhsRect);
return _CGRectEqualToRect(union, lhsRect);
}
/*!
Returns \c YES if the two rectangles intersect
@group CGRect
@param lhsRect the first CGRect
@param rhsRect the second CGRect
@return BOOL \c YES if the two rectangles have any common spaces, and \c NO, otherwise.
*/
function CGRectIntersectsRect(lhsRect, rhsRect)
{
var intersection = CGRectIntersection(lhsRect, rhsRect);
return !_CGRectIsEmpty(intersection);
}
/*!
Makes the origin and size of a CGRect all integers. Specifically, by making
the southwest corner the origin (rounded down), and the northeast corner a CGSize (rounded up).
@param aRect the rectangle to operate on
@return CGRect the modified rectangle (same as the input)
@group CGRect
*/
function CGRectIntegral(aRect)
{
aRect = CGRectStandardize(aRect);
// Store these out separately, if not the GetMaxes will return incorrect values.
var x = FLOOR(_CGRectGetMinX(aRect)),
y = FLOOR(_CGRectGetMinY(aRect));
aRect.size.width = CEIL(_CGRectGetMaxX(aRect)) - x;
aRect.size.height = CEIL(_CGRectGetMaxY(aRect)) - y;
aRect.origin.x = x;
aRect.origin.y = y;
return aRect;
}
/*!
Returns the intersection of the two provided rectangles as a new rectangle.
@param lhsRect the first rectangle used for calculation
@param rhsRect the second rectangle used for calculation
@return CGRect the intersection of the two rectangles
@group CGRect
*/
function CGRectIntersection(lhsRect, rhsRect)
{
var intersection = _CGRectMake(
MAX(_CGRectGetMinX(lhsRect), _CGRectGetMinX(rhsRect)),
MAX(_CGRectGetMinY(lhsRect), _CGRectGetMinY(rhsRect)),
0, 0);
intersection.size.width = MIN(_CGRectGetMaxX(lhsRect), _CGRectGetMaxX(rhsRect)) - _CGRectGetMinX(intersection);
intersection.size.height = MIN(_CGRectGetMaxY(lhsRect), _CGRectGetMaxY(rhsRect)) - _CGRectGetMinY(intersection);
return _CGRectIsEmpty(intersection) ? _CGRectMakeZero() : intersection;
}
/*
*/
function CGRectStandardize(aRect)
{
var width = _CGRectGetWidth(aRect),
height = _CGRectGetHeight(aRect),
standardized = _CGRectMakeCopy(aRect);
if (width < 0.0)
{
standardized.origin.x += width;
standardized.size.width = -width;
}
if (height < 0.0)
{
standardized.origin.y += height;
standardized.size.height = -height;
}
return standardized;
}
function CGRectUnion(lhsRect, rhsRect)
{
var lhsRectIsNull = !lhsRect || lhsRect === CGRectNull,
rhsRectIsNull = !rhsRect || rhsRect === CGRectNull;
if (lhsRectIsNull)
return rhsRectIsNull ? CGRectNull : rhsRect;
if (rhsRectIsNull)
return lhsRectIsNull ? CGRectNull : lhsRect;
var minX = MIN(_CGRectGetMinX(lhsRect), _CGRectGetMinX(rhsRect)),
minY = MIN(_CGRectGetMinY(lhsRect), _CGRectGetMinY(rhsRect)),
maxX = MAX(_CGRectGetMaxX(lhsRect), _CGRectGetMaxX(rhsRect)),
maxY = MAX(_CGRectGetMaxY(lhsRect), _CGRectGetMaxY(rhsRect));
return _CGRectMake(minX, minY, maxX - minX, maxY - minY);
}
function CGPointFromString(aString)
{
var comma = aString.indexOf(',');
return { x:parseFloat(aString.substr(1, comma - 1)), y:parseFloat(aString.substring(comma + 1, aString.length)) };
}
function CGSizeFromString(aString)
{
var comma = aString.indexOf(',');
return { width:parseFloat(aString.substr(1, comma - 1)), height:parseFloat(aString.substring(comma + 1, aString.length)) };
}
function CGRectFromString(aString)
{
var comma = aString.indexOf(',', aString.indexOf(',') + 1);
return { origin:CGPointFromString(aString.substr(1, comma - 1)), size:CGSizeFromString(aString.substring(comma + 2, aString.length)) };
}
function CGPointFromEvent(anEvent)
{
return _CGPointMake(anEvent.clientX, anEvent.clientY);
}
/*!
Combines two insets by adding their individual elements and returns the result.
@group CGInset
*/
function CGInsetUnion(lhsInset, rhsInset)
{
return _CGInsetMake(lhsInset.top + rhsInset.top,
lhsInset.right + rhsInset.right,
lhsInset.bottom + rhsInset.bottom,
lhsInset.left + rhsInset.left);
}
/*!
Subtract one inset from another by subtracting their individual elements and returns the result.
@group CGInset
*/
function CGInsetDifference(lhsInset, rhsInset)
{
return _CGInsetMake(lhsInset.top - rhsInset.top,
lhsInset.right - rhsInset.right,
lhsInset.bottom - rhsInset.bottom,
lhsInset.left - rhsInset.left);
}
function CGInsetFromString(aString)
{
var numbers = aString.substr(1, aString.length - 2).split(',');
return _CGInsetMake(parseFloat(numbers[0]), parseFloat(numbers[1]), parseFloat(numbers[2]), parseFloat(numbers[3]));
}
CGInsetFromCPString = CGInsetFromString;
function CPStringFromCGInset(anInset)
{
return '{' + anInset.top + ", " + anInset.left + ", " + anInset.bottom + ", " + anInset.right + '}';
}
/*!
@}
*/
@import <Foundation/_CGGeometry.j>
+11 -20
View File
@@ -33,6 +33,14 @@ var DOMFixedWidthSpanElement = nil,
{
}
+ (void)initialize
{
if (self !== [CPPlatformString class])
return;
DefaultFont = [CPFont systemFontOfSize:CPFontCurrentSystemSize];
}
+ (void)bootstrap
{
[self createDOMElements];
@@ -62,8 +70,7 @@ var DOMFixedWidthSpanElement = nil,
bodyElement.appendChild(DOMIFrameElement);
DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document);
DOMIFrameDocument.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head></head><body></body></html>');
DOMIFrameDocument.write('<!DOCTYPE html><head></head><body></body></html>');
DOMIFrameDocument.close();
// IE needs this wide <div> to prevent unwanted text wrapping:
@@ -151,14 +158,6 @@ var DOMFixedWidthSpanElement = nil,
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
{
if (!aFont)
{
if (!DefaultFont)
DefaultFont = [CPFont systemFontOfSize:12.0];
aFont = DefaultFont;
}
if (!DOMIFrameElement)
[self createDOMElements];
@@ -172,7 +171,7 @@ var DOMFixedWidthSpanElement = nil,
span.style.width = ROUND(aWidth) + "px";
}
span.style.font = [aFont cssString];
span.style.font = [(aFont || DefaultFont) cssString];
if (CPFeatureIsCompatible(CPJavaScriptInnerTextFeature))
span.innerText = aString;
@@ -184,18 +183,10 @@ var DOMFixedWidthSpanElement = nil,
+ (CPDictionary)metricsOfFont:(CPFont)aFont
{
if (!aFont)
{
if (!DefaultFont)
DefaultFont = [CPFont systemFontOfSize:12.0];
aFont = DefaultFont;
}
if (!DOMMetricsDivElement)
[self createDOMMetricsElements];
DOMMetricsDivElement.style.font = [aFont cssString];
DOMMetricsDivElement.style.font = [(aFont || DefaultFont) cssString];
var baseline = DOMMetricsImgElement.offsetTop - DOMMetricsTextSpanElement.offsetTop + DOMMetricsImgElement.offsetHeight,
descender = baseline - DOMMetricsTextSpanElement.offsetHeight,
Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 757 B

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 991 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 991 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 991 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1009 B

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 229 B

Some files were not shown because too many files have changed in this diff Show More