diff --git a/AppKit/CPAlert.j b/AppKit/CPAlert.j index 28edbe53d..38aeef5d8 100644 --- a/AppKit/CPAlert.j +++ b/AppKit/CPAlert.j @@ -41,6 +41,9 @@ @global CPApp +var CPAlertDelegate_alertShowHelp_ = 1 << 0, + CPAlertDelegate_alertDidEnd_returnCode_ = 1 << 1; + /* @global @group CPAlertStyle @@ -59,6 +62,14 @@ CPCriticalAlertStyle = 2; var bottomHeight = 71; +@protocol CPAlertDelegate + +@optional +- (BOOL)alertShowHelp:(CPAlert)alert; +- (void)alertDidEnd:(CPAlert)theAlert returnCode:(int)returnCode; + +@end + /*! @ingroup appkit @@ -83,32 +94,33 @@ var bottomHeight = 71; */ @implementation CPAlert : CPObject { - BOOL _showHelp @accessors(property=showsHelp); - BOOL _showSuppressionButton @accessors(property=showsSuppressionButton); + BOOL _showHelp @accessors(property=showsHelp); + BOOL _showSuppressionButton @accessors(property=showsSuppressionButton); - CPAlertStyle _alertStyle @accessors(property=alertStyle); - CPString _title @accessors(property=title); - CPView _accessoryView @accessors(property=accessoryView); - CPImage _icon @accessors(property=icon); + CPAlertStyle _alertStyle @accessors(property=alertStyle); + CPString _title @accessors(property=title); + CPView _accessoryView @accessors(property=accessoryView); + CPImage _icon @accessors(property=icon); - CPArray _buttons @accessors(property=buttons, readonly); - CPCheckBox _suppressionButton @accessors(property=suppressionButton, readonly); + CPArray _buttons @accessors(property=buttons, readonly); + CPCheckBox _suppressionButton @accessors(property=suppressionButton, readonly); - id _delegate @accessors(property=delegate); - id _modalDelegate; - SEL _didEndSelector @accessors(property=didEndSelector); - Function _didEndBlock; + id _delegate @accessors(property=delegate); + id _modalDelegate; + SEL _didEndSelector @accessors(property=didEndSelector); + Function _didEndBlock; + unsigned _implementedDelegateMethods; - _CPAlertThemeView _themeView @accessors(property=themeView, readonly); - CPWindow _window @accessors(property=window, readonly); - int _defaultWindowStyle; + _CPAlertThemeView _themeView @accessors(property=themeView, readonly); + CPWindow _window @accessors(property=window, readonly); + int _defaultWindowStyle; - CPImageView _alertImageView; - CPTextField _informativeLabel; - CPTextField _messageLabel; - CPButton _alertHelpButton; + CPImageView _alertImageView; + CPTextField _informativeLabel; + CPTextField _messageLabel; + CPButton _alertHelpButton; - BOOL _needsLayout; + BOOL _needsLayout; } #pragma mark Creating Alerts @@ -187,6 +199,30 @@ var bottomHeight = 71; return self; } + +#pragma mark - +#pragma mark Delegate + +/*! + Set the delegate of the receiver + @param aDelegate the delegate object for the alert. +*/ +- (void)setDelegate:(id )aDelegate +{ + if (_delegate === aDelegate) + return; + + _delegate = aDelegate; + _implementedDelegateMethods = 0; + + if ([_delegate respondsToSelector:@selector(alertShowHelp:)]) + _implementedDelegateMethods |= CPAlertDelegate_alertShowHelp_; + + if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)]) + _implementedDelegateMethods |= CPAlertDelegate_alertDidEnd_returnCode_; +} + + #pragma mark Accessors - (CPTheme)theme @@ -696,8 +732,7 @@ var bottomHeight = 71; */ - (@action)_showHelp:(id)aSender { - if ([_delegate respondsToSelector:@selector(alertShowHelp:)]) - [_delegate alertShowHelp:self]; + [self _sendDelegateAlertShowHelp]; } /* @@ -743,13 +778,43 @@ var bottomHeight = 71; { if (_didEndSelector) objj_msgSend(_delegate, _didEndSelector, self, returnCode); - else if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)]) - [_delegate alertDidEnd:self returnCode:returnCode]; + else + [self _sendDelegateAlertDidEndReturnCode:returnCode]; } } @end + +@implementation CPAlert (CPAlertDelegate) + +/*! + @ignore + Call the delegate alertDidEnd:returnCode +*/ +- (void)_sendDelegateAlertDidEndReturnCode:(int)returnCode +{ + if (!(_implementedDelegateMethods & CPAlertDelegate_alertDidEnd_returnCode_)) + return; + + [_delegate alertDidEnd:self returnCode:returnCode]; +} + +/*! + @ignore + Call the delegate alertShowHelp: +*/ +- (BOOL)_sendDelegateAlertShowHelp +{ + if (!(_implementedDelegateMethods & CPAlertDelegate_alertShowHelp_)) + return YES; + + return [_delegate alertShowHelp:self]; +} + +@end + + @implementation _CPAlertThemeView : CPView + (CPString)defaultThemeClass diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 224b64112..f26e3b648 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -41,6 +41,21 @@ var CPMainCibFile = @"CPMainCibFile", CPMainCibFileHumanFriendly = @"Main cib file base name", CPEventModifierFlags = 0; + +@protocol CPApplicationDelegate + +@optional +- (void)applicationDidBecomeActive:(CPNotification)aNotification; +- (void)applicationDidChangeScreenParameters:(CPNotification)aNotification; +- (void)applicationDidFinishLaunching:(CPNotification)aNotification; +- (void)applicationDidResignActive:(CPNotification)aNotification; +- (void)applicationWillBecomeActive:(CPNotification)aNotification; +- (void)applicationWillFinishLaunching:(CPNotification)aNotification; +- (void)applicationWillResignActive:(CPNotification)aNotification; +- (void)applicationWillTerminate:(CPNotification)aNotification; + +@end + /*! @ingroup appkit @class CPApplication @@ -68,36 +83,36 @@ var CPMainCibFile = @"CPMainCibFile", */ @implementation CPApplication : CPResponder { - CPArray _eventListeners; - int _eventListenerInsertionIndex; + CPArray _eventListeners; + int _eventListenerInsertionIndex; - CPEvent _currentEvent; - CPWindow _lastMouseMoveWindow; + CPEvent _currentEvent; + CPWindow _lastMouseMoveWindow; - CPArray _windows; - CPWindow _keyWindow; - CPWindow _mainWindow; - CPWindow _previousKeyWindow; - CPWindow _previousMainWindow; + CPArray _windows; + CPWindow _keyWindow; + CPWindow _mainWindow; + CPWindow _previousKeyWindow; + CPWindow _previousMainWindow; - CPDocumentController _documentController; + CPDocumentController _documentController; - CPModalSession _currentSession; + CPModalSession _currentSession; // - id _delegate; - BOOL _finishedLaunching; - BOOL _isActive; + id _delegate; + BOOL _finishedLaunching; + BOOL _isActive; - CPDictionary _namedArgs; - CPArray _args; - CPString _fullArgsString; + CPDictionary _namedArgs; + CPArray _args; + CPString _fullArgsString; - CPImage _applicationIconImage; + CPImage _applicationIconImage; - CPPanel _aboutPanel; + CPPanel _aboutPanel; - CPThemeBlend _themeBlend @accessors(property=themeBlend); + CPThemeBlend _themeBlend @accessors(property=themeBlend); } /*! @@ -143,7 +158,7 @@ var CPMainCibFile = @"CPMainCibFile", react to these events. @param aDelegate the delegate object */ -- (void)setDelegate:(id)aDelegate +- (void)setDelegate:(id )aDelegate { if (_delegate == aDelegate) return; diff --git a/AppKit/CPCollectionView.j b/AppKit/CPCollectionView.j index 8b5955763..5dbd5da53 100644 --- a/AppKit/CPCollectionView.j +++ b/AppKit/CPCollectionView.j @@ -32,6 +32,35 @@ @import "CPPasteboard.j" @import "CPView.j" + +var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_ = 1 << 0, + CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_ = 1 << 1, + CPCollectionViewDelegate_collectionView_writeItemsAtIndexes_toPasteboard_ = 1 << 2, + CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_ = 1 << 3, + CPCollectionViewDelegate_collectionView_dataForItemsAtIndexes_forType_ = 1 << 4, + CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_ = 1 << 5, + CPCollectionViewDelegate_collectionView_didDoubleClickOnItemAtIndex_ = 1 << 6, + CPCollectionViewDelegate_collectionViewDidChangeSelection_ = 1 << 7, + CPCollectionViewDelegate_collectionView_menuForItemAtIndex_ = 1 << 8, + CPCollectionViewDelegate_collectionView_draggingViewForItemsAtIndexes_withEvent_offset = 1 << 9; + + +@protocol CPCollectionViewDelegate + +@optional +- (BOOL)collectionView:(CPCollectionView)collectionView acceptDrop:(id)draggingInfo index:(CPInteger)index dropOperation:(CPCollectionViewDropOperation)dropOperation; +- (BOOL)collectionView:(CPCollectionView)collectionView canDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event; +- (BOOL)collectionView:(CPCollectionView)collectionView writeItemsAtIndexes:(CPIndexSet)indexes toPasteboard:(CPPasteboard)pasteboard; +- (CPArray)collectionView:(CPCollectionView)collectionView dragTypesForItemsAtIndexes:(CPIndexSet)indexes; +- (CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType; +- (CPDragOperation)collectionView:(CPCollectionView)collectionView validateDrop:(id)draggingInfo proposedIndex:(CPInteger)proposedDropIndex dropOperation:(CPCollectionViewDropOperation)proposedDropOperation; +- (CPMenu)collectionView:(CPCollectionView)collectionView menuForItemAtIndex:(CPInteger)anIndex; +- (CPView)collectionView:(CPCollectionView)collectionView dragginViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset; +- (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index; +- (void)collectionViewDidChangeSelection:(CPCollectionView)collectionView; + +@end + /*! @ingroup appkit @class CPCollectionView @@ -69,51 +98,52 @@ var HORIZONTAL_MARGIN = 2; @implementation CPCollectionView : CPView { - CPArray _content; - CPArray _items; + CPArray _content; + CPArray _items; - CPData _itemData; - CPCollectionViewItem _itemPrototype; - CPCollectionViewItem _itemForDragging; - CPMutableArray _cachedItems; + CPData _itemData; + CPCollectionViewItem _itemPrototype; + CPCollectionViewItem _itemForDragging; + CPMutableArray _cachedItems; - unsigned _maxNumberOfRows; - unsigned _maxNumberOfColumns; + unsigned _maxNumberOfRows; + unsigned _maxNumberOfColumns; - CGSize _minItemSize; - CGSize _maxItemSize; + CGSize _minItemSize; + CGSize _maxItemSize; - CPArray _backgroundColors; + CPArray _backgroundColors; - float _tileWidth; + float _tileWidth; - BOOL _isSelectable; - BOOL _allowsMultipleSelection; - BOOL _allowsEmptySelection; - CPIndexSet _selectionIndexes; + BOOL _isSelectable; + BOOL _allowsMultipleSelection; + BOOL _allowsEmptySelection; + CPIndexSet _selectionIndexes; - CGSize _itemSize; + CGSize _itemSize; - float _horizontalMargin; - float _verticalMargin; + float _horizontalMargin; + float _verticalMargin; - unsigned _numberOfRows; - unsigned _numberOfColumns; + unsigned _numberOfRows; + unsigned _numberOfColumns; - id _delegate; + id _delegate; + unsigned _implementedDelegateMethods; - CPEvent _mouseDownEvent; + CPEvent _mouseDownEvent; - BOOL _needsMinMaxItemSizeUpdate; - CGSize _storedFrameSize; + BOOL _needsMinMaxItemSizeUpdate; + CGSize _storedFrameSize; - BOOL _uniformSubviewsResizing @accessors(property=uniformSubviewsResizing); - BOOL _lockResizing; + BOOL _uniformSubviewsResizing @accessors(property=uniformSubviewsResizing); + BOOL _lockResizing; - CPInteger _currentDropIndex; - CPDragOperation _currentDragOperation; + CPInteger _currentDropIndex; + CPDragOperation _currentDragOperation; - _CPCollectionViewDropIndicator _dropView; + _CPCollectionViewDropIndicator _dropView; } - (id)initWithFrame:(CGRect)aFrame @@ -168,6 +198,54 @@ var HORIZONTAL_MARGIN = 2; [self setAutoresizingMask:0]; } + + +#pragma mark - +#pragma mark Delegate + +/*! + Set the delegate of the receiver + @param aDelegate the delegate object for the collectionView. +*/ +- (void)setDelegate:(id )aDelegate +{ + if (_delegate === aDelegate) + return; + + _delegate = aDelegate; + _implementedDelegateMethods = 0; + + if ([_delegate respondsToSelector:@selector(collectionView:acceptDrop:index:dropOperation:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_; + + if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_; + + if ([_delegate respondsToSelector:@selector(collectionView:writeItemsAtIndexes:toPasteboard:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_writeItemsAtIndexes_toPasteboard_; + + if ([_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_; + + if ([_delegate respondsToSelector:@selector(collectionView:dataForItemsAtIndexes:forType:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_dataForItemsAtIndexes_forType_; + + if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_; + + if ([_delegate respondsToSelector:@selector(collectionView:didDoubleClickOnItemAtIndex:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_didDoubleClickOnItemAtIndex_; + + if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionViewDidChangeSelection_; + + if ([_delegate respondsToSelector:@selector(collectionView:menuForItemAtIndex:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_menuForItemAtIndex_; + + if ([_delegate respondsToSelector:@selector(collectionView:draggingViewForItemsAtIndexes:withEvent:offset:)]) + _implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_draggingViewForItemsAtIndexes_withEvent_offset; +} + /*! Sets the item prototype to \c anItem @param anItem the new item prototype. @@ -755,8 +833,8 @@ var HORIZONTAL_MARGIN = 2; - (void)mouseUp:(CPEvent)anEvent { - if ([_selectionIndexes count] && [anEvent clickCount] == 2 && [_delegate respondsToSelector:@selector(collectionView:didDoubleClickOnItemAtIndex:)]) - [_delegate collectionView:self didDoubleClickOnItemAtIndex:[_selectionIndexes firstIndex]]; + if ([_selectionIndexes count] && [anEvent clickCount] == 2) + [self _sendDelegateDidDoubleClickOnItemAtIndex:[_selectionIndexes firstIndex]]; } - (void)mouseDown:(CPEvent)anEvent @@ -846,15 +924,6 @@ var HORIZONTAL_MARGIN = 2; return _verticalMargin; } -/*! - Sets the collection view's delegate - @param aDelegate the new delegate -*/ -- (void)setDelegate:(id)aDelegate -{ - _delegate = aDelegate; -} - /*! Returns the collection view's delegate */ @@ -868,13 +937,13 @@ var HORIZONTAL_MARGIN = 2; */ - (CPMenu)menuForEvent:(CPEvent)theEvent { - if (![[self delegate] respondsToSelector:@selector(collectionView:menuForItemAtIndex:)]) + if (![self _delegateRespondsToCollectionViewMenuForItemAtIndex]) return [super menuForEvent:theEvent]; var location = [self convertPoint:[theEvent locationInWindow] fromView:nil], index = [self _indexAtPoint:location]; - return [_delegate collectionView:self menuForItemAtIndex:index]; + return [self _sendDelegateMenuForItemAtIndex:index]; } - (int)_indexAtPoint:(CGPoint)thePoint @@ -932,7 +1001,7 @@ var HORIZONTAL_MARGIN = 2; */ - (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType { - [aPasteboard setData:[_delegate collectionView:self dataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType]; + [aPasteboard setData:[self _sendDelegateDataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType]; } - (void)_createDropIndicatorIfNeeded @@ -962,24 +1031,23 @@ var HORIZONTAL_MARGIN = 2; (ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3)) return; - if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)]) + if (![self _delegateRespondsToCollectionViewDragTypesForItemsAtIndexes]) return; // If we don't have any selected items, we've clicked away, and thus the drag is meaningless. if (![_selectionIndexes count]) return; - if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)] && - ![_delegate collectionView:self canDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent]) + if (![self _sendDelegateCanDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent]) return; // Set up the pasteboard - var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes]; + var dragTypes = [self _sendDelegateDragTypesForItemsAtIndexes:_selectionIndexes]; [[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self]; var dragImageOffset = CGSizeMakeZero(), - view = [self _draggingViewForItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent offset:dragImageOffset]; + view = [self _sendDelegateDraggingViewForItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent offset:dragImageOffset]; [view setFrameSize:_itemSize]; [view setAlphaValue:0.7]; @@ -996,14 +1064,6 @@ var HORIZONTAL_MARGIN = 2; slideBack:YES]; } -- (CPView)_draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent offset:(CGPoint)offset -{ - if ([_delegate respondsToSelector:@selector(collectionView:draggingViewForItemsAtIndexes:withEvent:offset:)]) - return [_delegate collectionView:self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:offset]; - - return [self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:offset]; -} - - (CPView)draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset { var idx = _content[[indexes firstIndex]]; @@ -1016,14 +1076,6 @@ var HORIZONTAL_MARGIN = 2; return [_itemForDragging view]; } -- (BOOL)_canDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent -{ - if ([self respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)]) - return [_delegate collectionView:self canDragItemsAtIndexes:indexes withEvent:anEvent]; - - return YES; -} - - (CPDragOperation)draggingEntered:(id)draggingInfo { var dropIndex = -1, @@ -1061,16 +1113,14 @@ var HORIZONTAL_MARGIN = 2; var result = CPDragOperationMove, dropIndex = [self _dropIndexForDraggingInfo:draggingInfo proposedDropOperation:dropOperation]; - if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)]) + if ([self _delegateRespondsToCollectionViewValidateDropProposedIndexDropOperation]) { var dropIndexRef2 = @ref(dropIndex); - result = [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation]; + result = [self _sendDelegateValidateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation]; if (result !== CPDragOperationNone) - { dropIndex = dropIndexRef2(); - } } dropIndexRef(dropIndex); @@ -1104,7 +1154,7 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype: var result = NO; if (_currentDragOperation && _currentDropIndex !== -1) - result = [_delegate collectionView:self acceptDrop:draggingInfo index:_currentDropIndex dropOperation:1]; + result = [self _sendDelegateAcceptDrop:draggingInfo index:_currentDropIndex dropOperation:1]; [self draggingEnded:draggingInfo]; // Is this correct ? @@ -1329,6 +1379,7 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype: @end + @implementation CPCollectionView (Deprecated) - (CGRect)rectForItemAtIndex:(int)anIndex @@ -1349,6 +1400,159 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype: @end + +@implementation CPCollectionView (CPCollectionViewDelegate) + +/* + @ignore + Return YES if the delegate implements collectionView:validateDrop:proposedIndex:dropOperation: +*/ +- (BOOL)_delegateRespondsToCollectionViewValidateDropProposedIndexDropOperation +{ + return _implementedDelegateMethods & CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_; +} + +/* + @ignore + Return YES if the delegate implements collectionView:menuForItemAtIndex: +*/ +- (BOOL)_delegateRespondsToCollectionViewMenuForItemAtIndex +{ + return _implementedDelegateMethods & CPCollectionViewDelegate_collectionView_menuForItemAtIndex_; +} + +/* + @ignore + Return YES if the delegate implements collectionView:dragTypesForItemsAtIndexes: +*/ +- (BOOL)_delegateRespondsToCollectionViewDragTypesForItemsAtIndexes +{ + return _implementedDelegateMethods & CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_; +} + +/*! + @ignore + Call delegate collectionView:acceptDrop:index:dropOperation: +*/ +- (BOOL)_sendDelegateAcceptDrop:(id)draggingInfo index:(CPInteger)index dropOperation:(CPCollectionViewDropOperation)dropOperation +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_)) + return NO; + + return [_delegate collectionView:self acceptDrop:draggingInfo index:index dropOperation:dropOperation]; +} + +/*! + @ignore + Call delegate collectionView:canDragItemsAtIndexes:withEvent: +*/ +- (BOOL)_sendDelegateCanDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_)) + return YES; + + return [_delegate collectionView:self canDragItemsAtIndexes:indexes withEvent:anEvent]; +} + +/*! + @ignore + Call delegate collectionView:writeItemsAtIndexes:toPasteboard: +*/ +- (BOOL)_sendDelegateWriteItemsAtIndexes:(CPIndexSet)indexes toPasteboard:(CPPasteboard)pasteboard +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_writeItemsAtIndexes_toPasteboard_)) + return NO; + + return [_delegate collectionView:self writeItemsAtIndexes:indexes toPasteboard:pasteboard]; +} + +/*! + @ignore + Call delegate collectionView:dragTypesForItemsAtIndexes: +*/ +- (CPArray)_sendDelegateDragTypesForItemsAtIndexes:(CPIndexSet)indexes +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_)) + return []; + + return [_delegate collectionView:self dragTypesForItemsAtIndexes:indexes]; +} + +/*! + @ignore + Call delegate collectionView:dataForItemsAtIndexes:forType: +*/ +- (CPData)_sendDelegateDataForItemsAtIndexes:(CPIndexSet)indexes forType:(CPString)aType +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_dataForItemsAtIndexes_forType_)) + return nil; + + return [_delegate collectionView:self dataForItemsAtIndexes:indexes forType:aType]; +} + +/*! + @ignore + Call delegate collectionView:validateDrop:proposedIndex:dropOperation: +*/ +- (CPDragOperation)_sendDelegateValidateDrop:(id)draggingInfo proposedIndex:(CPInteger)proposedDropIndex dropOperation:(CPCollectionViewDropOperation)proposedDropOperation +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_)) + return CPDragOperationNone; + + return [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:proposedDropIndex dropOperation:proposedDropOperation]; +} + +/*! + @ignore + Call delegate collectionView:didDoubleClickOnItemAtIndex: +*/ +- (void)_sendDelegateDidDoubleClickOnItemAtIndex:(int)index +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_didDoubleClickOnItemAtIndex_)) + return; + + return [_delegate collectionView:self didDoubleClickOnItemAtIndex:index]; +} + +/*! + @ignore + Call delegate collectionViewDidChangeSelection +*/ +- (void)_sendDelegateCollectionViewDidChangeSelection:(CPCollectionView)collectionView +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionViewDidChangeSelection_)) + return; + + return [_delegate collectionViewDidChangeSelection:self]; +} + +/*! + @ignore + Call delegate collectionView:menuForItemAtIndex: +*/ +- (void)_sendDelegateMenuForItemAtIndex:(CPInteger)anIndex +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_menuForItemAtIndex_)) + return nil; + + return [_delegate collectionView:self menuForItemAtIndex:anIndex]; +} + +/*! + @ignore + Call delegate draggingViewForItemsAtIndexes:withEvent:offset: +*/ +- (CPView)_sendDelegateDraggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent offset:(CGPoint)dragImageOffset +{ + if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_draggingViewForItemsAtIndexes_withEvent_offset)) + return [self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:dragImageOffset]; + + return [_delegate collectionView:self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:dragImageOffset]; +} + +@end + + var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey", CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey", CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey", diff --git a/AppKit/CPDatePicker/CPDatePicker.j b/AppKit/CPDatePicker/CPDatePicker.j index fbb611a1e..c4442a7b1 100644 --- a/AppKit/CPDatePicker/CPDatePicker.j +++ b/AppKit/CPDatePicker/CPDatePicker.j @@ -206,9 +206,6 @@ CPEraDatePickerElementFlag = 0x0100; if (!_locale) _locale = [CPLocale currentLocale]; - if (!_timeZone) - _timeZone = [CPTimeZone systemTimeZone]; - _datePickerTextfield = [[_CPDatePickerTextField alloc] initWithFrame:[self bounds] withDatePicker:self]; [_datePickerTextfield setDateValue:_dateValue]; @@ -309,7 +306,14 @@ CPEraDatePickerElementFlag = 0x0100; aTimeInterval = MAX(MIN(aTimeInterval, [_maxDate timeIntervalSinceDate:aDateValue]), [_minDate timeIntervalSinceDate:aDateValue]); if ([aDateValue isEqualToDate:_dateValue] && aTimeInterval == _timeInterval) + { + if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle) + [_datePickerTextfield setDateValue:_dateValue]; + else + [_datePickerCalendar setDateValue:_dateValue]; + return; + } if (_implementedCDatePickerDelegateMethods & CPDatePicker_validateProposedDateValue_timeInterval) { @@ -509,6 +513,11 @@ CPEraDatePickerElementFlag = 0x0100; [self didChangeValueForKey:@"timeZone"]; [self setNeedsLayout]; + + if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle) + [_datePickerTextfield setDateValue:_dateValue]; + else + [_datePickerCalendar setDateValue:_dateValue]; } diff --git a/AppKit/CPDatePicker/_CPDatePickerTextField.j b/AppKit/CPDatePicker/_CPDatePickerTextField.j index 59033f99e..8dbb21eaf 100644 --- a/AppKit/CPDatePicker/_CPDatePickerTextField.j +++ b/AppKit/CPDatePicker/_CPDatePickerTextField.j @@ -66,7 +66,6 @@ var CPZeroKeyCode = 48, _CPDatePickerElementView _datePickerElementView; CPDatePicker _datePicker; CPStepper _stepper; - CPTimer _timerEdition; } @@ -101,7 +100,7 @@ var CPZeroKeyCode = 48, #pragma mark - -#pragma mark Responder methods +#pragma mark Override responder methods - (BOOL)becomeFirstResponder { @@ -116,7 +115,7 @@ var CPZeroKeyCode = 48, - (BOOL)resignFirstResponder { // End the timer of editing - [self _endTimer]; + [_currentTextField _endEditing]; // Don't forget to unbind, otherwise several steppers will increase or decrease [_currentTextField unbind:@"objectValue"]; @@ -129,6 +128,10 @@ var CPZeroKeyCode = 48, return YES; } +- (BOOL)canBecomeKeyView +{ + return NO; +} #pragma mark - #pragma mark Setter Getter methods @@ -141,7 +144,6 @@ var CPZeroKeyCode = 48, { var dateValue = [aDateValue copy]; [dateValue _dateWithTimeZone:[_datePicker timeZone]]; - [_datePickerElementView setDateValue:dateValue]; } @@ -202,7 +204,7 @@ var CPZeroKeyCode = 48, return; // End the timer of editing - [self _endTimer]; + [_currentTextField _endEditing]; // Don't forget to unbind, otherwise several steppers will increase or decrease [_currentTextField unbind:@"objectValue"]; @@ -215,7 +217,7 @@ var CPZeroKeyCode = 48, if ([_currentTextField dateType] != CPAMPMDateType) { // We update the value of the stepper dependind on the textField - [_stepper setObjectValue:parseInt([_currentTextField objectValue])]; + [_stepper setObjectValue:parseInt([_currentTextField stringValue])]; [_stepper setMaxValue:[_currentTextField maxNumber]]; [_stepper setMinValue:[_currentTextField minNumber]]; @@ -281,7 +283,7 @@ var CPZeroKeyCode = 48, if (key == CPUpArrowFunctionKey) { - [self _endTimer]; + [_currentTextField _invalidTimer]; [_stepper setDoubleValue:parseInt([_currentTextField objectValue])]; [_stepper performClickUp:self]; return YES; @@ -289,7 +291,7 @@ var CPZeroKeyCode = 48, if (key == CPDownArrowFunctionKey) { - [self _endTimer]; + [_currentTextField _invalidTimer]; [_stepper setDoubleValue:parseInt([_currentTextField objectValue])]; [_stepper performClickDown:self]; return YES; @@ -299,8 +301,10 @@ var CPZeroKeyCode = 48, { if (_currentTextField == _firstTextField && [anEvent keyCode] == CPTabKeyCode) { - if ([_datePicker previousKeyView]) - [[self window] makeFirstResponder:[_datePicker previousKeyView]]; + var previousValidKeyView = [_datePicker previousValidKeyView]; + + if (previousValidKeyView) + [[self window] makeFirstResponder:previousValidKeyView]; return YES; } @@ -311,19 +315,23 @@ var CPZeroKeyCode = 48, if (key == CPRightArrowFunctionKey || [anEvent keyCode] == CPTabKeyCode) { - if (_currentTextField == _lastTextField && [anEvent keyCode] == CPTabKeyCode) { - if ([_datePicker nextKeyView]) - [[self window] makeFirstResponder:[_datePicker nextKeyView]]; + var nextValidKeyView = [_datePicker nextValidKeyView]; + + if (nextValidKeyView) + [[self window] makeFirstResponder:nextValidKeyView]; return YES; + } - } [self _selectTextField:[_currentTextField nextTextField]]; return YES; } + [self _selectTextField:[_currentTextField nextTextField]]; + return YES; + } - if ([anEvent keyCode] == CPReturnKeyCode && _timerEdition) + if ([anEvent keyCode] == CPReturnKeyCode) { - [_timerEdition fire]; + [_currentTextField _endEditing]; return YES; } @@ -350,84 +358,7 @@ var CPZeroKeyCode = 48, return; } - if ([anEvent keyCode] != CPDeleteKeyCode && [anEvent keyCode] != CPDeleteForwardKeyCode && [anEvent keyCode] < CPZeroKeyCode || [anEvent keyCode] > CPNineKeyCode) - return; - - // Here, at the first editing we launch a timer to auto-finish the editing. There is another behavior when the user has already edited something - if (!_timerEdition) - { - _timerEdition = [CPTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(_timerKeyEvent:) userInfo:nil repeats:NO]; - - // Take care about the delete key - if ([anEvent keyCode] == CPDeleteKeyCode || [anEvent keyCode] == CPDeleteForwardKeyCode) - [_currentTextField setStringKeyValue:@""]; - else - [_currentTextField setStringKeyValue:[anEvent characters]]; - } - else - { - var newFireDate = [CPDate date], - key; - - newFireDate.setSeconds(newFireDate.getSeconds() + 2); - - [_timerEdition setFireDate:newFireDate]; - - // Take care about the delete key - if ([anEvent keyCode] == CPDeleteKeyCode || [anEvent keyCode] == CPDeleteForwardKeyCode) - key = [[_currentTextField stringValue] substringToIndex:[[_currentTextField stringValue] length] - 1]; - else - key = [CPString stringWithFormat:@"%i%i",parseInt([_currentTextField stringValue]), parseInt([anEvent characters])]; - - [_currentTextField setStringKeyValue:key]; - } -} - - -#pragma mark - -#pragma mark Timer event - -/*! End of the timer -*/ -- (void)_timerKeyEvent:(id)sender -{ - _timerEdition = nil; - - if (![[_currentTextField stringValue] isEqualToString:@" "] && ![[_currentTextField stringValue] isEqualToString:@" "]) - { - var value = [_currentTextField stringValue]; - - if ([_datePicker _isEnglishFormat] && [_currentTextField dateType] == CPHourDateType) - { - if (![_datePickerElementView _isAMHour] && value != 12) - value = parseInt(value) + 12; - - if (value == 12 && ![_datePickerElementView _isAMHour]) - value = 12; - else if (value == 12) - value = 0; - } - - [_currentTextField setObjectValue:value]; - } - else - { - [_currentTextField setObjectValue:@"0"]; - } - - -} - -/*! We force to end the timer -*/ -- (void)_endTimer -{ - if (_timerEdition) - { - [_timerEdition invalidate]; - [self _timerKeyEvent:_timerEdition]; - _timerEdition = nil; - } + [_currentTextField setValueForKeyEvent:anEvent]; } @@ -518,6 +449,7 @@ var CPZeroKeyCode = 48, [_textFieldDay setDateType:CPDayDateType]; [_textFieldDay setDatePicker:_datePicker]; [_textFieldDay setAlignment:CPRightTextAlignment]; + [_textFieldDay setDatePickerElementView:self]; [self addSubview:_textFieldDay]; _textFieldMonth = [_CPDatePickerElementTextField new]; @@ -526,6 +458,7 @@ var CPZeroKeyCode = 48, [_textFieldMonth setDateType:CPMonthDateType]; [_textFieldMonth setDatePicker:_datePicker]; [_textFieldMonth setAlignment:CPRightTextAlignment]; + [_textFieldMonth setDatePickerElementView:self]; [self addSubview:_textFieldMonth]; _textFieldYear = [_CPDatePickerElementTextField new]; @@ -534,6 +467,7 @@ var CPZeroKeyCode = 48, [_textFieldYear setDateType:CPYearDateType]; [_textFieldYear setDatePicker:_datePicker]; [_textFieldYear setAlignment:CPRightTextAlignment]; + [_textFieldYear setDatePickerElementView:self]; [self addSubview:_textFieldYear]; _textFieldHour = [_CPDatePickerElementTextField new]; @@ -542,6 +476,7 @@ var CPZeroKeyCode = 48, [_textFieldHour setDateType:CPHourDateType]; [_textFieldHour setDatePicker:_datePicker]; [_textFieldHour setAlignment:CPRightTextAlignment]; + [_textFieldHour setDatePickerElementView:self]; [self addSubview:_textFieldHour]; _textFieldMinute = [_CPDatePickerElementTextField new]; @@ -550,6 +485,7 @@ var CPZeroKeyCode = 48, [_textFieldMinute setDateType:CPMinuteDateType]; [_textFieldMinute setDatePicker:_datePicker]; [_textFieldMinute setAlignment:CPRightTextAlignment]; + [_textFieldMinute setDatePickerElementView:self]; [self addSubview:_textFieldMinute]; _textFieldSecond = [_CPDatePickerElementTextField new]; @@ -558,6 +494,7 @@ var CPZeroKeyCode = 48, [_textFieldSecond setDateType:CPSecondDateType]; [_textFieldSecond setDatePicker:_datePicker]; [_textFieldSecond setAlignment:CPRightTextAlignment]; + [_textFieldSecond setDatePickerElementView:self]; [self addSubview:_textFieldSecond]; _textFieldPMAM = [_CPDatePickerElementTextField new]; @@ -566,6 +503,7 @@ var CPZeroKeyCode = 48, [_textFieldPMAM setDateType:CPAMPMDateType]; [_textFieldPMAM setDatePicker:_datePicker]; [_textFieldPMAM setAlignment:CPRightTextAlignment]; + [_textFieldPMAM setDatePickerElementView:self]; [self addSubview:_textFieldPMAM]; _textFieldSeparatorOne = [CPTextField labelWithTitle:@"/"]; @@ -614,6 +552,13 @@ var CPZeroKeyCode = 48, [_textFieldPMAM setStringValue:@"AM"]; } +/*! Set the day date value to the appropriate textField + @param aDayDateValue the day +*/ +- (void)setDayDateValue:(CPString)aDayDateValue +{ + [_textFieldDay setStringValue:aDayDateValue]; +} /*! Set the widget enabled or not @param aBoolean @@ -641,6 +586,65 @@ var CPZeroKeyCode = 48, return [[_textFieldPMAM stringValue] isEqualToString:@"AM"]; } +- (CPDate)dateValue +{ + var date = [[_datePicker dateValue] copy]; + + [date _dateWithTimeZone:[_datePicker timeZone]]; + + if (![_textFieldDay isHidden]) + date.setDate([_textFieldDay stringValue]); + + if (![_textFieldMonth isHidden]) + date.setMonth(parseInt([_textFieldMonth stringValue]) - 1); + + if (![_textFieldYear isHidden]) + date.setFullYear([_textFieldYear stringValue]); + + if (![_textFieldSecond isHidden]) + date.setSeconds([_textFieldSecond stringValue]); + + if (![_textFieldMinute isHidden]) + date.setMinutes([_textFieldMinute stringValue]); + + if (![_textFieldHour isHidden]) + { + var hour = parseInt([_textFieldHour stringValue]), + currentHour = parseInt(date.getHours()); + + if (hour != currentHour) + { + if (([_datePicker _isEnglishFormat] || [_datePicker _isAmericanFormat])) + { + if (![self _isAMHour]) + { + if (!(currentHour == 12 && hour == 11) && hour < 13) + hour = hour + 12; + } + else if (hour == 12 && currentHour != 11) + { + hour = 0; + } + else if (currentHour == 0 && hour == 11) + { + hour = 23; + } + else if (hour == 13) + { + hour = 1; + } + } + + if (hour == 24) + hour = 0; + + date.setHours(hour); + } + } + + return date; +} + #pragma mark - #pragma mark Notification methods @@ -1208,14 +1212,17 @@ var CPMonthDateType = 0, */ @implementation _CPDatePickerElementTextField : CPTextField { - _CPDatePickerElementTextField _nextTextField @accessors(property=nextTextField); - _CPDatePickerElementTextField _previousTextField @accessors(property=previousTextField); + _CPDatePickerElementTextField _nextTextField @accessors(property=nextTextField); + _CPDatePickerElementTextField _previousTextField @accessors(property=previousTextField); + _CPDatePickerElementView _datePickerElementView @accessors(property=datePickerElementView); CPDatePicker _datePicker @accessors(setter=setDatePicker:); int _dateType @accessors(getter=dateType); int _maxNumber @accessors(getter=maxNumber); int _minNumber @accessors(getter=minNumber); + + CPTimer _timerEdition; } @@ -1325,32 +1332,120 @@ var CPMonthDateType = 0, It's called when the user is editing with the keyboard @param aStringValue a CPString */ -- (void)setStringKeyValue:(id)anObjectValue +- (void)setValueForKeyEvent:(CPEvent)anEvent { - if (_dateType == CPYearDateType) - { - if ([anObjectValue length] > 4) - return + var keyCode = [anEvent keyCode]; - while ([anObjectValue length] < 4) - anObjectValue = " " + anObjectValue; + if (keyCode != CPDeleteKeyCode && keyCode != CPDeleteForwardKeyCode && keyCode < CPZeroKeyCode || keyCode > CPNineKeyCode) + return; + + var newValue = [self stringValue], + length = [newValue length], + eventKeyValue = parseInt([anEvent characters]).toString(); + + if (keyCode == CPDeleteKeyCode || keyCode == CPDeleteForwardKeyCode) + { + [_timerEdition invalidate]; + _timerEdition = nil; + newValue = [newValue substringToIndex:(length - 1)]; } else { - if ([anObjectValue length] > 2) - return + if (!_timerEdition) + { + _timerEdition = [CPTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(_timerKeyEvent:) userInfo:nil repeats:NO]; - while ([anObjectValue length] < 2) - anObjectValue = " " + anObjectValue; + if ((_dateType == CPYearDateType && length == 4) || (_dateType != CPYearDateType && length == 2) || !length) + newValue = eventKeyValue; + else + newValue = parseInt(newValue).toString() + eventKeyValue; + } + else + { + var newFireDate = [CPDate date]; + + newFireDate.setSeconds(newFireDate.getSeconds() + 2); + [_timerEdition setFireDate:newFireDate]; + + newValue = parseInt(newValue).toString() + eventKeyValue; + } } - if (parseInt(anObjectValue) > [self _maxNumberWithMaxDate]) + if (parseInt(newValue) > [self _maxNumberWithMaxDate] || ([_datePicker _isEnglishFormat] && _dateType == CPHourDateType && parseInt(newValue) > 12)) return; - if ([_datePicker _isEnglishFormat] && _dateType == CPHourDateType && parseInt(anObjectValue) > 12) - return; + [super setObjectValue:newValue]; +} - [super setObjectValue:anObjectValue]; +/*! + End of the timer +*/ +- (void)_timerKeyEvent:(id)sender +{ + var stringValue = [self stringValue]; + + _timerEdition = nil; + + if ([stringValue length]) + { + if ([_datePicker _isEnglishFormat] && [self dateType] == CPHourDateType) + { + var isAMHour = [[self superview] _isAMHour]; + + if (!isAMHour && stringValue != 12) + stringValue = parseInt(stringValue) + 12; + + if (stringValue == 12 && !isAMHour) + stringValue = 12; + else if (stringValue == 12) + stringValue = 0; + } + + [self setObjectValue:stringValue]; + } +} + +/*! + We force to end the timer +*/ +- (void)_invalidTimer +{ + if (_timerEdition) + { + [_timerEdition invalidate]; + _timerEdition = nil; + } +} + +/*! + We force to end the timer and to update the objectValue of the datePicker +*/ +- (void)_endEditing +{ + if (_timerEdition) + [_timerEdition invalidate]; + + _timerEdition = nil; + + var objectValue = [self stringValue]; + + if (![objectValue length]) + objectValue = [self objectValue]; + + if ([_datePicker _isEnglishFormat] && [self dateType] == CPHourDateType) + { + var isAMHour = [[self superview] _isAMHour]; + + if (!isAMHour && objectValue != 12) + objectValue = parseInt(objectValue) + 12; + + if (objectValue == 12 && !isAMHour) + objectValue = 12; + else if (objectValue == 12) + objectValue = 0; + } + + [self setObjectValue:objectValue]; } /*! Set the stringValue of the TextField. Add some zeros of there isn't 2/4 letters in the value. It's called at the end of the editing process @@ -1391,12 +1486,20 @@ var CPMonthDateType = 0, */ - (void)setObjectValue:(id)anObjectValue { - var dateValue = [[_datePicker dateValue] copy]; + var dateValue = [[_datePicker dateValue] copy], + lengthString = [[self stringValue] length], + objectValue = parseInt(anObjectValue); switch (_dateType) { case CPMonthDateType: + if (objectValue == 0 || !lengthString) + { + [self setStringValue:(dateValue.getMonth() + 1).toString()]; + return; + } + var dateNextMonth = [dateValue copy]; dateNextMonth.setDate(1); @@ -1405,76 +1508,81 @@ var CPMonthDateType = 0, var numberDayNextMonth = [dateNextMonth _daysInMonth]; if (numberDayNextMonth < [dateValue _daysInMonth] && dateValue.getDate() > numberDayNextMonth) - dateValue.setDate(numberDayNextMonth); + [_datePickerElementView setDayDateValue:numberDayNextMonth.toString()]; - dateValue.setMonth(parseInt(anObjectValue) - 1); + [super setObjectValue:objectValue]; break; case CPDayDateType: - dateValue.setDate(parseInt(anObjectValue)); + + if (objectValue == 0 || !lengthString) + { + [self setStringValue:dateValue.getDate().toString()]; + return; + } + + [super setObjectValue:objectValue]; break; case CPYearDateType: - dateValue.setFullYear(parseInt(anObjectValue)); + + if (objectValue == 0 || !lengthString) + { + [self setStringValue:dateValue.getFullYear().toString()]; + return; + } + + [super setObjectValue:objectValue]; break; case CPHourDateType: - dateValue.setHours(parseInt(anObjectValue)); + + if (!lengthString) + { + [self setStringValue:dateValue.getHours().toString()]; + return; + } + + [super setObjectValue:objectValue]; break; case CPSecondDateType: - dateValue.setSeconds(parseInt(anObjectValue)); + + if (!lengthString) + { + [self setStringValue:dateValue.getSeconds().toString()]; + return; + } + [super setObjectValue:objectValue]; break; case CPMinuteDateType: - dateValue.setMinutes(parseInt(anObjectValue)); + + if (!lengthString) + { + [self setStringValue:dateValue.getMinutes().toString()]; + return; + } + + [super setObjectValue:objectValue]; break; } - [_datePicker setDateValue:dateValue]; -} + var newDateValue = [_datePickerElementView dateValue], + timeZone = [_datePicker timeZone]; -/*! Return the objectValue of the textField. Needed for the binding. - This returns the objectValue relative to the dateValue -*/ -- (id)objectValue -{ - var dateValue = [[_datePicker dateValue] copy]; - - switch (_dateType) + if (timeZone) { - case CPMonthDateType: - return dateValue.getMonth() + 1; - break; + var secondsFromGMT = [timeZone secondsFromGMTForDate:newDateValue], + secondsFromGMTTimeZone = [timeZone secondsFromGMT]; - case CPDayDateType: - return dateValue.getDate(); - break; - - case CPYearDateType: - return dateValue.getFullYear(); - break; - - case CPHourDateType: - return dateValue.getHours(); - break; - - case CPSecondDateType: - return dateValue.getSeconds(); - break; - - case CPMinuteDateType: - return dateValue.getMinutes(); - break; - - default: - return [super objectValue]; - break; + newDateValue.setSeconds(newDateValue.getSeconds() + secondsFromGMT - secondsFromGMTTimeZone); } - return [super objectValue]; + [_datePicker setDateValue:newDateValue]; } + #pragma mark - #pragma mark Mouse event @@ -1507,4 +1615,65 @@ var CPMonthDateType = 0, [self unsetThemeState:CPThemeStateSelected]; } + +#pragma mark - +#pragma mark Override + +/*! + We override this method to get all the time the good width +*/ +- (CGSize)_minimumFrameSize +{ + var frameSize = [self frameSize], + contentInset = [self currentValueForThemeAttribute:@"content-inset"], + minSize = [self currentValueForThemeAttribute:@"min-size"], + maxSize = [self currentValueForThemeAttribute:@"max-size"], + lineBreakMode = [self lineBreakMode], + text = (_dateType == CPYearDateType) ? @"0000" : @"00", + textSize = CGSizeMakeCopy(frameSize), + font = [self currentValueForThemeAttribute:@"font"]; + + textSize.width -= contentInset.left + contentInset.right; + textSize.height -= contentInset.top + contentInset.bottom; + + if (_dateType == CPAMPMDateType) + text = [self stringValue]; + + if (frameSize.width !== 0 && + ![self isBezeled] && + (lineBreakMode === CPLineBreakByWordWrapping || lineBreakMode === CPLineBreakByCharWrapping)) + { + 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]) + { + frameSize.height = MAX(frameSize.height, minSize.height); + + if (maxSize.width > 0.0) + frameSize.width = MIN(frameSize.width, maxSize.width); + + if (maxSize.height > 0.0) + frameSize.height = MIN(frameSize.height, maxSize.height); + } + else + frameSize.width = textSize.width + contentInset.left + contentInset.right; + + frameSize.width = MAX(frameSize.width, minSize.width); + + return frameSize; +} + @end diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index c4b576e46..220c50202 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -88,6 +88,57 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, #define SHOULD_SELECT_ITEM(anOutlineView, anItem) (!((anOutlineView)._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_) || [(anOutlineView)._outlineViewDelegate outlineView:(anOutlineView) shouldSelectItem:(anItem)]) + +@protocol CPOutlineViewDelegate + +@optional +- (BOOL)outlineView:(CPOutlineView)anOutlineView isGroupItem:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldCollapseItem:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldEditTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldExpandItem:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldReorderColumn:(CPInteger)columnIndex toColumn:(CPInteger)newColumnIndex; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldSelectItem:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldSelectTableColumn:(CPTableColumn)aTableColumn; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldShowOutlineDisclosureControlForItem:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldShowViewExpansionForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldTrackView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldTypeSelectForEvent:(CPEvent)anEvent withCurrentSearchString:(CPString)searchString; +- (BOOL)selectionShouldChangeInOutlineView:(CPOutlineView)anOutlineView; +- (CPIndexSet)outlineView:(CPOutlineView)anOutlineView selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes; +- (CPMenu)outlineView:(CPOutlineView)anOutlineView menuForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (CPString)outlineView:(CPOutlineView)anOutlineView toolTipForView:(CPView)aView rect:(CGRect)aRect tableColumn:(CPTableColumn)aTableColumn item:(id)anItem mouseLocation:(CGPoint)mouseLocation; +- (CPString)outlineView:(CPOutlineView)anOutlineView typeSelectStringForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (CPView)outlineView:(CPOutlineView)anOutlineView dataViewForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (CPView)outlineView:(CPOutlineView)anOutlineView viewForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (float)outlineView:(CPOutlineView)anOutlineView heightOfRowByItem:(id)anItem; +- (float)outlineView:(CPOutlineView)anOutlineView sizeToFitWidthOfColumn:(CPTableColumn)aTableColumn; +- (id)outlineView:(CPOutlineView)anOutlineView nextTypeSelectMatchFromItem:(id)startItem toItem:(id)endItem forString:(CPString)searchString; +- (void)outlineView:(CPOutlineView)anOutlineView didClickTableColumn:(CPTableColumn)aTableColumn; +- (void)outlineView:(CPOutlineView)anOutlineView didDragTableColumn:(CPTableColumn)aTableColumn; +- (void)outlineView:(CPOutlineView)anOutlineView mouseDownInHeaderOfTableColumn:(CPTableColumn)aTableColumn; +- (void)outlineView:(CPOutlineView)anOutlineView willDisplayOutlineView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; +- (void)outlineView:(CPOutlineView)anOutlineView willDisplayView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem; + +@end + + +@protocol CPOutlineViewDataSource + +@optional +- (BOOL)outlineView:(CPOutlineView)anOutlineView acceptDrop:(id /**/)info item:(id)anItem childIndex:(CPInteger)anIndex; +- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldDeferDisplayingChildrenOfItem:(id)anItem; +- (BOOL)outlineView:(CPOutlineView)anOutlineView writeItems:(CPArray)items toPasteboard:(CPPasteboard)pboard; +- (CPArray)outlineView:(CPOutlineView)anOutlineView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedItems:(CPArray)items; +- (CPDragOperation)outlineView:(CPOutlineView)anOutlineView validateDrop:(id /**/)info proposedItem:(id)anItem proposedChildIndex:(CPInteger)anIndex; +- (CPDragOperation)outlineView:(CPOutlineView)anOutlineView validateDrop:(id /**/)info proposedRow:(int)theRow proposedDropOperation:(CPTableViewDropOperation)theOperation; +- (id)outlineView:(CPOutlineView)anOutlineView itemForPersistentObject:(id)anObject; +- (id)outlineView:(CPOutlineView)anOutlineView objectValueforTableColumn:(CPTableColumn)aTableColumn byItem:(id)anItem; +- (id)outlineView:(CPOutlineView)anOutlineView persistentObjectForItem:(id)anItem; +- (void)outlineView:(CPOutlineView)anOutlineView setObjectValue:(id)anObject forTableColumn:(CPTableColumn)aTableColumn byItem:(id)anItem; +- (void)outlineView:(CPOutlineView)anOutlineView sortDescriptorsDidChange:(CPArray)oldDescriptors; + +@end + /*! @ingroup appkit @class CPOutlineView @@ -105,34 +156,34 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, */ @implementation CPOutlineView : CPTableView { - id _outlineViewDataSource; - id _outlineViewDelegate; - CPTableColumn _outlineTableColumn; + id _outlineViewDataSource; + id _outlineViewDelegate; + CPTableColumn _outlineTableColumn; - float _indentationPerLevel; - BOOL _indentationMarkerFollowsDataView; + float _indentationPerLevel; + BOOL _indentationMarkerFollowsDataView; - CPInteger _implementedOutlineViewDataSourceMethods; - CPInteger _implementedOutlineViewDelegateMethods; + CPInteger _implementedOutlineViewDataSourceMethods; + CPInteger _implementedOutlineViewDelegateMethods; - Object _rootItemInfo; - CPMutableArray _itemsForRows; - Object _itemInfosForItems; + Object _rootItemInfo; + CPMutableArray _itemsForRows; + Object _itemInfosForItems; - CPControl _disclosureControlPrototype; - CPArray _disclosureControlsForRows; - CPData _disclosureControlData; - CPArray _disclosureControlQueue; + CPControl _disclosureControlPrototype; + CPArray _disclosureControlsForRows; + CPData _disclosureControlData; + CPArray _disclosureControlQueue; - BOOL _shouldRetargetItem; - id _retargetedItem; + BOOL _shouldRetargetItem; + id _retargetedItem; - BOOL _shouldRetargetChildIndex; - CPInteger _retargedChildIndex; - CPTimer _dragHoverTimer; - id _dropItem; + BOOL _shouldRetargetChildIndex; + CPInteger _retargedChildIndex; + CPTimer _dragHoverTimer; + id _dropItem; - BOOL _coalesceSelectionNotificationState; + BOOL _coalesceSelectionNotificationState; } - (id)initWithFrame:(CGRect)aFrame @@ -218,7 +269,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, If you want the drag to begin you should return YES and place the drag data on the pboard. @code - (BOOL)outlineView:(CPOutlineView)outlineView writeItems:(CPArray)items toPasteboard:(CPPasteboard)pboard; @endcode */ -- (void)setDataSource:(id)aDataSource +- (void)setDataSource:(id )aDataSource { if (_outlineViewDataSource === aDataSource) return; @@ -826,7 +877,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0, @code - (int)outlineView:(CPOutlineView)outlineView heightOfRowByItem:(id)anItem; @endcode */ -- (void)setDelegate:(id)aDelegate +- (void)setDelegate:(id )aDelegate { if (_outlineViewDelegate === aDelegate) return; diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 06f216b8c..6aa303cae 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -33,10 +33,22 @@ CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border. CPNoTabsLineBorder = 5; //Has no tabs and displays a line border. CPNoTabsNoBorder = 6; //Displays no tabs and no border. -var CPTabViewDidSelectTabViewItemSelector = 1, - CPTabViewShouldSelectTabViewItemSelector = 2, - CPTabViewWillSelectTabViewItemSelector = 4, - CPTabViewDidChangeNumberOfTabViewItemsSelector = 8; +var CPTabViewDidSelectTabViewItemSelector = 1 << 1, + CPTabViewShouldSelectTabViewItemSelector = 1 << 2, + CPTabViewWillSelectTabViewItemSelector = 1 << 3, + CPTabViewDidChangeNumberOfTabViewItemsSelector = 1 << 4; + + +@protocol CPTabViewDelegate + +@optional +- (BOOL)tabView:(CPTabView)tabView shouldSelectTabViewItem:(CPTabViewItem)tabViewItem; +- (void)tabView:(CPTabView)tabView didSelectTabViewItem:(CPTabViewItem)tabViewItem; +- (void)tabView:(CPTabView)tabView willSelectTabViewItem:(CPTabViewItem)tabViewItem; +- (void)tabViewDidChangeNumberOfTabViewItems:(CPTabView)tabView; + +@end + /*! @ingroup appkit @@ -48,18 +60,18 @@ var CPTabViewDidSelectTabViewItemSelector = 1, */ @implementation CPTabView : CPView { - CPArray _items; + CPArray _items; - CPSegmentedControl _tabs; - CPBox _box; + CPSegmentedControl _tabs; + CPBox _box; - CPNumber _selectedIndex; + CPNumber _selectedIndex; - CPTabViewType _type; - CPFont _font; + CPTabViewType _type; + CPFont _font; - id _delegate; - unsigned _delegateSelectors; + id _delegate; + unsigned _delegateSelectors; } - (id)initWithFrame:(CGRect)aFrame @@ -405,7 +417,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1, Sets the delegate for this tab view. @param aDelegate the tab view's delegate */ -- (void)setDelegate:(id)aDelegate +- (void)setDelegate:(id )aDelegate { if (_delegate == aDelegate) return; diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 54d2f976a..038e74691 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -58,7 +58,6 @@ var CPTableViewDataSource_numberOfRowsInTableView_ CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_ = 1 << 4, CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 5, CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_ = 1 << 6, - CPTableViewDataSource_tableView_sortDescriptorsDidChange_ = 1 << 7; var CPTableViewDelegate_selectionShouldChangeInTableView_ = 1 << 0, @@ -121,6 +120,50 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; #define ROW_BOTTOM(__heightInfo) (__heightInfo.y + __heightInfo.height + _intercellSpacing.height) #define HAS_VARIABLE_ROW_HEIGHTS() (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_) + +@protocol CPTableViewDataSource + +@optional +- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id )info row:(CPInteger)aRowIndex dropOperation:(CPTableViewDropOperation)operation; +- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard; +- (CPArray)tableView:(CPTableView)aTableView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedRowsWithIndexes:(CPIndexSet)anIndexSet; +- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id )info proposedRow:(CPInteger)aRowIndex proposedDropOperation:(CPTableViewDropOperation)anOperation; +- (CPInteger)numberOfRowsInTableView:(CPTableView)aTableView; +- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (void)tableView:(CPTableView)aTableView setObjectValue:(id)anObjectValue forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (void)tableView:(CPTableView)aTableView sortDescriptorsDidChange:(CPArray)oldDescriptors; + +@end + +@protocol CPTableViewDelegate + +@optional +- (BOOL)selectionShouldChangeInTableView:(CPTableView)aTableView; +- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(CPInteger)aRowIndex; +- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aTableView row:(CPInteger)aRowIndex; +- (BOOL)tableView:(CPTableView)aTableView shouldReorderColumn:(CPInteger)columnIndex toColumn:(NSInteger)newColumnIndex; +- (BOOL)tableView:(CPTableView)aTableView shouldSelectRow:(CPInteger)aRowIndex; +- (BOOL)tableView:(CPTableView)aTableView shouldSelectTableColumn:(CPTableColumn)aTableColumn; +- (BOOL)tableView:(CPTableView)aTableView shouldShowViewExpansionForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (BOOL)tableView:(CPTableView)aTableView shouldTrackView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (BOOL)tableView:(CPTableView)aTableView shouldTypeSelectForEvent:(CPEvent)anEvent withCurrentSearchString:(CPString)searchString; +- (CPIndexSet)tableView:(CPTableView)aTableView selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes; +- (CPInteger)tableView:(CPTableView)aTableView nextTypeSelectMatchFromRow:(CPInteger)startRow toRow:(CPInteger)endRow forString:(CPString)searchString; +- (CPMenu)tableViewMenuForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (CPString)tableView:(CPTableView)aTableView toolTipForView:(CPView)aView rect:(CGRect)aRect tableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex mouseLocation:(CGPoint)mouseLocation; +- (CPString)tableView:(CPTableView)aTableView typeSelectStringForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (CPView)tableView:(CPTableView)aTableView dataViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (CPView)tableView:(CPTableView)aTableView viewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (float)tableView:(CPTableView)aTableView heightOfRow:(CPInteger)aRowIndex; +- (void)tableView:(CPTableView)aTableView didClickTableColumn:(CPTableColumn)aTableColumn; +- (void)tableView:(CPTableView)aTableView didDragTableColumn:(CPTableColumn)aTableColumn; +- (void)tableView:(CPTableView)aTableView mouseDownInHeaderOfTableColumn:(CPTableColumn)aTableColumn; +- (void)tableView:(CPTableView)aTableView willDisplayView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex; +- (void)tableViewSelectionDidChange:(CPNotification)aNotification; +- (void)tableViewSelectionIsChanging:(CPNotification)aNotification; + +@end + @implementation _CPTableDrawView : CPView { CPTableView _tableView; @@ -173,106 +216,106 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; */ @implementation CPTableView : CPControl { - id _dataSource; - CPInteger _implementedDataSourceMethods; + id _dataSource; + CPInteger _implementedDataSourceMethods; - id _delegate; - CPInteger _implementedDelegateMethods; + id _delegate; + CPInteger _implementedDelegateMethods; - CPArray _tableColumns; - CPArray _tableColumnRanges; - CPInteger _dirtyTableColumnRangeIndex; - CPInteger _numberOfHiddenColumns; + CPArray _tableColumns; + CPArray _tableColumnRanges; + CPInteger _dirtyTableColumnRangeIndex; + CPInteger _numberOfHiddenColumns; - BOOL _reloadAllRows; - Object _objectValues; + BOOL _reloadAllRows; + Object _objectValues; - CGRect _exposedRect; - CPIndexSet _exposedRows; - CPIndexSet _exposedColumns; + CGRect _exposedRect; + CPIndexSet _exposedRows; + CPIndexSet _exposedColumns; - Object _dataViewsForTableColumns; - Object _cachedDataViews; - CPDictionary _archivedDataViews; - Object _unavailable_custom_cibs; + Object _dataViewsForTableColumns; + Object _cachedDataViews; + CPDictionary _archivedDataViews; + Object _unavailable_custom_cibs; //Configuring Behavior - BOOL _allowsColumnReordering; - BOOL _allowsColumnResizing; - BOOL _allowsColumnSelection; - BOOL _allowsMultipleSelection; - BOOL _allowsEmptySelection; + BOOL _allowsColumnReordering; + BOOL _allowsColumnResizing; + BOOL _allowsColumnSelection; + BOOL _allowsMultipleSelection; + BOOL _allowsEmptySelection; - CPArray _sortDescriptors; + CPArray _sortDescriptors; //Setting Display Attributes - CGSize _intercellSpacing; - float _rowHeight; + CGSize _intercellSpacing; + float _rowHeight; - BOOL _usesAlternatingRowBackgroundColors; - CPArray _alternatingRowBackgroundColors; + BOOL _usesAlternatingRowBackgroundColors; + CPArray _alternatingRowBackgroundColors; - unsigned _selectionHighlightStyle; - CPColor _unfocusedSelectionHighlightColor; - CPDictionary _unfocusedSourceListSelectionColor; - CPTableColumn _currentHighlightedTableColumn; - unsigned _gridStyleMask; + unsigned _selectionHighlightStyle; + CPColor _unfocusedSelectionHighlightColor; + CPDictionary _unfocusedSourceListSelectionColor; + CPTableColumn _currentHighlightedTableColumn; + unsigned _gridStyleMask; - unsigned _numberOfRows; - CPIndexSet _groupRows; + unsigned _numberOfRows; + CPIndexSet _groupRows; - CPArray _cachedRowHeights; + CPArray _cachedRowHeights; // Persistence - CPString _autosaveName; - BOOL _autosaveTableColumns; + CPString _autosaveName; + BOOL _autosaveTableColumns; - CPTableHeaderView _headerView; - _CPCornerView _cornerView; + CPTableHeaderView _headerView; + _CPCornerView _cornerView; - CPIndexSet _selectedColumnIndexes; - CPIndexSet _selectedRowIndexes; - CPInteger _selectionAnchorRow; - CPInteger _lastSelectedRow; - CPIndexSet _previouslySelectedRowIndexes; - CGPoint _startTrackingPoint; - CPDate _startTrackingTimestamp; - BOOL _trackingPointMovedOutOfClickSlop; - CGPoint _editingCellIndex; - CPInteger _editingRow; - CPInteger _editingColumn; + CPIndexSet _selectedColumnIndexes; + CPIndexSet _selectedRowIndexes; + CPInteger _selectionAnchorRow; + CPInteger _lastSelectedRow; + CPIndexSet _previouslySelectedRowIndexes; + CGPoint _startTrackingPoint; + CPDate _startTrackingTimestamp; + BOOL _trackingPointMovedOutOfClickSlop; + CGPoint _editingCellIndex; + CPInteger _editingRow; + CPInteger _editingColumn; - _CPTableDrawView _tableDrawView; + _CPTableDrawView _tableDrawView; - SEL _doubleAction; - CPInteger _clickedRow; - CPInteger _clickedColumn; - unsigned _columnAutoResizingStyle; + SEL _doubleAction; + CPInteger _clickedRow; + CPInteger _clickedColumn; + unsigned _columnAutoResizingStyle; - int _lastTrackedRowIndex; - CGPoint _originalMouseDownPoint; - BOOL _verticalMotionCanDrag; - unsigned _destinationDragStyle; - BOOL _isSelectingSession; - CPIndexSet _draggedRowIndexes; - BOOL _wasSelectionBroken; + int _lastTrackedRowIndex; + CGPoint _originalMouseDownPoint; + BOOL _verticalMotionCanDrag; + unsigned _destinationDragStyle; + BOOL _isSelectingSession; + CPIndexSet _draggedRowIndexes; + BOOL _wasSelectionBroken; _CPDropOperationDrawingView _dropOperationFeedbackView; - CPDragOperation _dragOperationDefaultMask; - int _retargetedDropRow; - CPDragOperation _retargetedDropOperation; - CPArray _draggingViews; + CPDragOperation _dragOperationDefaultMask; + int _retargetedDropRow; + CPDragOperation _retargetedDropOperation; + CPArray _draggingViews; - BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing); - BOOL _lastColumnShouldSnap; - BOOL _implementsCustomDrawRow; - BOOL _isViewBased; - BOOL _contentBindingExplicitlySet; + BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing); + BOOL _lastColumnShouldSnap; + BOOL _implementsCustomDrawRow; + BOOL _isViewBased; + BOOL _contentBindingExplicitlySet; - SEL _viewForTableColumnRowSelector; + SEL _viewForTableColumnRowSelector; - CPTableColumn _draggedColumn; - CPArray _differedColumnDataToRemove; + CPTableColumn _draggedColumn; + CPArray _differedColumnDataToRemove; } /*! @@ -495,7 +538,7 @@ NOT YET IMPLEMENTED - (CPArray)tableView:(CPTableView)aTableView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedRowsWithIndexes:(CPIndexSet)indexSet; @endcode */ -- (void)setDataSource:(id)aDataSource +- (void)setDataSource:(id )aDataSource { if (_dataSource === aDataSource) return; @@ -2774,7 +2817,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad - (void)tableViewDeleteKeyPressed:(CPTableView)aTableView; @endcode */ -- (void)setDelegate:(id)aDelegate +- (void)setDelegate:(id )aDelegate { if (_delegate === aDelegate) return; diff --git a/AppKit/CPToolbar.j b/AppKit/CPToolbar.j index bdf7214da..1506df9e8 100644 --- a/AppKit/CPToolbar.j +++ b/AppKit/CPToolbar.j @@ -30,6 +30,13 @@ @global CPApp +var CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_ = 1 << 0, + CPToolbarDelegate_toolbarAllowedItemIdentifiers_ = 1 << 1, + CPToolbarDelegate_toolbarDefaultItemIdentifiers_ = 1 << 2, + CPToolbarDelegate_toolbarDidRemoveItem_ = 1 << 3, + CPToolbarDelegate_toolbarSelectableItemIdentifiers_ = 1 << 4, + CPToolbarDelegate_toolbarWillAddItem_ = 1 << 5; + /* @global @group CPToolbarDisplayMode @@ -59,6 +66,20 @@ CPToolbarSizeModeSmall = 2; var CPToolbarsByIdentifier = nil, CPToolbarConfigurationsByIdentifier = nil; + +@protocol CPToolbarDelegate + +@optional +- (CPToolbarItem)toolbar:(CPToolbar)toolbar itemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag; +- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)toolbar; +- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)toolbar; +- (void)toolbarDidRemoveItem:(CPNotification)notification; +- (CPArray)toolbarSelectableItemIdentifiers:(CPToolbar)toolbar; +- (void)toolbarWillAddItem:(CPNotification)notification; + +@end + + /*! @ingroup appkit @class CPToolbar @@ -89,14 +110,15 @@ var CPToolbarsByIdentifier = nil, @implementation CPToolbar : CPObject { CPString _identifier; - CPToolbarDisplayMode _displayMode @accessors(property=displayMode); + CPToolbarDisplayMode _displayMode @accessors(property=displayMode); BOOL _showsBaselineSeparator; BOOL _allowsUserCustomization; BOOL _isVisible; - CPToolbarSizeMode _sizeMode @accessors(property=sizeMode); + CPToolbarSizeMode _sizeMode @accessors(property=sizeMode); int _desiredHeight; - id _delegate; + id _delegate; + unsigned _implementedDelegateMethods; CPArray _itemIdentifiers; @@ -239,6 +261,25 @@ var CPToolbarsByIdentifier = nil, return; _delegate = aDelegate; + _implementedDelegateMethods = 0; + + if ([_delegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:)]) + _implementedDelegateMethods |= CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_; + + if ([_delegate respondsToSelector:@selector(toolbarAllowedItemIdentifiers:)]) + _implementedDelegateMethods |= CPToolbarDelegate_toolbarAllowedItemIdentifiers_; + + if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)]) + _implementedDelegateMethods |= CPToolbarDelegate_toolbarDefaultItemIdentifiers_; + + if ([_delegate respondsToSelector:@selector(toolbarDidRemoveItem:)]) + _implementedDelegateMethods |= CPToolbarDelegate_toolbarDidRemoveItem_; + + if ([_delegate respondsToSelector:@selector(toolbarSelectableItemIdentifiers:)]) + _implementedDelegateMethods |= CPToolbarDelegate_toolbarSelectableItemIdentifiers_; + + if ([_delegate respondsToSelector:@selector(toolbarWillAddItem:)]) + _implementedDelegateMethods |= CPToolbarDelegate_toolbarWillAddItem_; [self _reloadToolbarItems]; } @@ -289,9 +330,9 @@ var CPToolbarsByIdentifier = nil, // _defaultItems may have been loaded from Cib _itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || []; - if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)]) + if ([self _delegateRespondsToToolbarDefaultItemIdentifiers]) { - var itemIdentifiersFromDelegate = [_delegate toolbarDefaultItemIdentifiers:self]; + var itemIdentifiersFromDelegate = [self _sendDelegateToolbarDefaultItemIdentifiers]; // If we get items both from the Cib and from the delegate method, put the delegate items before the // Cib ones. @@ -316,7 +357,7 @@ var CPToolbarsByIdentifier = nil, item = [_identifiedItems objectForKey:identifier]; if (!item && _delegate) - item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES]; + item = [self _sendDelegateItemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES]; item = [item copy]; @@ -394,12 +435,14 @@ var CPToolbarsByIdentifier = nil, - (id)_itemForItemIdentifier:(CPString)identifier willBeInsertedIntoToolbar:(BOOL)toolbar { var item = [_identifiedItems objectForKey:identifier]; + if (!item) { item = [CPToolbarItem _standardItemWithItemIdentifier:identifier]; + if (_delegate && !item) { - item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy]; + item = [[self _sendDelegateItemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy]; if (!item) [CPException raise:CPInvalidArgumentException reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier " + identifier]; @@ -424,11 +467,11 @@ var CPToolbarsByIdentifier = nil, /* @ignore */ - (id)_defaultToolbarItems { - if (!_defaultItems && [_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)]) + if (!_defaultItems && [self _delegateRespondsToToolbarDefaultItemIdentifiers]) { _defaultItems = []; - var identifiers = [_delegate toolbarDefaultItemIdentifiers:self], + var identifiers = [self _sendDelegateToolbarDefaultItemIdentifiers], index = 0, count = [identifiers count]; @@ -1240,3 +1283,89 @@ var LABEL_MARGIN = 2.0; } @end + + +@implementation CPToolbar (CPToolbarDelegate) + +/* + @ignore + Return YES if the delegate implements toolbarDefaultItemIdentifiers: +*/ +- (BOOL)_delegateRespondsToToolbarDefaultItemIdentifiers +{ + return _implementedDelegateMethods & CPToolbarDelegate_toolbarDefaultItemIdentifiers_; +} + +/*! + @ignore + Call the delegate toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar: +*/ +- (CPToolbarItem)_sendDelegateItemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag +{ + if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_)) + return nil; + + return [_delegate toolbar:self itemForItemIdentifier:itemIdentifier willBeInsertedIntoToolbar:flag]; +} + +/*! + @ignore + Call the delegate toolbarAllowedItemIdentifiers: +*/ +- (CPArray)_sendDelegateToolbarAllowedItemIdentifiers +{ + if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbarAllowedItemIdentifiers_)) + return []; + + return [_delegate toolbarAllowedItemIdentifiers:self]; +} + +/*! + @ignore + Call the delegate toolbarDefaultItemIdentifiers: +*/ +- (CPArray)_sendDelegateToolbarDefaultItemIdentifiers +{ + if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbarDefaultItemIdentifiers_)) + return []; + + return [_delegate toolbarDefaultItemIdentifiers:self]; +} + +/*! + @ignore + Call the delegate toolbarDidRemoveItem: +*/ +- (void)_sendDelegateToolbarDidRemoveItem:(CPNotification)notification +{ + if (!(_delegate & CPToolbarDelegate_toolbarDidRemoveItem_)) + return; + + [_delegate toolbarDidRemoveItem:notification]; +} + +/*! + @ignore + Call the delegate toolbarSelectableItemIdentifiers: +*/ +- (CPArray)_sendDelegateToolbarSelectableItemIdentifiers +{ + if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbarSelectableItemIdentifiers_)) + return []; + + return [_delegate toolbarSelectableItemIdentifiers:self]; +} + +/*! + @ignore + Call the delegate toolbarWillAddItem: +*/ +- (void)_sendDelegateToolbarWillAddItem:(CPNotification)notification +{ + if (!(_delegate & CPToolbarDelegate_toolbarWillAddItem_)) + return; + + [_delegate toolbarWillAddItem:notification]; +} + +@end diff --git a/Foundation/CPDateFormatter.j b/Foundation/CPDateFormatter.j index a2131debc..3c237d0e9 100644 --- a/Foundation/CPDateFormatter.j +++ b/Foundation/CPDateFormatter.j @@ -79,8 +79,8 @@ var defaultDateFormatterBehavior = CPDateFormatterBehavior10_4, return; relativeDateFormating = @{ - @"fr" : [@"demain", 1440, @"apr" + String.fromCharCode(233) + @"s-demain", 2880, @"apr" + String.fromCharCode(233) + @"s-apr" + String.fromCharCode(233) + @"s-demain", 4320, @"hier", -1440, @"avant-hier", -2880, @"avant-avant-hier", -4320], - @"en" : [@"tomorrow", 1440, @"yesterday", -1440], + @"fr" : [@"demain", 1, @"apr" + String.fromCharCode(233) + @"s-demain", 2, @"apr" + String.fromCharCode(233) + @"s-apr" + String.fromCharCode(233) + @"s-demain", 3, @"hier", -1, @"avant-hier", -2, @"avant-avant-hier", -3], + @"en" : [@"tomorrow", 1, @"yesterday", -1], @"de" : [], @"es" : [] }; @@ -552,13 +552,13 @@ var defaultDateFormatterBehavior = CPDateFormatterBehavior10_4, var date = [CPDate date]; [date _dateWithTimeZone:_timeZone]; - date.setHours(aDate.getHours()); - date.setMinutes(aDate.getMinutes()); - date.setSeconds(aDate.getSeconds()); + date.setHours(12); + date.setMinutes(0); + date.setSeconds(0); - date.setMinutes([relativeWords objectAtIndex:i]); + date.setDate([relativeWords objectAtIndex:i] + date.getDate()); - if (date.getDate() == aDate.getDate() && date.getMonth() && aDate.getMonth() && date.getFullYear() == aDate.getFullYear()) + if (date.getDate() == aDate.getDate() && date.getMonth() == aDate.getMonth() && date.getFullYear() == aDate.getFullYear()) { relativeWord = [relativeWords objectAtIndex:(i - 1)]; format = @""; @@ -1224,7 +1224,7 @@ var defaultDateFormatterBehavior = CPDateFormatterBehavior10_4, // Interpret @"" as the date 2000-01-01 00:00:00 +0000, like in Cocoa. No idea why they picked this particular date. if (!aString) return [[CPDate alloc] initWithTimeIntervalSinceReferenceDate:-31622400]; - + if (aFormat == nil) return nil; @@ -2119,8 +2119,11 @@ var CPDateFormatterDateStyleKey = @"CPDateFormatterDateStyle", */ - (void)_dateWithTimeZone:(CPTimeZone)aTimeZone { + if (!aTimeZone) + return; + self.setSeconds(self.getSeconds() - [aTimeZone secondsFromGMTForDate:self]); self.setSeconds(self.getSeconds() + [aTimeZone secondsFromGMT]); } -@end \ No newline at end of file +@end diff --git a/Tests/AppKit/CPTableViewTest.j b/Tests/AppKit/CPTableViewTest.j index 74a0ecc4f..c1c5d0180 100644 --- a/Tests/AppKit/CPTableViewTest.j +++ b/Tests/AppKit/CPTableViewTest.j @@ -317,7 +317,7 @@ @end -@implementation TestDataSource : CPObject +@implementation TestDataSource : CPObject { CPArray tableEntries @accessors; }