Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into scroll_before_focus_text_field

Conflicts:
	AppKit/CPTokenField.j
  • Loading branch information...
commit 82337b8baa33c09c8aaf4eb080ccd8ec4825461b 2 parents 7bf5f6f + 71b93a2
@mrcarlberg authored
Showing with 5,321 additions and 2,679 deletions.
  1. +1 −0  AppKit/CPAlert.j
  2. +11 −1 AppKit/CPApplication.j
  3. +35 −0 AppKit/CPBezierPath.j
  4. +20 −0 AppKit/CPBox.j
  5. +4 −0 AppKit/CPCollectionView.j
  6. +8 −0 AppKit/CPColor.j
  7. +15 −0 AppKit/CPFont.j
  8. +10 −0 AppKit/CPGraphics.j
  9. +34 −1 AppKit/CPGraphicsContext.j
  10. +8 −1 AppKit/CPKeyValueBinding.j
  11. +1 −2  AppKit/CPMenu/CPMenu.j
  12. +8 −1 AppKit/CPPopover.j
  13. +5 −5 AppKit/CPRuleEditor/_CPRuleEditorViewSlice.j
  14. +10 −1 AppKit/CPRuleEditor/_CPRuleEditorViewSliceRow.j
  15. +6 −1 AppKit/CPSearchField.j
  16. +35 −2 AppKit/CPStepper.j
  17. +1 −1  AppKit/CPTabViewItem.j
  18. +31 −1 AppKit/CPTableColumn.j
  19. +62 −4 AppKit/CPTableHeaderView.j
  20. +23 −7 AppKit/CPTableView.j
  21. +19 −7 AppKit/CPTextField.j
  22. +52 −24 AppKit/CPTokenField.j
  23. +8 −7 AppKit/CPToolbar.j
  24. +6 −53 AppKit/CPView.j
  25. +5 −0 AppKit/CPWebView.j
  26. +69 −3 AppKit/CPWindow/CPWindow.j
  27. +23 −12 AppKit/CPWindow/_CPAttachedWindowView.j
  28. +0 −32 AppKit/CPWindow/_CPStandardWindowView.j
  29. +24 −2 AppKit/CPWindow/_CPWindowView.j
  30. +1 −1  AppKit/CPWindowController.j
  31. +85 −65 AppKit/Cib/_CPCibWindowTemplate.j
  32. +10 −0 AppKit/CoreGraphics/CGContext.j
  33. +1 −1  AppKit/CoreGraphics/CGContextCanvas.j
  34. +2 −2 AppKit/CoreGraphics/CGContextVML.j
  35. +119 −0 AppKit/CoreGraphics/CGPath.j
  36. +4 −2 AppKit/Platform/DOM/CPPlatformWindow+DOM.j
  37. +3 −2 AppKit/Themes/Aristo/ThemeDescriptors.j
  38. +14 −1 AppKit/_CPAttachedWindow.j
  39. +8 −1 AppKit/_CPAutocompleteMenu.j
  40. +45 −27 AppKit/_CPImageAndTextView.j
  41. +44 −1 AppKit/_CPToolTip.j
  42. +12 −0 Foundation/CPGeometry.j
  43. +11 −13 Tests/Manual/ArrayController1/AppController.j
  44. +1 −0  Tests/Manual/AttachedSheet2/MainMenu.cib
  45. +1 −1  Tests/Manual/AttachedSheet2/Resources/MainMenu.cib
  46. +1 −1  Tests/Manual/AttachedSheet2/Resources/Window.cib
  47. +157 −119 Tests/Manual/AttachedSheet2/Resources/Window.xib
  48. +18 −2 Tests/Manual/AttachedSheet2/SheetWindowController.j
  49. +1 −0  Tests/Manual/AttachedSheet2/Window.cib
  50. +0 −5 Tests/Manual/CPButtonTest/AppController.j
  51. +1 −1  Tests/Manual/CPButtonTest/Resources/MainMenu.cib
  52. +2,256 −2,180 Tests/Manual/CPButtonTest/Resources/MainMenu.xib
  53. +33 −0 Tests/Manual/CPStepperBindings/AppController.j
  54. +10 −0 Tests/Manual/CPStepperBindings/Info.plist
  55. +94 −0 Tests/Manual/CPStepperBindings/Jakefile
  56. +1 −0  Tests/Manual/CPStepperBindings/Resources/MainMenu.cib
  57. +1,487 −0 Tests/Manual/CPStepperBindings/Resources/MainMenu.xib
  58. BIN  Tests/Manual/CPStepperBindings/Resources/spinner.gif
  59. +107 −0 Tests/Manual/CPStepperBindings/index-debug.html
  60. +77 −0 Tests/Manual/CPStepperBindings/index.html
  61. +18 −0 Tests/Manual/CPStepperBindings/main.j
  62. +33 −2 Tests/Manual/CPTextField/AppController.j
  63. +1 −1  Tests/Manual/TableTest/TableCibTest/Resources/MainMenu.cib
  64. +86 −66 Tests/Manual/TableTest/TableCibTest/Resources/MainMenu.xib
  65. +1 −0  Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj
  66. +9 −2 Tools/XcodeCapp/parser.j
  67. +2 −4 Tools/nib2cib/NSButton.j
  68. +5 −0 Tools/nib2cib/NSControl.j
  69. +1 −0  Tools/nib2cib/NSMatrix.j
  70. +2 −1  Tools/nib2cib/NSTableColumn.j
  71. +14 −9 Tools/nib2cib/NSWindowTemplate.j
  72. +11 −1 common.jake
View
1  AppKit/CPAlert.j
@@ -595,6 +595,7 @@ CPCriticalAlertStyle = 2;
frame.size = [self currentValueForThemeAttribute:@"size"];
_window = [[CPWindow alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
+ [_window setLevel:CPStatusWindowLevel];
if (_title)
[_window setTitle:_title];
View
12 AppKit/CPApplication.j
@@ -1218,7 +1218,17 @@ function CPApplicationMain(args, namedArgs)
#if PLATFORM(DOM)
// hook to allow recorder, etc to manipulate things before starting AppKit
if (window.parent !== window && typeof window.parent._childAppIsStarting === "function")
- window.parent._childAppIsStarting(window);
+ {
+ try
+ {
+ window.parent._childAppIsStarting(window);
+ }
+ catch(err)
+ {
+ // This could happen if we're in an iframe without access to the parent frame.
+ CPLog.warn("Failed to call parent frame's _childAppIsStarting().");
+ }
+ }
#endif
var mainBundle = [CPBundle mainBundle],
View
35 AppKit/CPBezierPath.j
@@ -165,6 +165,19 @@ var DefaultLineWidth = 1.0;
CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
}
+- (CGRect)bounds
+{
+ // TODO: this should return this. The controlPointBounds is not a tight fit.
+ // return CGPathGetPathBoundingBox(_path);
+
+ return [self controlPointBounds];
+}
+
+- (CGRect)controlPointBounds
+{
+ return CGPathGetBoundingBox(_path);
+}
+
/*!
Create a line segment between the first and last points in the subpath, closing it.
*/
@@ -272,6 +285,11 @@ var DefaultLineWidth = 1.0;
CGPathAddPath(_path, nil, CGPathWithRoundedRectangleInRect(rect, xRadius, yRadius, YES, YES, YES, YES));
}
+- (void)appendBezierPathWithArcFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint radius:(float)radius
+{
+ CGPathAddArcToPoint(_path, null, fromPoint.x, fromPoint.y, toPoint.x, toPoint.y, radius);
+}
+
/*!
Append the contents of a CPBezierPath object.
*/
@@ -288,4 +306,21 @@ var DefaultLineWidth = 1.0;
_path = CGPathCreateMutable();
}
+- (void)addClip
+{
+ var ctx = [[CPGraphicsContext currentContext] graphicsPort];
+
+ CGContextAddPath(ctx, _path);
+ CGContextClip(ctx);
+}
+
+- (void)setClip
+{
+ var ctx = [[CPGraphicsContext currentContext] graphicsPort];
+
+ CGContextBeginPath(ctx);
+ CGContextAddPath(ctx, _path);
+ CGContextClip(ctx);
+}
+
@end
View
20 AppKit/CPBox.j
@@ -322,6 +322,26 @@ CPBelowBottom = 6;
[self _manageTitlePositioning];
}
+- (CPFont)titleFont
+{
+ return [_titleView font];
+}
+
+- (void)setTitleFont:(CPFont)aFont
+{
+ [_titleView setFont:aFont];
+}
+
+/*!
+ Return the text field used to display the receiver's title.
+
+ This is the Cappuccino equivalent to the `titleCell` method.
+*/
+- (CPTextField)titleView
+{
+ return _titleView;
+}
+
- (void)_manageTitlePositioning
{
if (_titlePosition == CPNoTitle)
View
4 AppKit/CPCollectionView.j
@@ -690,6 +690,10 @@
- (void)mouseDragged:(CPEvent)anEvent
{
+ // Don't crash if we never registered the intial click.
+ if (!_mouseDownEvent)
+ return;
+
var locationInWindow = [anEvent locationInWindow],
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
View
8 AppKit/CPColor.j
@@ -612,6 +612,14 @@ function CPColorWithImages()
}
/*!
+ Returns the receiver. This method is a placeholder that does nothing but may be implemented in the future.
+*/
+- (CPColor)colorUsingColorSpaceName:(id)aColorSpaceName
+{
+ return self;
+}
+
+/*!
Returns an array with the HSB values for this color.
The index values are ordered as:
<pre>
View
15 AppKit/CPFont.j
@@ -174,6 +174,21 @@ following:
return _CPFontSystemFontSize;
}
++ (float)systemFontSizeForControlSize:(CPControlSize)aSize
+{
+ // TODO These sizes should be themable or made less arbitrary in some other way.
+ switch (aSize)
+ {
+ case CPSmallControlSize:
+ return _CPFontSystemFontSize - 1;
+ case CPMiniControlSize:
+ return _CPFontSystemFontSize - 2;
+ case CPRegularControlSize:
+ default:
+ return _CPFontSystemFontSize;
+ }
+}
+
/*!
Sets the default system font size.
*/
View
10 AppKit/CPGraphics.j
@@ -23,6 +23,16 @@
@import "CPColor.j"
@import "CPGraphicsContext.j"
+CPCalibratedWhiteColorSpace = @"CalibratedWhiteColorSpace";
+CPCalibratedBlackColorSpace = @"CalibratedBlackColorSpace";
+CPCalibratedRGBColorSpace = @"CalibratedRGBColorSpace";
+CPDeviceWhiteColorSpace = @"DeviceWhiteColorSpace";
+CPDeviceBlackColorSpace = @"DeviceBlackColorSpace";
+CPDeviceRGBColorSpace = @"DeviceRGBColorSpace";
+CPDeviceCMYKColorSpace = @"DeviceCMYKColorSpace";
+CPNamedColorSpace = @"NamedColorSpace";
+CPPatternColorSpace = @"PatternColorSpace";
+CPCustomColorSpace = @"CustomColorSpace";
function CPDrawTiledRects(
/* CGRect */ boundsRect,
View
35 AppKit/CPGraphicsContext.j
@@ -25,7 +25,8 @@
@import "CGContext.j"
-var CPGraphicsContextCurrent = nil;
+var CPGraphicsContextCurrent = nil,
+ CPGraphicsContextThreadStack = nil;
/*!
@ingroup appkit
@@ -52,6 +53,28 @@ var CPGraphicsContextCurrent = nil;
CPGraphicsContextCurrent = aGraphicsContext;
}
++ (void)saveGraphicsState
+{
+ if (!CPGraphicsContextCurrent)
+ return;
+
+ if (!CPGraphicsContextThreadStack)
+ CPGraphicsContextThreadStack = [CPMutableArray array];
+
+ [CPGraphicsContextThreadStack addObject:CPGraphicsContextCurrent];
+ [CPGraphicsContextCurrent saveGraphicsState];
+}
+
++ (void)restoreGraphicsState
+{
+ var lastContext = [CPGraphicsContextThreadStack lastObject];
+ if (lastContext)
+ {
+ [lastContext restoreGraphicsState];
+ [CPGraphicsContextThreadStack removeLastObject];
+ }
+}
+
/*!
Creates a graphics context with a provided port.
@param aContext the context to initialize with
@@ -99,4 +122,14 @@ var CPGraphicsContextCurrent = nil;
return YES;
}
+- (void)saveGraphicsState
+{
+ CGContextSaveGState(_graphicsPort);
+}
+
+- (void)restoreGraphicsState
+{
+ CGContextRestoreGState(_graphicsPort);
+}
+
@end
View
9 AppKit/CPKeyValueBinding.j
@@ -131,7 +131,7 @@ var CPBindingOperationAnd = 0,
if (options)
[_info setObject:options forKey:CPOptionsKey];
- [self _updatePlaceholdersWithOptions:options];
+ [self _updatePlaceholdersWithOptions:options forBinding:aName];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
@@ -321,6 +321,11 @@ var CPBindingOperationAnd = 0,
}
}
+- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
+{
+ [self _updatePlaceholdersWithOptions:options];
+}
+
- (void)_placeholderForMarker:aMarker
{
var placeholder = _placeholderForMarker[aMarker];
@@ -564,6 +569,8 @@ CPFontNameBinding = @"fontName";
CPFontBoldBinding = @"fontBold";
CPHiddenBinding = @"hidden";
CPFilterPredicateBinding = @"filterPredicate";
+CPMaxValueBinding = @"maxValue";
+CPMinValueBinding = @"minValue";
CPPredicateBinding = @"predicate";
CPSelectedIndexBinding = @"selectedIndex";
CPSelectedLabelBinding = @"selectedLabel";
View
3  AppKit/CPMenu/CPMenu.j
@@ -976,8 +976,7 @@ var _CPMenuBarVisible = NO,
for (; index < count; ++index)
{
- var item = _items[index],
- modifierMask = [item keyEquivalentModifierMask];
+ var item = _items[index];
if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[item keyEquivalentModifierMask]])
{
View
9 AppKit/CPPopover.j
@@ -234,7 +234,7 @@ Set the behavior of the CPPopover. It can be:
[_attachedWindow setContentView:[_contentViewController view]];
[_attachedWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
- if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
+ if (!_animates && _implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
@@ -311,6 +311,13 @@ Set the behavior of the CPPopover. It can be:
[_delegate popoverDidClose:self];
}
+/*! @ignore */
+- (void)attachedWindowDidShow:(_CPAttachedWindow)anAttachedWindow
+{
+ if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
+ [_delegate popoverDidShow:self];
+}
+
#pragma mark -
#pragma mark Notifications
View
10 AppKit/CPRuleEditor/_CPRuleEditorViewSlice.j
@@ -45,7 +45,7 @@
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
- maxX = CGRectGetWidth(bounds) - 2,
+ maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
// Draw background
@@ -63,7 +63,7 @@
// Draw Top Border
CGContextBeginPath(context);
- CGContextMoveToPoint(context, 1, 0);
+ CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, maxX, 0);
CGContextClosePath(context);
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
@@ -71,8 +71,8 @@
// Draw Bottom Border
CGContextBeginPath(context);
- CGContextMoveToPoint(context, 1, maxY - 0.5);
- CGContextAddLineToPoint(context, maxX, maxY - 0.5);
+ CGContextMoveToPoint(context, 0, maxY);
+ CGContextAddLineToPoint(context, maxX, maxY);
CGContextClosePath(context);
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
CGContextSetStrokeColor(context, bottomColor);
@@ -106,4 +106,4 @@
return [CPString stringWithFormat:@"<%@ %p index:%d indentation:%d>",[self className],self,[self rowIndex],[self indentation]];
}
-@end
+@end
View
11 AppKit/CPRuleEditor/_CPRuleEditorViewSliceRow.j
@@ -121,7 +121,7 @@ var CONTROL_HEIGHT = 16.,
return [CPMenuItem separatorItem];
}
-- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString )text
+- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
{
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)],
refont = [_ruleEditor font],
@@ -352,6 +352,15 @@ var CONTROL_HEIGHT = 16.,
optionFrame = _ruleOptionFrames[i];
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2 - 2;
+
+ // small positioning fix
+ if ([ruleOptionView isKindOfClass:CPTextField])
+ {
+ optionFrame.origin.y += 2;
+ [_ruleOptionViews[i] setValue:CGInsetMake(7, 7, 7, 8) forThemeAttribute:@"content-inset"];
+ }
+
+
if (widthChanged)
{
optionFrame.origin.x = optionViewOriginX;
View
7 AppKit/CPSearchField.j
@@ -501,7 +501,12 @@ var RECENT_SEARCH_PREFIX = @" ";
if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
{
if (_searchMenuTemplate == nil)
- [self _sendAction:self];
+ {
+ if ([_searchButton target] && [_searchButton action])
+ [_searchButton mouseDown:anEvent];
+ else
+ [self _sendAction:self];
+ }
else
[self _showMenu];
}
View
37 AppKit/CPStepper.j
@@ -76,6 +76,22 @@
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
++ (Class)_binderClassForBinding:(CPString)theBinding
+{
+ if (theBinding == CPValueBinding || theBinding == CPMinValueBinding || theBinding == CPMaxValueBinding)
+ return [_CPStepperValueBinder class];
+
+ return [super _binderClassForBinding:theBinding];
+}
+
+- (id)_replacementKeyPathForBinding:(CPString)aBinding
+{
+ if (aBinding == CPValueBinding)
+ return @"doubleValue";
+
+ return [super _replacementKeyPathForBinding:aBinding];
+}
+
/*!
Initializes a CPStepper.
@param aFrame the frame of the control
@@ -211,8 +227,7 @@
else
[self setDoubleValue:([self doubleValue] - _increment)];
- if (_target && _action && [_target respondsToSelector:_action])
- [self sendAction:_action to:_target];
+ [self sendAction:[self action] to:[self target]];
}
/*!
@@ -250,6 +265,24 @@
@end
+@implementation _CPStepperValueBinder : CPBinder
+{
+}
+
+- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
+{
+ var placeholder = (aBinding == CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
+
+ [super _updatePlaceholdersWithOptions:options];
+
+ [self _setPlaceholder:placeholder forMarker:CPMultipleValuesMarker isDefault:YES];
+ [self _setPlaceholder:placeholder forMarker:CPNoSelectionMarker isDefault:YES];
+ [self _setPlaceholder:placeholder forMarker:CPNotApplicableMarker isDefault:YES];
+ [self _setPlaceholder:placeholder forMarker:CPNullMarker isDefault:YES];
+}
+
+@end
+
var CPStepperMinValue = @"CPStepperMinValue",
CPStepperMaxValue = @"CPStepperMaxValue",
CPStepperValueWraps = @"CPStepperValueWraps",
View
2  AppKit/CPTabViewItem.j
@@ -138,7 +138,7 @@ CPPressedTab = 2;
_view = aView;
if ([_tabView selectedTabViewItem] == self)
- [_tabView _setContentViewForItem:self];
+ [_tabView _setContentViewFromItem:self];
}
/*!
View
32 AppKit/CPTableColumn.j
@@ -494,7 +494,13 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (CPSortDescriptor)sortDescriptorPrototype
{
- return _sortDescriptorPrototype;
+ if (_sortDescriptorPrototype)
+ return _sortDescriptorPrototype;
+
+ var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
+ binding = [binderClass getBinding:CPValueBinding forObject:self];
+
+ return [binding _defaultSortDescriptorPrototype];
}
/*!
@@ -570,6 +576,30 @@ CPTableColumnUserResizingMask = 1 << 1;
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
}
+- (CPSortDescriptor)_defaultSortDescriptorPrototype
+{
+ if (![self createsSortDescriptor])
+ return nil;
+
+ var keyPath = [_info objectForKey:CPObservedKeyPathKey],
+ dotIndex = keyPath.indexOf(".");
+
+ if (dotIndex === CPNotFound)
+ return nil;
+
+ var firstPart = keyPath.substring(0, dotIndex),
+ key = keyPath.substring(dotIndex + 1);
+
+ return [CPSortDescriptor sortDescriptorWithKey:key ascending:YES];
+}
+
+- (BOOL)createsSortDescriptor
+{
+ var options = [_info objectForKey:CPOptionsKey],
+ optionValue = [options objectForKey:CPCreatesSortDescriptorBindingOption];
+ return optionValue === nil ? YES : [optionValue boolValue];
+}
+
@end
@implementation CPTableColumn (Bindings)
View
66 AppKit/CPTableHeaderView.j
@@ -39,8 +39,8 @@
+ (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", @"font", @"text-shadow-color", @"text-shadow-offset"]];
+ return [CPDictionary dictionaryWithObjects:[[CPNull null], CPLeftTextAlignment, CPLineBreakByTruncatingTail, CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
+ forKeys:[@"background-color", @"text-alignment", @"line-break-mode", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
}
- (void)initWithFrame:(CGRect)frame
@@ -78,6 +78,7 @@
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
[_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
+ [_textField setLineBreakMode:[self currentValueForThemeAttribute:@"line-break-mode"]];
}
- (void)setStringValue:(CPString)string
@@ -102,7 +103,52 @@
- (void)setFont:(CPFont)aFont
{
- [self setValue:aFont forThemeAttribute:"font"];
+ [self setValue:aFont forThemeAttribute:@"font"];
+}
+
+- (CPFont)font
+{
+ return [self currentValueForThemeAttribute:@"font"]
+}
+
+- (void)setAlignment:(CPTextAlignment)alignment
+{
+ [self setValue:alignment forThemeAttribute:@"text-alignment"];
+}
+
+- (CPTextAlignment)alignment
+{
+ return [self currentValueForThemeAttribute:@"text-alignment"]
+}
+
+- (void)setLineBreakMode:(CPLineBreakMode)mode
+{
+ [self setValue:mode forThemeAttribute:@"line-break-mode"];
+}
+
+- (CPLineBreakMode)lineBreakMode
+{
+ return [self currentValueForThemeAttribute:@"line-break-mode"]
+}
+
+- (void)setTextColor:(CPColor)aColor
+{
+ [self setValue:aColor forThemeAttribute:@"text-color"];
+}
+
+- (CPColor)textColor
+{
+ return [self currentValueForThemeAttribute:@"text-color"]
+}
+
+- (void)setTextShadowColor:(CPColor)aColor
+{
+ [self setValue:aColor forThemeAttribute:@"text-shadow-color"];
+}
+
+- (CPColor)textShadowColor
+{
+ return [self currentValueForThemeAttribute:@"text-shadow-color"]
}
- (void)_setIndicatorImage:(CPImage)anImage
@@ -122,6 +168,10 @@
var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
_CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
+ _CPTableColumnHeaderViewTextColorKey = @"_CPTableColumnHeaderViewTextColorKey",
+ _CPTableColumnHeaderViewTextShadowColorKey = @"_CPTableColumnHeaderViewTextShadowColorKey",
+ _CPTableColumnHeaderViewAlignmentKey = @"_CPTableColumnHeaderViewAlignmentKey",
+ _CPTableColumnHeaderViewLineBreakModeKey = @"_CPTableColumnHeaderViewLineBreakModeKey",
_CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
@implementation _CPTableColumnHeaderView (CPCoding)
@@ -134,6 +184,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
+ [self setTextColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextColorKey]];
+ [self setTextShadowColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextShadowColorKey]];
+ [self setAlignment:[aCoder decodeIntForKey:_CPTableColumnHeaderViewAlignmentKey]];
+ [self setLineBreakMode:[aCoder decodeIntForKey:_CPTableColumnHeaderViewLineBreakModeKey]];
}
return self;
@@ -145,7 +199,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
- [aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
+ [aCoder encodeObject:[self font] forKey:_CPTableColumnHeaderViewFontKey];
+ [aCoder encodeObject:[self textColor] forKey:_CPTableColumnHeaderViewTextColorKey];
+ [aCoder encodeObject:[self textShadowColor] forKey:_CPTableColumnHeaderViewTextShadowColorKey];
+ [aCoder encodeInt:[self alignment] forKey:_CPTableColumnHeaderViewAlignmentKey];
+ [aCoder encodeInt:[self lineBreakMode] forKey:_CPTableColumnHeaderViewLineBreakModeKey];
}
@end
View
30 AppKit/CPTableView.j
@@ -222,6 +222,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
SEL _doubleAction;
CPInteger _clickedRow;
+ CPInteger _clickedColumn;
unsigned _columnAutoResizingStyle;
int _lastTrackedRowIndex;
@@ -324,7 +325,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)_init
{
- _lastSelectedRow = -1;
+ _lastSelectedRow = _clickedColumn = _clickedRow = -1;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
@@ -542,8 +543,12 @@ NOT YET IMPLEMENTED
}
/*
- * - clickedColumn
+ Returns the index of the the column the user clicked to trigger an action, or -1 if no column was clicked.
*/
+- (CPInteger)clickedColumn
+{
+ return _clickedColumn;
+}
/*!
Returns the index of the the row the user clicked to trigger an action, or -1 if no row was clicked.
@@ -3376,7 +3381,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
rowIndex = 0,
rowsCount = rowArray.length;
- if (dataViewsForTableColumn) {
+ if (dataViewsForTableColumn)
+ {
for (; rowIndex < rowsCount; ++rowIndex)
{
var row = rowArray[rowIndex],
@@ -4190,7 +4196,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
_isSelectingSession = NO;
var CLICK_TIME_DELTA = 1000,
- columnIndex,
+ columnIndex = -1,
column,
rowIndex,
shouldEdit = YES;
@@ -4198,6 +4204,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)
{
rowIndex = [self rowAtPoint:aPoint];
+
if (rowIndex !== -1)
{
if ([_draggedRowIndexes count] > 0)
@@ -4219,12 +4226,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|| [self infoForBinding:@"content"]))
{
columnIndex = [self columnAtPoint:lastPoint];
+
if (columnIndex !== -1)
{
column = _tableColumns[columnIndex];
+
if ([column isEditable])
{
rowIndex = [self rowAtPoint:aPoint];
+
if (rowIndex !== -1)
{
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldEditTableColumn_row_)
@@ -4244,6 +4254,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([[CPApp currentEvent] clickCount] === 2 && _doubleAction)
{
_clickedRow = [self rowAtPoint:aPoint];
+ _clickedColumn = [self columnAtPoint:lastPoint];
[self sendAction:_doubleAction to:_target];
}
}
@@ -4783,10 +4794,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
_contentBindingExpicitelySet = NO;
}
- if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
- [self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
+ // If the content binding was set manually assume the user is taking manual control of establishing bindings.
+ if (!_contentBindingExpicitelySet)
+ {
+ if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
+ [self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
- //[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
+ if ([[self infoForBinding:@"sortDescriptors"] objectForKey:CPObservedObjectKey] !== destination)
+ [self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
+ }
}
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
View
26 AppKit/CPTextField.j
@@ -490,13 +490,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (BOOL)becomeFirstResponder
{
#if PLATFORM(DOM)
+ // FIXME Why do we care about who's the first responder in a different window?
if (CPTextFieldInputOwner && [CPTextFieldInputOwner window] !== [self window])
[[CPTextFieldInputOwner window] makeFirstResponder:nil];
#endif
// As long as we are the first responder we need to monitor the key status of our window.
- [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResignKey:) name:CPWindowDidResignKeyNotification object:[self window]];
- [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidBecomeKey:) name:CPWindowDidBecomeKeyNotification object:[self window]];
+ [self _setObserveWindowKeyNotifications:YES];
_isEditing = NO;
@@ -616,10 +616,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
/* @ignore */
- (BOOL)resignFirstResponder
{
- // When we are no longer the first responder we don't worry about the key status of our window anymore.
- [[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidResignKeyNotification object:[self window]];
- [[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidBecomeKeyNotification object:[self window]];
-
#if PLATFORM(DOM)
var element = [self _inputElement],
@@ -641,6 +637,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
+ // When we are no longer the first responder we don't worry about the key status of our window anymore.
+ [self _setObserveWindowKeyNotifications:NO];
+
[self _resignFirstKeyResponder];
_isEditing = NO;
@@ -664,7 +663,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
-
[self setNeedsLayout];
#if PLATFORM(DOM)
@@ -699,6 +697,20 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
}
+- (void)_setObserveWindowKeyNotifications:(BOOL)shouldObserve
+{
+ if (shouldObserve)
+ {
+ [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResignKey:) name:CPWindowDidResignKeyNotification object:[self window]];
+ [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidBecomeKey:) name:CPWindowDidBecomeKeyNotification object:[self window]];
+ }
+ else
+ {
+ [[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidResignKeyNotification object:[self window]];
+ [[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidBecomeKeyNotification object:[self window]];
+ }
+}
+
- (void)_windowDidResignKey:(CPNotification)aNotification
{
if (![[self window] isKeyWindow])
View
76 AppKit/CPTokenField.j
@@ -138,6 +138,11 @@ var CPScrollDestinationNone = 0,
return _autocompleteMenu;
}
+- (void)_complete:(_CPAutocompleteMenu)anAutocompleteMenu
+{
+ [self _autocompleteWithEvent:nil];
+}
+
- (void)_autocompleteWithEvent:(CPEvent)anEvent
{
if (![self _inputElement].value && (![_autocompleteMenu contentArray] || ![self hasThemeState:CPThemeStateAutocompleting]))
@@ -307,11 +312,24 @@ var CPScrollDestinationNone = 0,
- (BOOL)becomeFirstResponder
{
+#if PLATFORM(DOM)
if (CPTokenFieldInputOwner && [CPTokenFieldInputOwner window] !== [self window])
[[CPTokenFieldInputOwner window] makeFirstResponder:nil];
+#endif
+
+ // As long as we are the first responder we need to monitor the key status of our window.
+ [self _setObserveWindowKeyNotifications:YES];
[self scrollRectToVisible:[self bounds]];
+ if ([[self window] isKeyWindow])
+ [self _becomeFirstKeyResponder];
+
+ return YES;
+}
+
+- (void)_becomeFirstKeyResponder
+{
[self setThemeState:CPThemeStateEditing];
[self _updatePlaceholderState];
@@ -373,8 +391,6 @@ var CPScrollDestinationNone = 0,
}
#endif
-
- return YES;
}
- (BOOL)resignFirstResponder
@@ -382,9 +398,31 @@ var CPScrollDestinationNone = 0,
if (_preventResign)
return NO;
+ [self _autocomplete];
+
+ // From CPTextField superclass.
+ [self _setObserveWindowKeyNotifications:NO];
+
+ [self _resignFirstKeyResponder];
+
+ if (_shouldNotifyTarget)
+ {
+ _shouldNotifyTarget = NO;
+ [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
+
+ if ([self sendsActionOnEndEditing])
+ [self sendAction:[self action] to:[self target]];
+ }
+
+ return YES;
+}
+
+- (void)_resignFirstKeyResponder
+{
[self unsetThemeState:CPThemeStateEditing];
- [self _autocomplete];
+ [self _updatePlaceholderState];
+ [self setNeedsLayout];
#if PLATFORM(DOM)
@@ -414,21 +452,6 @@ var CPScrollDestinationNone = 0,
}
#endif
-
- [self _updatePlaceholderState];
-
- [self setNeedsLayout];
-
- if (_shouldNotifyTarget)
- {
- _shouldNotifyTarget = NO;
- [self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
-
- if ([self sendsActionOnEndEditing])
- [self sendAction:[self action] to:[self target]];
- }
-
- return YES;
}
- (void)mouseDown:(CPEvent)anEvent
@@ -634,10 +657,13 @@ var CPScrollDestinationNone = 0,
if (CPTokenFieldInputOwner && CPTokenFieldInputOwner._preventResign)
return false;
- if (!CPTokenFieldInputResigning && !CPTokenFieldFocusInput)
+ if (!CPTokenFieldInputResigning && [[CPTokenFieldInputOwner window] isKeyWindow])
{
- [[CPTokenFieldInputOwner window] makeFirstResponder:nil];
- return;
+ // If we lost focus somehow but we're not resigning and we're still in the key window, we'll need to take it back.
+ window.setTimeout(function()
+ {
+ CPTokenFieldDOMInputElement.focus();
+ }, 0.0);
}
CPTokenFieldHandleBlur(anEvent, CPTokenFieldDOMInputElement);
@@ -975,8 +1001,7 @@ var CPScrollDestinationNone = 0,
var frame = [self frame],
contentView = [_tokenScrollView documentView],
- tokens = [self _tokens],
- shouldShowAutoComplete = [self hasThemeState:CPThemeStateAutocompleting];
+ tokens = [self _tokens];
// Hack to make sure we are handling an array
if (![tokens isKindOfClass:[CPArray class]])
@@ -994,6 +1019,9 @@ var CPScrollDestinationNone = 0,
lineHeight = [font defaultLineHeightForFont],
editorInset = [self currentValueForThemeAttribute:@"editor-inset"];
+ // Put half a spacing above the tokens.
+ offset.y += CEIL(spaceBetweenTokens.height / 2.0);
+
// Get the height of a typical token, or a token token if you will.
[tokenToken sizeToFit];
@@ -1093,7 +1121,7 @@ var CPScrollDestinationNone = 0,
}
// Trim off any excess height downwards (in case we shrank).
- var scrollHeight = offset.y + tokenHeight + CEIL(spaceBetweenTokens.height / 2.0);
+ var scrollHeight = offset.y + tokenHeight;
if (_CGRectGetHeight([contentView bounds]) > scrollHeight)
[contentView setFrameSize:_CGSizeMake(_CGRectGetWidth([_tokenScrollView bounds]), scrollHeight)];
View
15 AppKit/CPToolbar.j
@@ -247,7 +247,7 @@ var CPToolbarsByIdentifier = nil,
_window = aWindow;
if (_window)
- [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_autovalidate) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
+ [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_autoValidateVisibleItems) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
/*!
@@ -400,14 +400,15 @@ var CPToolbarsByIdentifier = nil,
*/
- (void)validateVisibleItems
{
- var toolbarItems = [self visibleItems],
- count = [toolbarItems count];
+ [self _validateVisibleItems:NO]
+}
- while (count--)
- [toolbarItems[count] validate];
+- (void)_autoValidateVisibleItems
+{
+ [self _validateVisibleItems:YES]
}
-- (void)_autovalidate
+- (void)_validateVisibleItems:(BOOL)isAutovalidation
{
var toolbarItems = [self visibleItems],
count = [toolbarItems count];
@@ -415,7 +416,7 @@ var CPToolbarsByIdentifier = nil,
while (count--)
{
var item = [toolbarItems objectAtIndex:count];
- if ([item autovalidates])
+ if (!isAutovalidation || [item autovalidates])
[item validate];
}
}
View
59 AppKit/CPView.j
@@ -98,9 +98,6 @@ var CPViewFlags = { },
CPViewHasCustomDrawRect = 1 << 0,
CPViewHasCustomLayoutSubviews = 1 << 1;
-var CPCurrentToolTip,
- CPCurrentToolTipTimer,
- CPToolTipDelay = 1.0;
/*!
@ingroup appkit
@@ -246,8 +243,8 @@ var CPCurrentToolTip,
- (void)_setupToolTipHandlers
{
_toolTipInstalled = NO;
- _toolTipFunctionIn = function(e) { [self _fireToolTip]; }
- _toolTipFunctionOut = function(e) { [self _invalidateToolTip]; };
+ _toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
+ _toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
}
+ (CPSet)keyPathsForValuesAffectingFrame
@@ -336,6 +333,9 @@ var CPCurrentToolTip,
if (_toolTip == aToolTip)
return;
+ if (aToolTip && ![aToolTip isKindOfClass:CPString])
+ aToolTip = [aToolTip description];
+
_toolTip = aToolTip;
if (_toolTip)
@@ -398,54 +398,6 @@ var CPCurrentToolTip,
_toolTipInstalled = NO;
}
-/*! @ignore
- Starts the tooltip timer.
-*/
-- (void)_fireToolTip
-{
- if (CPCurrentToolTipTimer)
- {
- [CPCurrentToolTipTimer invalidate];
-
- if (CPCurrentToolTip)
- [CPCurrentToolTip close];
-
- CPCurrentToolTip = nil;
- }
-
- if (_toolTip)
- CPCurrentToolTipTimer = [CPTimer scheduledTimerWithTimeInterval:CPToolTipDelay target:self selector:@selector(_showToolTip:) userInfo:nil repeats:NO];
-}
-
-/*! @ignore
- Stop the tooltip timer if any
-*/
-- (void)_invalidateToolTip
-{
- if (CPCurrentToolTipTimer)
- {
- [CPCurrentToolTipTimer invalidate];
- CPCurrentToolTipTimer = nil;
- }
-
- if (CPCurrentToolTip)
- {
- [CPCurrentToolTip close];
- CPCurrentToolTip = nil;
- }
-}
-
-/*! @ignore
- Actually shows the tooltip if any
-*/
-- (void)_showToolTip:(CPTimer)aTimer
-{
- if (CPCurrentToolTip)
- [CPCurrentToolTip close];
-
- CPCurrentToolTip = [_CPToolTip toolTipWithString:_toolTip];
-}
-
/*!
Returns the container view of the receiver
@return the receiver's containing view
@@ -3072,6 +3024,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
[self _setupToolTipHandlers];
_toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
+
if (_toolTip)
[self _installToolTipEventHandlers];
View
5 AppKit/CPWebView.j
@@ -1032,6 +1032,11 @@ CPWebViewAppKitScrollMaxPollCount = 3;
var documentURL = [CPURL URLWithString:window.location.href];
if ([documentURL isFileURL] && CPFeatureIsCompatible(CPSOPDisabledFromFileURLs))
return YES;
+
+ // Relative URLs always pass the SOP.
+ if (![self scheme] && ![self host] && ![self port])
+ return YES;
+
return ([documentURL scheme] == [self scheme] && [documentURL host] == [self host] && [documentURL port] == [self port]);
}
View
72 AppKit/CPWindow/CPWindow.j
@@ -287,6 +287,9 @@ var CPWindowActionMessageKeys = [
unsigned _shadowStyle;
BOOL _showsResizeIndicator;
+ int _positioningMask;
+ CGRect _positioningScreenRect;
+
BOOL _isDocumentEdited;
BOOL _isDocumentSaving;
@@ -535,6 +538,49 @@ CPTexturedBackgroundWindowMask
// set up a default key view loop.
if (_keyViewLoopIsDirty && ![self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
+
+ // At this time we know the final screen (or browser) size and can apply the positioning mask, if any, from the nib.
+ if (_positioningScreenRect)
+ {
+ var actualScreenRect = [CPPlatform isBrowser] ? [_platformWindow contentBounds] : [[self screen] visibleFrame],
+ frame = [self frame],
+ origin = frame.origin;
+
+ if (actualScreenRect)
+ {
+ if ((_positioningMask & CPWindowPositionFlexibleLeft) && (_positioningMask & CPWindowPositionFlexibleRight))
+ {
+ // Proportional Horizontal.
+ origin.x *= (actualScreenRect.size.width / _positioningScreenRect.size.width);
+ }
+ else if (_positioningMask & CPWindowPositionFlexibleLeft)
+ {
+ // Fixed from Right
+ origin.x += actualScreenRect.size.width - _positioningScreenRect.size.width;
+ }
+ else if (_positioningMask & CPWindowPositionFlexibleRight)
+ {
+ // Fixed from Left
+ }
+
+ if ((_positioningMask & CPWindowPositionFlexibleTop) && (_positioningMask & CPWindowPositionFlexibleBottom))
+ {
+ // Proportional Vertical.
+ origin.y *= (actualScreenRect.size.height / _positioningScreenRect.size.height);
+ }
+ else if (_positioningMask & CPWindowPositionFlexibleTop)
+ {
+ // Fixed from Bottom
+ origin.y += actualScreenRect.size.height - _positioningScreenRect.size.height;
+ }
+ else if (_positioningMask & CPWindowPositionFlexibleBottom)
+ {
+ // Fixed from Top
+ }
+
+ [self setFrameOrigin:origin];
+ }
+ }
}
- (void)_setWindowView:(CPView)aWindowView
@@ -1627,11 +1673,29 @@ CPTexturedBackgroundWindowMask
[self selectPreviousKeyView:self];
else
[self selectNextKeyView:self];
-
+#if PLATFORM(DOM)
+ // Make sure the browser doesn't try to do its own tab handling.
+ // This is important or the browser might blur the shared text field or token field input field,
+ // even that we just moved it to a new first responder.
+ [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]
+#endif
return;
}
else if ([anEvent charactersIgnoringModifiers] === CPBackTabCharacter)
- return [self selectPreviousKeyView:self];
+ {
+ var didTabBack = [self selectPreviousKeyView:self];
+ if (didTabBack)
+ {
+#if PLATFORM(DOM)
+ // Make sure the browser doesn't try to do its own tab handling.
+ // This is important or the browser might blur the shared text field or token field input field,
+ // even that we just moved it to a new first responder.
+ [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]
+#endif
+ }
+
+ return didTabBack;
+ }
[[self firstResponder] keyDown:anEvent];
@@ -1792,7 +1856,9 @@ CPTexturedBackgroundWindowMask
*/
- (BOOL)canBecomeKeyWindow
{
- return YES;
+ // In Cocoa only resizable or titled windows return YES here by default. But the main browser window in Cappuccino
+ // doesn't have these masks even that it's both titled and resizable, so we return YES when isFullPlatformWindow too.
+ return (_styleMask & CPResizableWindowMask) || (_styleMask & CPResizableWindowMask) || [self isFullPlatformWindow];
}
/*!
View
35 AppKit/CPWindow/_CPAttachedWindowView.j
@@ -53,15 +53,20 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10),
*/
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
- var contentRect = CGRectMakeCopy(aFrameRect);
+ var contentRect = CGRectMakeCopy(aFrameRect),
+ modifierX = 16,
+ modifierY = 19;
// @todo change border art and remove this pixel perfect adaptation
- // return CGRectInset(contentRect, 20, 20);
+ //
+ // @comment: If we use this, each time we open the popover, the content
+ // view is reduced a little over and over
+ // return CGRectInset(contentRect, modifierX, modifierY);
- contentRect.origin.x += 18;
- contentRect.origin.y += 17;
- contentRect.size.width -= 35;
- contentRect.size.height -= 37;
+ contentRect.origin.x += modifierX;
+ contentRect.origin.y += modifierY;
+ contentRect.size.width -= modifierX * 2;
+ contentRect.size.height -= modifierY * 2;
return contentRect;
}
@@ -73,15 +78,21 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10),
*/
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
- var frameRect = CGRectMakeCopy(aContentRect);
+ var frameRect = CGRectMakeCopy(aContentRect),
+ modifierX = 16,
+ modifierY = 19;
// @todo change border art and remove this pixel perfect adaptation
- //return CGRectOffset(frameRect, 20, 20);
+ // @comment: If we use this, each time we open the popover, the content
+ //
+ // view is reduced a little over and over
+ // return CGRectOffset(frameRect, modifierX, modifierY);
+
+ frameRect.origin.x -= modifierX;
+ frameRect.origin.y -= modifierY;
+ frameRect.size.width += modifierX * 2;
+ frameRect.size.height += modifierY * 2;
- frameRect.origin.x -= 18;
- frameRect.origin.y -= 17;
- frameRect.size.width += 35;
- frameRect.size.height += 37;
return frameRect;
}
View
32 AppKit/CPWindow/_CPStandardWindowView.j
@@ -152,38 +152,6 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
return _CPStandardWindowViewDividerBackgroundColor;
}
-- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
-{
- var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
- theToolbar = [[self window] toolbar];
-
- if ([theToolbar isVisible])
- {
- var toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
-
- contentRect.origin.y += toolbarHeight;
- contentRect.size.height -= toolbarHeight;
- }
-
- return contentRect;
-}
-
-- (CGRect)frameRectForContentRect:(CGRect)aContentRect
-{
- var frameRect = [[self class] frameRectForContentRect:aContentRect],
- theToolbar = [[self window] toolbar];
-
- if ([theToolbar isVisible])
- {
- var toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
-
- frameRect.origin.y -= toolbarHeight;
- frameRect.size.height += toolbarHeight;
- }
-
- return frameRect;
-}
-
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame styleMask:aStyleMask];
View
26 AppKit/CPWindow/_CPWindowView.j
@@ -76,12 +76,34 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
- return [[self class] contentRectForFrameRect:aFrameRect];
+ var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
+ theToolbar = [[self window] toolbar];
+
+ if ([theToolbar isVisible])
+ {
+ var toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
+
+ contentRect.origin.y += toolbarHeight;
+ contentRect.size.height -= toolbarHeight;
+ }
+
+ return contentRect;
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
- return [[self class] frameRectForContentRect:aContentRect];
+ var frameRect = [[self class] frameRectForContentRect:aContentRect],
+ theToolbar = [[self window] toolbar];
+
+ if ([theToolbar isVisible])
+ {
+ var toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
+
+ frameRect.origin.y -= toolbarHeight;
+ frameRect.size.height += toolbarHeight;
+ }
+
+ return frameRect;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
View
2  AppKit/CPWindowController.j
@@ -285,7 +285,7 @@
// Change of document means toolbar items may no longer make sense.
// FIXME: DOCUMENT ARCHITECTURE Should we setToolbar: as well?
- [[[self window] toolbar] validateVisibleItems];
+ [[[self window] toolbar] _autoValidateVisibleItems];
}
- (void)setSupportsMultipleDocuments:(BOOL)shouldSupportMultipleDocuments
View
150 AppKit/Cib/_CPCibWindowTemplate.j
@@ -4,29 +4,20 @@
@import "CGGeometry.j"
@import "CPWindow.j"
+CPWindowPositionFlexibleRight = 1 << 19;
+CPWindowPositionFlexibleLeft = 1 << 20;
+CPWindowPositionFlexibleBottom = 1 << 21;
+CPWindowPositionFlexibleTop = 1 << 22;
-var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
- _CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
-
- _CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
- _CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
-
- _CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
- _CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
- _CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
- _CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
-
- _CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
- _CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
@implementation _CPCibWindowTemplate : CPObject
{
CGSize _minSize;
CGSize _maxSize;
- //CGSize _screenRect;
+ CGRect _screenRect;
id _viewClass;
- //unsigned _wtFlags;
+ unsigned _wtFlags;
CPString _windowClass;
CGRect _windowRect;
unsigned _windowStyleMask;
@@ -52,67 +43,18 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
_windowView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 200.0)];
_windowIsFullPlatformWindow = NO;
- }
-
- return self;
-}
-
-- (id)initWithCoder:(CPCoder)aCoder
-{
- self = [super init];
-
- if (self)
- {
- if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
- _minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
- if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
- _maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
-
- _viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
-
- _windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
- _windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
- _windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
- _windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
- _windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
-
- _windowAutorecalculatesKeyViewLoop = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
- _windowIsFullPlatformWindow = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
+ _wtFlags = CPPositionProportionalHorizontal | CPPositionProportionalVertical;
}
return self;
}
-- (void)encodeWithCoder:(CPCoder)aCoder
-{
- if (_minSize)
- [aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
- if (_maxSize)
- [aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
-
- [aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
-
- [aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
- [aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
- [aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
-
- [aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
- [aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
-
- if (_windowAutorecalculatesKeyViewLoop)
- [aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
-
- if (_windowIsFullPlatformWindow)
- [aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
-}
-
- (CPString)customClassName
{
return _windowClass;
}
-
- (void)setCustomClassName:(CPString)aClassName
{
_windowClass = aClassName;
@@ -155,7 +97,85 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
[theWindow setAutorecalculatesKeyViewLoop:_windowAutorecalculatesKeyViewLoop];
[theWindow setFullBridge:_windowIsFullPlatformWindow];
+ theWindow._positioningMask = _wtFlags;
+ theWindow._positioningScreenRect = _screenRect;
+
return theWindow;
}
@end
+
+var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
+ _CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
+
+ _CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
+ _CPCibWindowTemplateWTFlagsKey = @"_CPCibWindowTemplateWTFlagsKey",
+ _CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
+
+ _CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
+ _CPCibWindowTemplateScreenRectKey = @"_CPCibWindowTemplateScreenRectKey",
+ _CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
+ _CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
+ _CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
+
+ _CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
+ _CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
+
+@implementation _CPCibWindowTemplate (Coding)
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ self = [super init];
+
+ if (self)
+ {
+ if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
+ _minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
+ if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
+ _maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
+
+ _viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
+
+ _windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
+ _wtFlags = [aCoder decodeIntForKey:_CPCibWindowTemplateWTFlagsKey];
+ _windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
+ _screenRect = [aCoder decodeRectForKey:_CPCibWindowTemplateScreenRectKey];
+ _windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
+
+ _windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
+ _windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
+
+ _windowAutorecalculatesKeyViewLoop = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
+ _windowIsFullPlatformWindow = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ if (_minSize)
+ [aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
+ if (_maxSize)
+ [aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
+
+ [aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
+
+ [aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
+ [aCoder encodeInt:_wtFlags forKey:_CPCibWindowTemplateWTFlagsKey];
+ [aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
+ [aCoder encodeRect:_screenRect forKey:_CPCibWindowTemplateScreenRectKey];
+ [aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
+
+ [aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
+ [aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
+
+ if (_windowAutorecalculatesKeyViewLoop)
+ [aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
+
+ if (_windowIsFullPlatformWindow)
+ [aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
+}
+
+@end
+
View
10 AppKit/CoreGraphics/CGContext.j
@@ -322,6 +322,16 @@ function CGContextClosePath(aContext)
}
/*!
+ Return YES if the current path in the given context is empty.
+ @param aContext the CGContext to examine
+ @return BOOL
+*/
+function CGContextIsPathEmpty(aContext)
+{
+ return (!aContext.path || CGPathIsEmpty(aContext.path));
+}
+
+/*!
Moves the current location of aContext to the given x and y coordinates
@param aContext the CGContext to move
@param x the x location to move the context to
View
2  AppKit/CoreGraphics/CGContextCanvas.j
@@ -129,7 +129,7 @@ function CGContextAddPath(aContext, aPath)
break;
case kCGPathElementAddArc: _CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
break;
- case kCGPathElementAddArcTo: //_CGContextAddArcToPointCanvas(aContext, element.cp1x, element.cp1.y, element.cp2.x, element.cp2y, element.radius);
+ case kCGPathElementAddArcToPoint: _CGContextAddArcToPointCanvas(aContext, element.p1x, element.p1y, element.p2x, element.p2y, element.radius);
break;
}
}
View
4 AppKit/CoreGraphics/CGContextVML.j
@@ -215,7 +215,7 @@ function CGContextDrawPath(aContext, aMode)
COORD(start.x), ',', COORD(start.y), " ",
COORD(end.x), ',', COORD(end.y));
break;
- case kCGPathElementAddArcTo: break;
+ case kCGPathElementAddArcToPoint: break;
}
// TODO: Following is broken for curves due to
@@ -332,4 +332,4 @@ function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoin
// aContext.buffer += vml.join("");
// else
// aContext.DOMElement.innerHTML = vml.join("");
-}
+}
View
119 AppKit/CoreGraphics/CGPath.j
@@ -118,6 +118,17 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
function CGPathAddArcToPoint(aPath, aTransform, x1, y1, x2, y2, aRadius)
{
+ var p1 = _CGPointMake(x1, y1),
+ p2 = _CGPointMake(x2, y2);
+
+ if (aTransform)
+ {
+ p1 = _CGPointApplyAffineTransform(p1, aTransform);
+ p2 = _CGPointApplyAffineTransform(p2, aTransform);
+ }
+
+ aPath.current = p2;
+ aPath.elements[aPath.count++] = { type:kCGPathElementAddArcToPoint, p1x:p1.x, p1y:p1.y, p2x:p2.x, p2y:p2.y, radius:aRadius };
}
function CGPathAddCurveToPoint(aPath, aTransform, cp1x, cp1y, cp2x, cp2y, x, y)
@@ -186,6 +197,12 @@ function CGPathAddPath(aPath, aTransform, anotherPath)
element.endAngle, element.isClockwise);
break;
+ case kCGPathElementAddArcToPoint: CGPathAddArcToPoint(aPath, aTransform,
+ element.p1x, element.p1y,
+ element.p2x, element.p2y,
+ element.radius);
+ break;
+
case kCGPathElementAddQuadCurveToPoint: CGPathAddQuadCurveToPoint(aPath, aTransform,
element.cpx, element.cpy,
element.x, element.y);
@@ -390,6 +407,108 @@ function CGPathIsEmpty(aPath)
}
/*!
+ Calculate the smallest rectangle to contain both the path of the receiver and all control points.
+*/
+function CGPathGetBoundingBox(aPath)
+{
+ if (!aPath || !aPath.count)
+ return _CGRectMakeZero();
+
+ var ox = 0,
+ oy = 0,
+ rx = 0,
+ ry = 0,
+ movePoint = nil;
+
+ function addPoint(x, y)
+ {
+ ox = MIN(ox, x);
+ oy = MIN(oy, y);
+ rx = MAX(rx, x);
+ ry = MAX(ry, y);
+ }
+
+ for (var i = 0, count = aPath.count; i < count; ++i)
+ {
+ var element = aPath.elements[i];
+
+ // Just enclose all the control points. The curves must be inside of the control points.
+ // This won't work for CGPathGetPathBoundingBox.
+ switch (element.type)
+ {
+ case kCGPathElementAddLineToPoint:
+ if (movePoint)
+ {
+ addPoint(movePoint.x, movePoint.y);
+ movePoint = nil;
+ }
+
+ addPoint(element.x, element.y);
+ break;
+
+ case kCGPathElementAddCurveToPoint:
+ if (movePoint)
+ {
+ addPoint(movePoint.x, movePoint.y);
+ movePoint = nil;
+ }
+
+ addPoint(element.cp1x, element.cp1y);
+ addPoint(element.cp2x, element.cp2y);
+ addPoint(element.x, element.y);
+ break;
+
+ case kCGPathElementAddArc:
+ if (movePoint)
+ {
+ addPoint(movePoint.x, movePoint.y);
+ movePoint = nil;
+ }
+
+ addPoint(element.x, element.y);
+ break;
+
+ case kCGPathElementAddArcToPoint:
+ if (movePoint)
+ {
+ addPoint(movePoint.x, movePoint.y);
+ movePoint = nil;
+ }
+
+ addPoint(element.p1x, element.p1y);
+ addPoint(element.p2x, element.p2y);
+ break;
+
+ case kCGPathElementAddQuadCurveToPoint:
+ if (movePoint)
+ {
+ addPoint(movePoint.x, movePoint.y);
+ movePoint = nil;
+ }
+
+ addPoint(element.cpx, element.cpy);
+ addPoint(element.x, element.y);
+ break;
+
+ case kCGPathElementMoveToPoint:
+ movePoint = _CGPointMake(element.x, element.y);
+ break;
+
+ case kCGPathElementCloseSubpath:
+ if (movePoint)
+ {
+ addPoint(movePoint.x, movePoint.y);
+ movePoint = nil;
+ }
+
+ break;
+ }
+ }
+
+ return _CGRectMake(ox, oy, rx - ox, ry - oy);
+}
+
+/*!
@}
*/
View
6 AppKit/Platform/DOM/CPPlatformWindow+DOM.j
@@ -113,14 +113,12 @@
@import "CPEvent.j"
@import "CPText.j"
@import "CPCompatibility.j"
-
@import "CPDOMWindowLayer.j"
@import "CPPlatform.j"
@import "CPPlatformWindow.j"
@import "CPPlatformWindow+DOMKeys.j"
-
// List of all open native windows
var PlatformWindows = [CPSet set];
@@ -1242,6 +1240,10 @@ var resizeTimer = nil;
else if (type === "mousedown")
{
+ // If we receive a click event, then we invalidate any scheduled
+ // or visible tooltips
+ [_CPToolTip invalidateCurrentToolTipIfNeeded];
+
var button = aDOMEvent.button;
_mouseDownIsRightClick = button == 2 || (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && button == 0 && modifierFlags & CPControlKeyMask);
View
5 AppKit/Themes/Aristo/ThemeDescriptors.j
@@ -1028,7 +1028,7 @@ var themedButtonValues = nil,
overrides =
[
[@"bezel-inset", CGInsetMakeZero()],
- [@"editor-inset", CGInsetMake(2.0, 0.0, 0.0, 0.0)],
+ [@"editor-inset", CGInsetMake(3.0, 0.0, 0.0, 0.0)],
// Non-bezeled token field with tokens
[@"content-inset", CGInsetMake(6.0, 8.0, 4.0, 8.0)],
@@ -1037,7 +1037,7 @@ var themedButtonValues = nil,
[@"content-inset", CGInsetMake(7.0, 8.0, 6.0, 8.0), CPTextFieldStatePlaceholder],
// Bezeled token field with tokens
- [@"content-inset", CGInsetMake(6.0, 5.0, 4.0, 5.0), CPThemeStateBezeled],
+ [@"content-inset", CGInsetMake(5.0, 5.0, 4.0, 5.0), CPThemeStateBezeled],
// Bezeled token field with no tokens
[@"content-inset", CGInsetMake(8.0, 8.0, 7.0, 8.0), CPThemeStateBezeled | CPTextFieldStatePlaceholder]
@@ -1678,6 +1678,7 @@ var themedButtonValues = nil,
[@"text-shadow-color", [CPColor whiteColor]],
[@"text-shadow-offset", CGSizeMake(0.0, 1.0)],
[@"text-alignment", CPLeftTextAlignment],
+ [@"line-break-mode", CPLineBreakByTruncatingTail],
[@"background-color", pressed, CPThemeStateHighlighted],
[@"background-color", highlighted, CPThemeStateSelected],
View
15 AppKit/_CPAttachedWindow.j
@@ -31,7 +31,8 @@ CPPopoverAppearanceMinimal = 0;
CPPopoverAppearanceHUD = 1;
var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
- _CPAttachedWindow_attachedWindowDidClose_ = 1 << 1;
+ _CPAttachedWindow_attachedWindowDidClose_ = 1 << 1,
+ _CPAttachedWindow_attachedWindowDidShow_ = 1 << 2;
/*!
@@ -170,6 +171,9 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
if ([_delegate respondsToSelector:@selector(attachedWindowDidClose:)])
_implementedDelegateMethods |= _CPAttachedWindow_attachedWindowDidClose_;
+
+ if ([_delegate respondsToSelector:@selector(attachedWindowDidShow:)])
+ _implementedDelegateMethods |= _CPAttachedWindow_attachedWindowDidShow_;
}
#pragma mark -
@@ -458,6 +462,15 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
// Because we are watching the -webkit-transform, it will occur now.
[self setCSS3Property:@"Transform" value:@"scale(1)"];
[self setCSS3Property:@"Transition" value:@"-webkit-transform 50ms linear"];
+
+ var transitionCompleteFunction = function()
+ {
+ _DOMElement.removeEventListener("webkitTransitionEnd", transitionCompleteFunction, YES);
+ if (_implementedDelegateMethods & _CPAttachedWindow_attachedWindowDidShow_)
+ [_delegate attachedWindowDidShow:self];
+ }
+
+ _DOMElement.addEventListener("webkitTransitionEnd", transitionCompleteFunction, YES);
};
_DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
View
9 AppKit/_CPAutocompleteMenu.j
@@ -73,6 +73,8 @@ var _CPAutocompleteMenuMaximumHeight = 307;
[tableView setDataSource:self];
[tableView setDelegate:self];
+ [tableView setTarget:self];
+ [tableView setAction:@selector(complete:)];
[tableView setAllowsMultipleSelection:NO];
[tableView setHeaderView:nil];
[tableView setCornerView:nil];
@@ -161,7 +163,7 @@ var _CPAutocompleteMenuMaximumHeight = 307;
// TODO Track down why mystery constant is needed to allocate enough width. Scroll view insets?
}
- var frameOrigin = [textField convertPoint:origin toView:nil],
+ var frameOrigin = [[textField window] convertBaseToGlobal:[textField convertPointToBase:origin]],
screenSize = [([CPPlatform isBrowser] ? [_menuWindow platformWindow] : [_menuWindow screen]) visibleFrame].size,
availableWidth = screenSize.width - frameOrigin.x,
availableHeight = screenSize.height - frameOrigin.y,
@@ -251,6 +253,11 @@ var _CPAutocompleteMenuMaximumHeight = 307;
return [contentArray objectAtIndex:row];
}
+- (@action)complete:(id)sender
+{
+ [textField _complete:self];
+}
+
@end
View
72 AppKit/_CPImageAndTextView.j
@@ -292,7 +292,7 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0,
{
[self layoutIfNeeded];
- var textFrame = CGRectMakeZero();
+ var textFrame = _CGRectMakeZero();
if (_DOMTextElement)
{
@@ -681,38 +681,47 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0,
textRectWidth = _CGRectGetWidth(textRect),
textRectHeight = _CGRectGetHeight(textRect);
- if (_verticalAlignment !== CPTopVerticalTextAlignment)
+ if (textRectWidth <= 0 || textRectHeight <= 0)
{
- if (!_textSize)
+ // Don't bother trying to position the text in an empty rect.
+ textRectWidth = 0;
+ textRectHeight = 0;
+ }
+ else
+ {
+ if (_verticalAlignment !== CPTopVerticalTextAlignment)
{
- if (_lineBreakMode === CPLineBreakByCharWrapping ||
- _lineBreakMode === CPLineBreakByWordWrapping)
+ if (!_textSize)
{
- _textSize = [_text sizeWithFont:_font inWidth:textRectWidth];
+ if (_lineBreakMode === CPLineBreakByCharWrapping ||
+ _lineBreakMode === CPLineBreakByWordWrapping)
+ {
+ _textSize = [_text sizeWithFont:_font inWidth:textRectWidth];
+ }
+ 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;
}
- else
- {
- _textSize = [_text sizeWithFont:_font];
- // Account for possible fractional pixels at right edge
- _textSize.width += 1;
+ if (_verticalAlignment === CPCenterVerticalTextAlignment)
+ {
+ // Since we added +1 px height above to show fractional pixels on the bottom, we have to remove that when calculating vertical centre.
+ textRectY = textRectY + (textRectHeight - _textSize.height + 1.0) / 2.0;
+ textRectHeight = _textSize.height;
}
- // Account for possible fractional pixels at bottom edge
- _textSize.height += 1;
- }
-
- if (_verticalAlignment === CPCenterVerticalTextAlignment)
- {
- // Since we added +1 px height above to show fractional pixels on the bottom, we have to remove that when calculating vertical centre.
- textRectY = textRectY + (textRectHeight - _textSize.height + 1.0) / 2.0;
- textRectHeight = _textSize.height;
- }
-
- else //if (_verticalAlignment === CPBottomVerticalTextAlignment)
- {
- textRectY = textRectY + textRectHeight - _textSize.height;
- textRectHeight = _textSize.height;
+ else //if (_verticalAlignment === CPBottomVerticalTextAlignment)
+ {
+ textRectY = textRectY + textRectHeight - _textSize.height;
+ textRectHeight = _textSize.height;
+ }
}
}
@@ -740,7 +749,7 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0,
- (void)sizeToFit
{
- var size = CGSizeMakeZero();
+ var size = _CGSizeMakeZero();
if ((_imagePosition !== CPNoImage) && _image)
{
@@ -781,4 +790,13 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0,
[self setFrameSize:size];
}
+- (void)setFrameSize:(CGSize)aSize
+{
+ // If we're applying line breaks the height of the text size might change as a result of the bounds changing.
+ if ((_lineBreakMode === CPLineBreakByCharWrapping || _lineBreakMode === CPLineBreakByWordWrapping) && aSize.width !== [self frameSize].width)
+ _textSize = nil;
+
+ [super setFrameSize:aSize];
+}
+
@end
View
45 AppKit/_CPToolTip.j
@@ -27,7 +27,10 @@
_CPToolTipWindowMask = 1 << 27;
var _CPToolTipHeight = 24.0,
- _CPToolTipFontSize = 11.0;
+ _CPToolTipFontSize = 11.0,
+ _CPToolTipDelay = 1.0,
+ _CPToolTipCurrentToolTip,
+ _CPToolTipCurrentToolTipTimer;
/*! @ingroup appkit
This is a basic tooltip that behaves mostly like Cocoa ones.
@@ -41,6 +44,46 @@ var _CPToolTipHeight = 24.0,
#pragma mark -
#pragma mark Class Methods
+/*! @ignore
+ Invalidate any scheduled tooltips, or hide any visible one
+*/
++ (void)invalidateCurrentToolTipIfNeeded
+{
+ if (_CPToolTipCurrentToolTipTimer)
+ {
+ [_CPToolTipCurrentToolTipTimer invalidate];
+ _CPToolTipCurrentToolTipTimer = nil;
+ }
+
+ if (_CPToolTipCurrentToolTip)
+ {
+ [_CPToolTipCurrentToolTip close];
+ _CPToolTipCurrentToolTip = nil;
+ }
+}
+
+/*! @ignore
+ Schedule a tooltip for the given view
+ @param aView the view that might display the tooltip
+*/
++ (void)scheduleToolTipForView:(CPView)aView
+{
+ if (![aView toolTip] || ![[aView toolTip] length])
+ return;
+
+ [_CPToolTip invalidateCurrentToolTipIfNeeded];
+
+ var callbackFunction = function() {
+ [_CPToolTip invalidateCurrentToolTipIfNeeded];
+ _CPToolTipCurrentToolTip = [_CPToolTip toolTipWithString:[aView toolTip]];
+ };
+
+ _CPToolTipCurrentToolTipTimer = [CPTimer scheduledTimerWithTimeInterval:_CPToolTipDelay
+ callback:callbackFunction
+ repeats:NO];
+}
+
+
/*! Returns an initialized _CPToolTip with the given text and attach it to given view.
@param aString the content of the tooltip
*/
View
12 Foundation/CPGeometry.j
@@ -75,6 +75,18 @@ CPPointCreateCopy = CGPointMakeCopy;
CPPointEqualToPoint = CGPointEqualToPoint;
/*!
+ Tests whether the CGPoint is contained by the CGRect.
+ @group CGPoint
+ @param aPoint the CGPoint to check
+ @param aRect the CGRect to check
+ @return BOOL \c YES if the rect contains the point.
+*/
+CPPointInRect = function(aPoint, aRect)
+{
+ return CGRectContainsPoint(aRect, aPoint)
+};
+
+/*!
Test whether the two CGRects have the same origin and size
@group CGRect
@param lhsRect the first CGRect to compare
View
24 Tests/Manual/ArrayController1/AppController.j
@@ -26,11 +26,9 @@ CPLogRegister(CPLogConsole);
- (void)awakeFromCib
{
- var contentView = [theWindow contentView];
+ var contentView = [theWindow contentView],
+ notWrongItem = [Item new];
- //create our non ui objects
-
- var notWrongItem = [Item new];
[notWrongItem setRightOrWrong:"also right"];
itemsArray = [[Item new], notWrongItem];
@@ -104,8 +102,7 @@ CPLogRegister(CPLogConsole);
{
// bind array controller to self's itemsArray
- [arrayController bind:@"contentArray" toObject:self
- withKeyPath:@"itemsArray" options:nil];
+ [arrayController bind:@"contentArray" toObject:self withKeyPath:@"itemsArray" options:nil];
// bind the total field -- no options on this one
[totalCountField bind:CPValueBinding toObject:arrayController
@@ -113,13 +110,14 @@ CPLogRegister(CPLogConsole);
var bindingOptions = [CPDictionary dictionary];
//[bindingOptions setObject:@"No Name" forKey:@"NSNullPlaceholder"];
- [selectedNameField bind: @"value" toObject:arrayController
- withKeyPath:@"selection.name" options:bindingOptions];
+ [selectedNameField bind:CPValueBinding toObject:arrayController
+ withKeyPath:@"selection.name" options:bindingOptions];
// binding for "name" column
var tableColumn = [tableView tableColumnWithIdentifier:@"name"],
- bindingOptions = [CPDictionary dictionary];
- [tableColumn bind:@"value" toObject: arrayController
+ bindingOptions = [CPDictionary dictionary];
+
+ [tableColumn bind:CPValueBinding toObject:arrayController
withKeyPath:@"arrangedObjects.name" options:bindingOptions];
@@ -129,13 +127,13 @@ CPLogRegister(CPLogConsole);
//[bindingOptions removeObjectForKey:@"NSNullPlaceholder"];
//[bindingOptions setObject:YES
// forKey:CPValidatesImmediatelyBindingOption];
- [selectedPriceField bind:@"value" toObject: arrayController
+ [selectedPriceField bind:CPValueBinding toObject: arrayController
withKeyPath:@"selection.price" options:bindingOptions];
// binding for "price" column
tableColumn = [tableView tableColumnWithIdentifier:@"price"];
bindingOptions = [CPDictionary dictionary];
- [tableColumn bind:@"value" toObject: arrayController
+ [tableColumn bind:CPValueBinding toObject:arrayController
withKeyPath:@"arrangedObjects.price" options:bindingOptions];
tableColumn = [tableView tableColumnWithIdentifier:@"all right"];
@@ -215,4 +213,4 @@ CPLogRegister(CPLogConsole);
return aValue == "wrong" ? "right" : aValue;
}
-@end
+@end
View
1  Tests/Manual/AttachedSheet2/MainMenu.ci