From 179ef85f4edff4f7b7267843b7f06f7433878d50 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Tue, 4 May 2010 14:49:31 -0700 Subject: [PATCH 01/54] Final timer fix. Reviewed by me. --- Foundation/CPRunLoop.j | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/Foundation/CPRunLoop.j b/Foundation/CPRunLoop.j index ef1f10433..c5fde7b54 100644 --- a/Foundation/CPRunLoop.j +++ b/Foundation/CPRunLoop.j @@ -269,13 +269,16 @@ var CPRunLoopLastNativeRunLoop = 0; aTimer._lastNativeRunLoopsForModes[aMode] = CPRunLoopLastNativeRunLoop; -#if PLATFORM(DOM) - if (!_runLoopInsuranceTimer) - _runLoopInsuranceTimer = window.setNativeTimeout(function() - { - [self limitDateForMode:CPDefaultRunLoopMode]; - }, 0); -#endif + + // FIXME: Hack for not doing this in CommonJS + if (CFBundle.environments().indexOf("Browser") !== -1) + { + if (!_runLoopInsuranceTimer) + _runLoopInsuranceTimer = window.setNativeTimeout(function() + { + [self limitDateForMode:CPDefaultRunLoopMode]; + }, 0); + } } /*! @@ -289,13 +292,15 @@ var CPRunLoopLastNativeRunLoop = 0; _runLoopLock = YES; -#if PLATFORM(DOM) - if (_runLoopInsuranceTimer) + // FIXME: Hack for not doing this in CommonJS + if (CFBundle.environments().indexOf("Browser") !== -1) { - window.clearNativeTimeout(_runLoopInsuranceTimer); - _runLoopInsuranceTimer = nil; + if (_runLoopInsuranceTimer) + { + window.clearNativeTimeout(_runLoopInsuranceTimer); + _runLoopInsuranceTimer = nil; + } } -#endif var now = _effectiveDate ? [_effectiveDate laterDate:[CPDate date]] : [CPDate date], nextFireDate = nil, From 71104e49023e8287539f1f3a57581389d2efc25a Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Thu, 29 Apr 2010 14:44:11 +0200 Subject: [PATCH 02/54] fixed CPTableView moveColumn: --- AppKit/CPTableView.j | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 3768e2e60..2937445a6 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -691,15 +691,19 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; else _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex); - if (toIndex > fromIndex) - --toIndex; - var tableColumn = _tableColumns[fromIndex]; [_tableColumns removeObjectAtIndex:fromIndex]; [_tableColumns insertObject:tableColumn atIndex:toIndex]; + + [[self headerView] setNeedsLayout]; + [[self headerView] setNeedsDisplay:YES]; - [self setNeedsLayout]; + var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])], + columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)]; + + [self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes]; + // [self setNeedsLayout]; } /*! @@ -717,7 +721,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [[self headerView] setNeedsLayout]; [[self headerView] setNeedsDisplay:YES]; - [self reloadData]; + var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])]; + [self reloadDataForRowIndexes:rowIndexes columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]]; } - (CPArray)tableColumns From ef68408fff2e5acb22133c01ee2ac5dd31c3bedc Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Fri, 30 Apr 2010 00:14:59 +0200 Subject: [PATCH 03/54] refactored CPTableHeaderView mouse interaction --- AppKit/CPTableHeaderView.j | 458 +++++++++++++++++++++++++++++-------- 1 file changed, 365 insertions(+), 93 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 534b24da1..2d752f151 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -147,13 +147,24 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal @implementation CPTableHeaderView : CPView { - int _resizedColumn @accessors(readonly, property=resizedColumn); - int _draggedColumn @accessors(readonly, property=draggedColumn); - int _pressedColumn @accessors(readonly, property=pressedColumn); + CPPoint _previousTrackingLocation; + int _activeColumn; + int _pressedColumn; - float _draggedDistance @accessors(readonly, property=draggedDistance); - float _lastLocation; - float _columnOldWidth; + BOOL _isResizing; + BOOL _isTrackingColumn; + + // CPPoint _previousTrackingLocation; + // + // int _resizedColumn @accessors(readonly, property=resizedColumn); + // int _draggedColumn @accessors(readonly, property=draggedColumn); + // int _pressedColumn @accessors(readonly, property=pressedColumn); + // int _clickedColumn @accessors(readonly, property=clickedColumn); + // BOOL _isTrackingColumn; + // + // float _draggedDistance @accessors(readonly, property=draggedDistance); + // float _lastLocation; + // float _columnOldWidth; CPTableView _tableView @accessors(property=tableView); } @@ -162,7 +173,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { _resizedColumn = -1; _draggedColumn = -1; - _pressedColumn = -1; + _pressedColumn = CPNotFound; _draggedDistance = 0.0; _lastLocation = nil; _columnOldWidth = nil; @@ -182,7 +193,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (int)columnAtPoint:(CGPoint)aPoint { - return [_tableView columnAtPoint:CGPointMake(aPoint.x, 0)]; + return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)]; } - (CGRect)headerRectOfColumn:(int)aColumnIndex @@ -228,104 +239,365 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)mouseDown:(CPEvent)theEvent { - var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil], - clickedColumn = [self columnAtPoint:mouseLocation]; - - // should we send column -1 ? - [_tableView _sendDelegateDidMouseDownInHeader:clickedColumn]; - - var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), - resizedColumn = [self columnAtPoint:resizeLocation]; - - if (resizedColumn == -1) - return; - - // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering - if ([_tableView allowsColumnResizing] - && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation)) - { - _resizedColumn = resizedColumn; - [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; - [_tableView setDisableAutomaticResizing:YES]; - [self trackResizeWithEvent:theEvent]; - } - else - { - [self _setPressedColumn:clickedColumn]; - [self trackMouseWithEvent:theEvent]; - } + [self trackMouse:theEvent]; } -- (void)trackMouseWithEvent:(CPEvent)theEvent +- (void)trackMouse:(CPEvent)theEvent { - var type = [theEvent type]; + var type = [theEvent type], + currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - if (type == CPLeftMouseUp) - { - var location = [self convertPoint:[theEvent locationInWindow] fromView:nil], - clickedColumn = [self columnAtPoint:location]; + // Take the right columns resize tracking area into account + currentLocation.x -= 5.0; - [self _setPressedColumn:-1]; + var columnIndex = [self columnAtPoint:currentLocation], + shouldResize = [self shouldResizeTableColumn:columnIndex at:CPPointMake(currentLocation.x + 5.0, currentLocation.y)]; - if (clickedColumn != -1) - [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]]; - - return; - } - - [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; -} - -- (void)trackResizeWithEvent:(CPEvent)anEvent -{ - var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], - tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], - type = [anEvent type]; - - if (_lastLocation == nil) - _lastLocation = location; - - if (_columnOldWidth == nil) - _columnOldWidth = [tableColumn width]; - if (type === CPLeftMouseUp) - { - [self _updateResizeCursor:anEvent]; - - [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; - [tableColumn setDisableResizingPosting:NO]; - [_tableView setDisableAutomaticResizing:NO]; - - _resizedColumn = -1; - _lastLocation = nil; - _columnOldWidth = nil; - - return; - } - else if (type === CPLeftMouseDragged) { - var newWidth = [tableColumn width] + location.x - _lastLocation.x; - - if (newWidth < [tableColumn minWidth]) - [[CPCursor resizeRightCursor] set]; - else if (newWidth > [tableColumn maxWidth]) - [[CPCursor resizeLeftCursor] set]; + if (shouldResize) + [self stopResizingTableColumn:_activeColumn at:currentLocation]; + else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation]) + { + [[self tableView] _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]]; + [self stopTrackingTableColumn:columnIndex at:currentLocation]; + + _isTrackingColumn = NO; + } + + _activeColumn = CPNotFound; + return; + } + + if (type === CPLeftMouseDown) + { + _activeColumn = columnIndex; + + [[self tableView] _sendDelegateDidMouseDownInHeader:columnIndex]; + + if (shouldResize) + [self startResizingTableColumn:columnIndex at:currentLocation]; else { - _tableView._lastColumnShouldSnap = NO; - [tableColumn setWidth:newWidth]; - // FIXME: there has to be a better way to do this... - // We should refactor the auto resizing crap. - // We need to figure out the exact cocoa behavior here though. - _lastLocation = location; - - [[CPCursor resizeLeftRightCursor] set]; - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self startTrackingTableColumn:columnIndex at:currentLocation]; + _isTrackingColumn = YES; } } + else if (type === CPLeftMouseDragged) + { + if (shouldResize) + [self continueResizingTableColumn:_activeColumn at:currentLocation]; + else + { + if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation)) + { + if (_isTrackingColumn && _pressedColumn !== CPNotFound) + [self continueTrackingTableColumn:columnIndex at:currentLocation]; + else + [self startTrackingTableColumn:columnIndex at:currentLocation]; + } else if (_isTrackingColumn && _pressedColumn !== CPNotFound) + [self stopTrackingTableColumn:_activeColumn at:currentLocation]; + } + } + + _previousTrackingLocation = currentLocation; + [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +} - [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +/*! + @ignore + Determines if the header view should finish the column tracking + Returns YES if the receiver is in a tracking session, the active column is equal to the hovered column + and the header rect of the column contains the current mouse location +*/ +- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return _isTrackingColumn && _activeColumn === aColumnIndex && + CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint); +} + +- (void)startTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"startTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + [self _setPressedColumn:aColumnIndex]; +} + +- (void)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"continueTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); +} + +- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"stopTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + [self _setPressedColumn:CPNotFound]; +} + +/*! + @ignore + Determines if the table column should be resized + Returns YES if the receiver is already resizing a column or when the tableview allows + resizing and the point is in the resize rect of the column +*/ +- (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + if (_isResizing) + return YES; + + if (_isTrackingColumn) + return NO; + + return [[self tableView] allowsColumnResizing] && CPRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint); +} + +- (void)startResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + _isResizing = YES; + + CPLog.debug(@"startResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + + [tableColumn setDisableResizingPosting:YES]; + [[self tableView] setDisableAutomaticResizing:YES]; + + _resizedColumn = aColumnIndex; +} + +- (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"continueResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + + var newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; + + if (newWidth < [tableColumn minWidth]) + [[CPCursor resizeRightCursor] set]; + else if (newWidth > [tableColumn maxWidth]) + [[CPCursor resizeLeftCursor] set]; + else + { + [self tableView]._lastColumnShouldSnap = NO; + [tableColumn setWidth:newWidth]; + + [[CPCursor resizeLeftRightCursor] set]; + [self setNeedsLayout]; + [self setNeedsDisplay:YES]; + } +} + +- (void)stopResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"stopResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + // [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; + [tableColumn setDisableResizingPosting:NO]; + [[self tableView] setDisableAutomaticResizing:NO]; + + _isResizing = NO; +} + +// - (void)resizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp +// { +// var tableColumn = [[[self tableColumn] tableColumns] objectAtIndex:aColumnIndex]; +// +// if (isMouseUp) +// { +// [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; +// +// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; +// [tableColumn setDisableResizingPosting:NO]; +// [[self tableView] setDisableAutomaticResizing:NO]; +// } +// else +// { +// var newWidth = [tableColumn width] + location - _lastLocation.x; +// +// if (newWidth < [tableColumn minWidth]) +// [[CPCursor resizeRightCursor] set]; +// else if (newWidth > [tableColumn maxWidth]) +// [[CPCursor resizeLeftCursor] set]; +// else +// { +// [self tableView]._lastColumnShouldSnap = NO; +// [tableColumn setWidth:newWidth]; +// +// [[CPCursor resizeLeftRightCursor] set]; +// [self setNeedsLayout]; +// [self setNeedsDisplay:YES]; +// } +// } +// } + + +// - (BOOL)startTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint +// { +// [self _setPressedColumn:aColumnIndex]; +// +// return YES; + + // var resizeLocation = CPPointMake(aPoint.x - 5.0, aPoint.y); + // + // if ([self shouldResizeTableColumn:aColumnIndex at:aPoint]) + // { + // _resizedColumn = aColumnIndex; + // [[[[self tableView] tableColumns] objectAtIndex:_resizedColumn] setDisableResizingPosting:YES]; + // [[self tableView] setDisableAutomaticResizing:YES]; + // + // // // Use point :) + // // [self trackResizeWithEvent:[CPApp currentEvent]]; + // // return NO; + // } + // + // + // return YES; + + // _clickedColumn = [self columnAtPoint:mouseLocation]; + // + // // should we send column -1 ? + // [_tableView _sendDelegateDidMouseDownInHeader:_clickedColumn]; + // + // var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), + // resizedColumn = [self columnAtPoint:resizeLocation]; + // + // if (resizedColumn == -1) + // return; + // + // // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering + // if ([_tableView allowsColumnResizing] + // && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation)) + // { + // _resizedColumn = resizedColumn; + // [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; + // [_tableView setDisableAutomaticResizing:YES]; + // [self trackResizeWithEvent:theEvent]; + // } + // else + // { + // [self _setPressedColumn:_clickedColumn]; + // [self trackMouseWithEvent:theEvent]; + // } +} +// +// - (BOOL)continueTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint +// { +// } +// +// - (void)stopTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint; +// { +// [self _setPressedColumn:-1]; +// } + + + +// - (void)trackMouseWithEvent:(CPEvent)theEvent +// { +// var type = [theEvent type], +// location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; +// +// if (type === CPLeftMouseUp) +// { +// var clickedColumn = [self columnAtPoint:location], +// pressedColumn = _pressedColumn; +// +// [self _setPressedColumn:-1]; +// +// if (pressedColumn === clickedColumn) +// if (clickedColumn !== -1) +// [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]]; +// +// return; +// } +// else if (type === CPLeftMouseDragged) +// { +// var hoveredColumn = [self columnAtPoint:location]; +// +// CPLog.debug(@"hovered: %i pressed: %i", hoveredColumn, _pressedColumn); +// if (hoveredColumn === _clickedColumn) +// [self _setPressedColumn:_clickedColumn]; +// else +// [self _setPressedColumn:-1] +// } +// // CPLog.debug(@"..."); +// // +// // var point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; +// // +// // var view = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds], CPRectGetHeight([[self tableView] bounds])))]; +// // [view setBackgroundColor:[CPColor greenColor]]; +// // var viewLocation = CPPointMake(point.x - CGRectGetWidth(bounds)/2, point.y - CGRectGetHeight(bounds)/2); +// // +// // [self dragView:view at:viewLocation offset:CPPointMakeZero() event:theEvent pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; +// // return; +// // } +// +// [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; +// } + +// - (void)trackResizeWithEvent:(CPEvent)anEvent +// { +// var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], +// tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], +// type = [anEvent type]; +// +// if (_lastLocation == nil) +// _lastLocation = location; +// +// if (_columnOldWidth == nil) +// _columnOldWidth = [tableColumn width]; +// +// if (type === CPLeftMouseUp) +// { +// [self _updateResizeCursor:anEvent]; +// +// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; +// [tableColumn setDisableResizingPosting:NO]; +// [_tableView setDisableAutomaticResizing:NO]; +// +// _resizedColumn = -1; +// _lastLocation = nil; +// _columnOldWidth = nil; +// +// return; +// } +// else if (type === CPLeftMouseDragged) +// { +// var newWidth = [tableColumn width] + location.x - _lastLocation.x; +// +// if (newWidth < [tableColumn minWidth]) +// [[CPCursor resizeRightCursor] set]; +// else if (newWidth > [tableColumn maxWidth]) +// [[CPCursor resizeLeftCursor] set]; +// else +// { +// _tableView._lastColumnShouldSnap = NO; +// [tableColumn setWidth:newWidth]; +// // FIXME: there has to be a better way to do this... +// // We should refactor the auto resizing crap. +// // We need to figure out the exact cocoa behavior here though. +// _lastLocation = location; +// +// [[CPCursor resizeLeftRightCursor] set]; +// [self setNeedsLayout]; +// [self setNeedsDisplay:YES]; +// } +// } +// +// [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +// } + +- (void)_updateResizeCursorForTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp +{ + if (![[self tableView] allowsColumnResizing] || (isMouseUp && ![[self window] acceptsMouseMovedEvents])) + { + [[CPCursor arrowCursor] set]; + return; + } + + } - (void)_updateResizeCursor:(CPEvent)theEvent From 85283cff38168c7470ca7b225e645e579e7b871d Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Mon, 3 May 2010 11:10:45 +0200 Subject: [PATCH 04/54] - refactored mouse interaction - implemented basic column reordering --- AppKit/CPTableHeaderView.j | 255 +++++++++---------------------------- 1 file changed, 63 insertions(+), 192 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 2d752f151..d978f73e9 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -147,6 +147,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal @implementation CPTableHeaderView : CPView { + CPPoint _mouseDownLocation; CPPoint _previousTrackingLocation; int _activeColumn; int _pressedColumn; @@ -271,6 +272,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (type === CPLeftMouseDown) { + _mouseDownLocation = currentLocation; _activeColumn = columnIndex; [[self tableView] _sendDelegateDidMouseDownInHeader:columnIndex]; @@ -284,7 +286,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal } } else if (type === CPLeftMouseDragged) - { + { if (shouldResize) [self continueResizingTableColumn:_activeColumn at:currentLocation]; else @@ -292,9 +294,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation)) { if (_isTrackingColumn && _pressedColumn !== CPNotFound) - [self continueTrackingTableColumn:columnIndex at:currentLocation]; - else + { + if (![self continueTrackingTableColumn:columnIndex at:currentLocation]) + return; // Stop tracking the column, because it's being dragged + } else [self startTrackingTableColumn:columnIndex at:currentLocation]; + } else if (_isTrackingColumn && _pressedColumn !== CPNotFound) [self stopTrackingTableColumn:_activeColumn at:currentLocation]; } @@ -322,9 +327,63 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [self _setPressedColumn:aColumnIndex]; } -- (void)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; +} + +- (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { CPLog.debug(@"continueTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + if ([self _shouldDragTableColumn:aColumnIndex at:aPoint]) + { + CPLog.debug(@"start drag"); + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], + columnRect = [self headerRectOfColumn:aColumnIndex], + // offset = CPSizeMake(_mouseDownLocation.x - aPoint.x, _mouseDownLocation.y); + + var frame = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([[self tableView] bounds])), + view = [[CPView alloc] initWithFrame:frame]; + + [view setBackgroundColor:[CPColor greenColor]]; + + [self dragView:view at:aPoint offset:CPSizeMake(0.0, 0.0) event:[CPApp currentEvent] + pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; + + return NO; + } + + return YES; +} + +- (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint +{ + var hoveredColumn = [self columnAtPoint:aPoint], + if (_activeColumn === hoveredColumn) + return; + + var columnRect = [self headerRectOfColumn:hoveredColumn], + columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); + + if (_activeColumn < hoveredColumn && aPoint.x > columnCenterPoint.x) + { + [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; + _activeColumn = hoveredColumn; + } + else if (_activeColumn > hoveredColumn && aPoint.x < columnCenterPoint.x) + { + [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; + _activeColumn = hoveredColumn; + } +} + +- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation +{ + CPLog.debug(@"draggedView view ended at: %@", CPStringFromPoint(aLocation)); + + [self stopTrackingTableColumn:[self columnAtPoint:aLocation] at:aLocation]; } - (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint @@ -401,194 +460,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _isResizing = NO; } -// - (void)resizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp -// { -// var tableColumn = [[[self tableColumn] tableColumns] objectAtIndex:aColumnIndex]; -// -// if (isMouseUp) -// { -// [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; -// -// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; -// [tableColumn setDisableResizingPosting:NO]; -// [[self tableView] setDisableAutomaticResizing:NO]; -// } -// else -// { -// var newWidth = [tableColumn width] + location - _lastLocation.x; -// -// if (newWidth < [tableColumn minWidth]) -// [[CPCursor resizeRightCursor] set]; -// else if (newWidth > [tableColumn maxWidth]) -// [[CPCursor resizeLeftCursor] set]; -// else -// { -// [self tableView]._lastColumnShouldSnap = NO; -// [tableColumn setWidth:newWidth]; -// -// [[CPCursor resizeLeftRightCursor] set]; -// [self setNeedsLayout]; -// [self setNeedsDisplay:YES]; -// } -// } -// } - - -// - (BOOL)startTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint -// { -// [self _setPressedColumn:aColumnIndex]; -// -// return YES; - - // var resizeLocation = CPPointMake(aPoint.x - 5.0, aPoint.y); - // - // if ([self shouldResizeTableColumn:aColumnIndex at:aPoint]) - // { - // _resizedColumn = aColumnIndex; - // [[[[self tableView] tableColumns] objectAtIndex:_resizedColumn] setDisableResizingPosting:YES]; - // [[self tableView] setDisableAutomaticResizing:YES]; - // - // // // Use point :) - // // [self trackResizeWithEvent:[CPApp currentEvent]]; - // // return NO; - // } - // - // - // return YES; - - // _clickedColumn = [self columnAtPoint:mouseLocation]; - // - // // should we send column -1 ? - // [_tableView _sendDelegateDidMouseDownInHeader:_clickedColumn]; - // - // var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), - // resizedColumn = [self columnAtPoint:resizeLocation]; - // - // if (resizedColumn == -1) - // return; - // - // // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering - // if ([_tableView allowsColumnResizing] - // && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation)) - // { - // _resizedColumn = resizedColumn; - // [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; - // [_tableView setDisableAutomaticResizing:YES]; - // [self trackResizeWithEvent:theEvent]; - // } - // else - // { - // [self _setPressedColumn:_clickedColumn]; - // [self trackMouseWithEvent:theEvent]; - // } -} -// -// - (BOOL)continueTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint -// { -// } -// -// - (void)stopTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint; -// { -// [self _setPressedColumn:-1]; -// } - - - -// - (void)trackMouseWithEvent:(CPEvent)theEvent -// { -// var type = [theEvent type], -// location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; -// -// if (type === CPLeftMouseUp) -// { -// var clickedColumn = [self columnAtPoint:location], -// pressedColumn = _pressedColumn; -// -// [self _setPressedColumn:-1]; -// -// if (pressedColumn === clickedColumn) -// if (clickedColumn !== -1) -// [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]]; -// -// return; -// } -// else if (type === CPLeftMouseDragged) -// { -// var hoveredColumn = [self columnAtPoint:location]; -// -// CPLog.debug(@"hovered: %i pressed: %i", hoveredColumn, _pressedColumn); -// if (hoveredColumn === _clickedColumn) -// [self _setPressedColumn:_clickedColumn]; -// else -// [self _setPressedColumn:-1] -// } -// // CPLog.debug(@"..."); -// // -// // var point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; -// // -// // var view = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds], CPRectGetHeight([[self tableView] bounds])))]; -// // [view setBackgroundColor:[CPColor greenColor]]; -// // var viewLocation = CPPointMake(point.x - CGRectGetWidth(bounds)/2, point.y - CGRectGetHeight(bounds)/2); -// // -// // [self dragView:view at:viewLocation offset:CPPointMakeZero() event:theEvent pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; -// // return; -// // } -// -// [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; -// } - -// - (void)trackResizeWithEvent:(CPEvent)anEvent -// { -// var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], -// tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], -// type = [anEvent type]; -// -// if (_lastLocation == nil) -// _lastLocation = location; -// -// if (_columnOldWidth == nil) -// _columnOldWidth = [tableColumn width]; -// -// if (type === CPLeftMouseUp) -// { -// [self _updateResizeCursor:anEvent]; -// -// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; -// [tableColumn setDisableResizingPosting:NO]; -// [_tableView setDisableAutomaticResizing:NO]; -// -// _resizedColumn = -1; -// _lastLocation = nil; -// _columnOldWidth = nil; -// -// return; -// } -// else if (type === CPLeftMouseDragged) -// { -// var newWidth = [tableColumn width] + location.x - _lastLocation.x; -// -// if (newWidth < [tableColumn minWidth]) -// [[CPCursor resizeRightCursor] set]; -// else if (newWidth > [tableColumn maxWidth]) -// [[CPCursor resizeLeftCursor] set]; -// else -// { -// _tableView._lastColumnShouldSnap = NO; -// [tableColumn setWidth:newWidth]; -// // FIXME: there has to be a better way to do this... -// // We should refactor the auto resizing crap. -// // We need to figure out the exact cocoa behavior here though. -// _lastLocation = location; -// -// [[CPCursor resizeLeftRightCursor] set]; -// [self setNeedsLayout]; -// [self setNeedsDisplay:YES]; -// } -// } -// -// [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; -// } - - (void)_updateResizeCursorForTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp { if (![[self tableView] allowsColumnResizing] || (isMouseUp && ![[self window] acceptsMouseMovedEvents])) From 6bb8514253c29970d54c20e20d051239ab6be73d Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Mon, 3 May 2010 14:42:52 +0200 Subject: [PATCH 05/54] - gave the drag column a proper 'image' representation - constrained the drags y coordinates - made sure a drag is never out of bounds --- AppKit/CPTableHeaderView.j | 42 ++++++++++++++++++++++++------ AppKit/CPTableView.j | 53 +++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index d978f73e9..444103e29 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -341,15 +341,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal CPLog.debug(@"start drag"); var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], - columnRect = [self headerRectOfColumn:aColumnIndex], - // offset = CPSizeMake(_mouseDownLocation.x - aPoint.x, _mouseDownLocation.y); + columnRect = [self headerRectOfColumn:aColumnIndex]; - var frame = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([[self tableView] bounds])), - view = [[CPView alloc] initWithFrame:frame]; - - [view setBackgroundColor:[CPColor greenColor]]; + var offset = CPPointMakeZero(), + view = [[self tableView] dragViewForTableColumns:[tableColumn] event:[CPApp currentEvent] offset:offset], + viewLocation = CPPointMakeZero(); - [self dragView:view at:aPoint offset:CPSizeMake(0.0, 0.0) event:[CPApp currentEvent] + viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); + viewLocation.y = CPRectGetMinY(columnRect) + offset.y; + + [view setAlphaValue:0.7]; + + [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent] pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; return NO; @@ -358,10 +361,33 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return YES; } +- (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint +{ + var tableColumns = [[self tableView] tableColumns], + lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + dragWindow = [theDragView window], + frame = [dragWindow frame]; + + // Because the drag window is as wide as the entire tableview, it's start origin is always 0.0 + // The minimal x coordinate is the minimal dragged table columns negated x value + var minimumX = -(CPRectGetMinX([self headerRectOfColumn:_activeColumn])) + maximumX = CPRectGetMinX(lastColumnRect); + + // This effectively clamps the value between the minimal and maximum + // frame.origin.x = MAX(minimumX, MIN(CPRectGetMinX(frame), maximumX)); + + // Make sure the column cannot move vertically + frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); + + [dragWindow setFrame:frame]; +} + - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint { + [self _constrainDragView:aView at:aPoint]; + var hoveredColumn = [self columnAtPoint:aPoint], - if (_activeColumn === hoveredColumn) + if (hoveredColumn === -1 || _activeColumn === hoveredColumn) return; var columnRect = [self headerRectOfColumn:hoveredColumn], diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 2937445a6..674a650dc 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1810,7 +1810,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)]; } -- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPoint)dragViewOffset +- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)dragViewOffset { var bounds = [self bounds], view = [[CPView alloc] initWithFrame:bounds]; @@ -1846,6 +1846,57 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return view; } +- (CPView)dragViewForTableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset +{ + var bounds = CPRectMake(0.0, 0.0, 0.0, CPRectGetHeight([self bounds]) + 23.0); + index = [theTableColumns count], + dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; + + // Fetch all the data views for the columns and visible rows + // After that copy these add them to a transparent drag view and use that drag view + // to make it appear we are dragging images of those rows (as you would do in regular Cocoa) + while (index--) + { + // Get the tablecolumn and create a rect with it's width so we can use CPRectUnion + // to determine the end result + var tableColumn = [theTableColumns objectAtIndex:index], + columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:tableColumn]; + columnRect = [self rectOfColumn:columnIndex], + headerView = [tableColumn headerView]; + + // Add the column header view + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:[headerView frame]]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; + + bounds = CPRectUnion(bounds, columnRect); + + row = [_exposedRows firstIndex]; + while (row !== CPNotFound) + { + var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], + dataViewFrame = [self frameOfDataViewAtColumn:columnIndex row:row]; + + // Offset by table header height to make room for the table header + dataViewFrame.origin.y += 23.0; + [dataView setFrame:dataViewFrame]; + + [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; + [dragView addSubview:dataView]; + + row = [_exposedRows indexGreaterThanIndex:row]; + } + } + + // The columns are placed in the drag window at their original locations resulting in the dragged column + // being of when started the drag, we compensate for this by offseting the drag window by the x coordinate of the column + theDragViewOffset.x -= columnRect.origin.x; + [dragView setFrame:bounds]; + + return dragView; +} + - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal { //ignoral local for the time being since only one capp app can run at a time... From 040e7bc9eeb0ca1e591de8cddcaf74d0e0f74351 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 12:06:06 +0200 Subject: [PATCH 06/54] - made the _dragViewForTableColumn:event:offset: method private - removed the multiple column support from _dragViewForTableColumn:event:offset: (Cocoa doesn't allow multiple column selection / dragging) - made the dragview the size of the dragged column --- AppKit/CPTableHeaderView.j | 12 ++---- AppKit/CPTableView.j | 77 +++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 444103e29..1b721d613 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -338,20 +338,14 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if ([self _shouldDragTableColumn:aColumnIndex at:aPoint]) { - CPLog.debug(@"start drag"); - - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], - columnRect = [self headerRectOfColumn:aColumnIndex]; - - var offset = CPPointMakeZero(), - view = [[self tableView] dragViewForTableColumns:[tableColumn] event:[CPApp currentEvent] offset:offset], + var columnRect = [self headerRectOfColumn:aColumnIndex], + offset = CPPointMakeZero(), + view = [[self tableView] _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset], viewLocation = CPPointMakeZero(); viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); viewLocation.y = CPRectGetMinY(columnRect) + offset.y; - [view setAlphaValue:0.7]; - [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent] pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 674a650dc..c9c5bc688 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1846,52 +1846,51 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return view; } -- (CPView)dragViewForTableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset -{ - var bounds = CPRectMake(0.0, 0.0, 0.0, CPRectGetHeight([self bounds]) + 23.0); - index = [theTableColumns count], - dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; - - // Fetch all the data views for the columns and visible rows - // After that copy these add them to a transparent drag view and use that drag view +/*! + @ignore + // Fetches all the data views (from the datasource) for the column and it's visible rows + // Copy the dataviews add them to a transparent drag view and use that drag view // to make it appear we are dragging images of those rows (as you would do in regular Cocoa) - while (index--) +*/ +- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset +{ + var dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; + tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex], + bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self bounds]) + 23.0), + columnRect = [self rectOfColumn:theColumnIndex], + headerView = [tableColumn headerView]; + + // Add the column header view + var headerFrame = [headerView frame]; + headerFrame.origin = CPPointMakeZero(); + + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; + + row = [_exposedRows firstIndex]; + while (row !== CPNotFound) { - // Get the tablecolumn and create a rect with it's width so we can use CPRectUnion - // to determine the end result - var tableColumn = [theTableColumns objectAtIndex:index], - columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:tableColumn]; - columnRect = [self rectOfColumn:columnIndex], - headerView = [tableColumn headerView]; + var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], + dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row]; + + // Offset by table header height to make room for the table header + dataViewFrame.origin.x = 0.0; + dataViewFrame.origin.y += 23.0; + [dataView setFrame:dataViewFrame]; - // Add the column header view - columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:[headerView frame]]; - [columnHeaderView setStringValue:[headerView stringValue]]; - [columnHeaderView setThemeState:[headerView themeState]]; - [dragView addSubview:columnHeaderView]; - - bounds = CPRectUnion(bounds, columnRect); + [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; + [dragView addSubview:dataView]; - row = [_exposedRows firstIndex]; - while (row !== CPNotFound) - { - var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], - dataViewFrame = [self frameOfDataViewAtColumn:columnIndex row:row]; - - // Offset by table header height to make room for the table header - dataViewFrame.origin.y += 23.0; - [dataView setFrame:dataViewFrame]; - - [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; - [dragView addSubview:dataView]; - - row = [_exposedRows indexGreaterThanIndex:row]; - } + row = [_exposedRows indexGreaterThanIndex:row]; } // The columns are placed in the drag window at their original locations resulting in the dragged column - // being of when started the drag, we compensate for this by offseting the drag window by the x coordinate of the column - theDragViewOffset.x -= columnRect.origin.x; + // being of when starting the drag, we compensate for this by offseting the drag window by the x coordinate of the column + // theDragViewOffset.x -= columnRect.origin.x; + + [dragView setAlphaValue:0.7]; [dragView setFrame:bounds]; return dragView; From 93afa11ef9fa2a638f8110bdf7e28e6738f387ea Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 13:52:57 +0200 Subject: [PATCH 07/54] - switch columns when the dragged column is more than halfway over the previous/next column - constrain the horizontal coordinates within the header view --- AppKit/CPTableHeaderView.j | 104 +++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 1b721d613..3306e6b72 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -309,33 +309,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; } -/*! - @ignore - Determines if the header view should finish the column tracking - Returns YES if the receiver is in a tracking session, the active column is equal to the hovered column - and the header rect of the column contains the current mouse location -*/ -- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - return _isTrackingColumn && _activeColumn === aColumnIndex && - CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint); -} - - (void)startTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - CPLog.debug(@"startTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); [self _setPressedColumn:aColumnIndex]; } -- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; -} - - (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - CPLog.debug(@"continueTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - +{ if ([self _shouldDragTableColumn:aColumnIndex at:aPoint]) { var columnRect = [self headerRectOfColumn:aColumnIndex], @@ -355,20 +335,32 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return YES; } +- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return _isTrackingColumn && _activeColumn === aColumnIndex && + CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint); +} + +- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + [self _setPressedColumn:CPNotFound]; +} + +- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; +} + - (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint { var tableColumns = [[self tableView] tableColumns], lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + activeColumnRect = [self headerRectOfColumn:_activeColumn]; dragWindow = [theDragView window], frame = [dragWindow frame]; - // Because the drag window is as wide as the entire tableview, it's start origin is always 0.0 - // The minimal x coordinate is the minimal dragged table columns negated x value - var minimumX = -(CPRectGetMinX([self headerRectOfColumn:_activeColumn])) - maximumX = CPRectGetMinX(lastColumnRect); - - // This effectively clamps the value between the minimal and maximum - // frame.origin.x = MAX(minimumX, MIN(CPRectGetMinX(frame), maximumX)); + // This effectively clamps the value between the minimum and maximum + frame.origin.x = MAX(0.0, MIN(CPRectGetMinX(frame), CPRectGetMaxX(lastColumnRect) - CPRectGetWidth(activeColumnRect))); // Make sure the column cannot move vertically frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); @@ -376,48 +368,46 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [dragWindow setFrame:frame]; } +- (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex +{ + [[self tableView] moveColumn:aFromIndex toColumn:aToIndex]; + _activeColumn = aToIndex; + _pressedColumn = _activeColumn; +} + - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint { [self _constrainDragView:aView at:aPoint]; - var hoveredColumn = [self columnAtPoint:aPoint], - if (hoveredColumn === -1 || _activeColumn === hoveredColumn) - return; - - var columnRect = [self headerRectOfColumn:hoveredColumn], - columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); + var dragWindowFrame = [[aView window] frame]; - if (_activeColumn < hoveredColumn && aPoint.x > columnCenterPoint.x) + var hoverPoint = CPPointCreateCopy(aPoint); + if (aPoint.x < _previousTrackingLocation.x) + hoverPoint = CPPointMake(CPRectGetMinX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); + else if (aPoint.x > _previousTrackingLocation.x) + hoverPoint = CPPointMake(CPRectGetMaxX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); + + var hoveredColumn = [self columnAtPoint:hoverPoint], + + if (hoveredColumn !== -1) { - [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; - _activeColumn = hoveredColumn; - } - else if (_activeColumn > hoveredColumn && aPoint.x < columnCenterPoint.x) - { - [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; - _activeColumn = hoveredColumn; + var columnRect = [self headerRectOfColumn:hoveredColumn], + columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); + + if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x) + [self _moveColumn:_activeColumn toColumn:hoveredColumn]; + else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x) + [self _moveColumn:_activeColumn toColumn:hoveredColumn]; } + + _previousTrackingLocation = aPoint; } - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation { - CPLog.debug(@"draggedView view ended at: %@", CPStringFromPoint(aLocation)); - - [self stopTrackingTableColumn:[self columnAtPoint:aLocation] at:aLocation]; + [self stopTrackingTableColumn:_activeColumn at:aLocation]; } -- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - CPLog.debug(@"stopTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - [self _setPressedColumn:CPNotFound]; -} - -/*! - @ignore - Determines if the table column should be resized - Returns YES if the receiver is already resizing a column or when the tableview allows - resizing and the point is in the resize rect of the column -*/ - (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { if (_isResizing) From 006f7e0c158273d691f13ceec4f32f0ecf9819af Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 15:31:21 +0200 Subject: [PATCH 08/54] - fixed a out of bounds error when clicking in the table header outside of any column - made the dragged table column appear gray - gave the tablecolumn drag view a white background --- AppKit/CPTableHeaderView.j | 52 +++++++++++++++++++++----------------- AppKit/CPTableView.j | 32 +++++++++++++++++++---- 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 3306e6b72..318e78357 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -26,7 +26,7 @@ @implementation _CPTableColumnHeaderView : CPView { - _CPImageAndTextView _textField; + _CPImageAndTextView _textField; } - (void)initWithFrame:(CGRect)frame @@ -153,6 +153,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal int _pressedColumn; BOOL _isResizing; + BOOL _isDragging; BOOL _isTrackingColumn; // CPPoint _previousTrackingLocation; @@ -272,6 +273,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (type === CPLeftMouseDown) { + if (columnIndex === -1) + return; + _mouseDownLocation = currentLocation; _activeColumn = columnIndex; @@ -373,6 +377,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [[self tableView] moveColumn:aFromIndex toColumn:aToIndex]; _activeColumn = aToIndex; _pressedColumn = _activeColumn; + + [[self tableView] _setDraggedColumn:_activeColumn]; +} + +- (void)draggedView:(CPView)aView beganAt:(CPPoint)aPoint +{ + _isDragging = YES; + + [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:YES]; + [[self tableView] _setDraggedColumn:_activeColumn]; + + [self setNeedsDisplay:YES]; } - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint @@ -405,7 +421,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation { + _isDragging = NO; + + [[self tableView] _setDraggedColumn:-1]; + [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; [self stopTrackingTableColumn:_activeColumn at:aLocation]; + + [self setNeedsDisplay:YES]; } - (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint @@ -594,27 +616,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal CGContextClosePath(context); CGContextStrokePath(context); - -/* - var maxY = CGRectGetMaxY([self bounds]); - // draw normal gradient for remaining space - if (supportsCanvasGradient) + + if (_isDragging) { - aRect.origin.x = columnMaxX - 0.5; - aRect.size.width -= columnMaxX; - CGContextBeginPath(context); - CGContextAddRect(context, CGRectMake(columnMaxX + 1, 0, CGRectGetMaxX([self bounds]) - columnMaxX, CGRectGetHeight([self bounds]))); - CGContextClosePath(context); - CGContextDrawLinearGradient(context, [_CPTableColumnHeaderView headerGradient], CGPointMake(0,0), CGPointMake(0, maxY - 1),0); - } - - // Draw bottom line - CGContextBeginPath(context); - CGContextMoveToPoint(context, 0, maxY - 0.5); - CGContextAddLineToPoint(context, CGRectGetMaxX([self bounds]), maxY - 0.5); - CGContextClosePath(context); - CGContextStrokePath(context); -*/ + CGContextSetFillColor(context, [CPColor grayColor]); + CGContextFillRect(context, [self headerRectOfColumn:_activeColumn]) + } } @end @@ -640,5 +647,4 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey"; [aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey]; } -@end - +@end \ No newline at end of file diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index c9c5bc688..8d79b93d0 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -212,6 +212,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; CPGradient _sourceListActiveGradient; CPColor _sourceListActiveTopLineColor; CPColor _sourceListActiveBottomLineColor; + + int _draggedColumnIndex; + /* CPGradient _sourceListInactiveGradient; CPColor _sourceListInactiveTopLineColor; @@ -309,7 +312,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (!_cornerView) _cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))]; - + + _draggedColumnIndex = -1; + // Gradients for the source list _sourceListActiveGradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0/255.0, 153.0/255.0, 209.0/255.0,1.0, 33.0/255.0, 94.0/255.0, 208.0/255.0,1.0], [0,1], 2); _sourceListActiveTopLineColor = [CPColor colorWithCalibratedRed:(61.0/255.0) green:(123.0/255.0) blue:(218.0/255.0) alpha:1.0]; @@ -672,6 +677,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self setNeedsLayout]; } +- (void)_setDraggedColumn:(int)aColumnIndex +{ + if (_draggedColumnIndex === aColumnIndex) + return; + + _draggedColumnIndex = aColumnIndex; + + [self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:aColumnIndex]]; +} /*! Moves the column and heading at a given index to a new given index. @@ -703,7 +717,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)]; [self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes]; - // [self setNeedsLayout]; } /*! @@ -1856,7 +1869,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; { var dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex], - bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self bounds]) + 23.0), + bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self _exposedRect]) + 23.0), columnRect = [self rectOfColumn:theColumnIndex], headerView = [tableColumn headerView]; @@ -1890,6 +1903,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; // being of when starting the drag, we compensate for this by offseting the drag window by the x coordinate of the column // theDragViewOffset.x -= columnRect.origin.x; + [dragView setBackgroundColor:[CPColor whiteColor]]; [dragView setAlphaValue:0.7]; [dragView setFrame:bounds]; @@ -2138,7 +2152,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; var column = columnArray[columnIndex], tableColumn = _tableColumns[column]; - if ([tableColumn isHidden]) + if ([tableColumn isHidden] || columnIndex === _draggedColumnIndex) continue; var tableColumnUID = [tableColumn UID]; @@ -2294,6 +2308,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self drawBackgroundInClipRect:exposedRect]; [self drawGridInClipRect:exposedRect]; [self highlightSelectionInClipRect:exposedRect]; + + if (_draggedColumnIndex === -1) + return; + + var context = [[CPGraphicsContext currentContext] graphicsPort], + columnRect = [self rectOfColumn:_draggedColumnIndex]; + + CGContextSetFillColor(context, [CPColor grayColor]); + CGContextFillRect(context, columnRect); } - (void)drawBackgroundInClipRect:(CGRect)aRect @@ -2301,7 +2324,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (!_usesAlternatingRowBackgroundColors) return; - var rowColors = [self alternatingRowBackgroundColors], colorCount = [rowColors count]; From bdb0fb1310d08e8c2ca7417934bc18fa41e05f43 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 15:54:13 +0200 Subject: [PATCH 09/54] some cleanup --- AppKit/CPTableHeaderView.j | 63 ++++++++++---------------------------- 1 file changed, 16 insertions(+), 47 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 318e78357..8335069d8 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -156,29 +156,23 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal BOOL _isDragging; BOOL _isTrackingColumn; - // CPPoint _previousTrackingLocation; - // - // int _resizedColumn @accessors(readonly, property=resizedColumn); - // int _draggedColumn @accessors(readonly, property=draggedColumn); - // int _pressedColumn @accessors(readonly, property=pressedColumn); - // int _clickedColumn @accessors(readonly, property=clickedColumn); - // BOOL _isTrackingColumn; - // - // float _draggedDistance @accessors(readonly, property=draggedDistance); - // float _lastLocation; - // float _columnOldWidth; + float _columnOldWidth; - CPTableView _tableView @accessors(property=tableView); + CPTableView _tableView @accessors(property=tableView); } - (void)_init { - _resizedColumn = -1; - _draggedColumn = -1; - _pressedColumn = CPNotFound; - _draggedDistance = 0.0; - _lastLocation = nil; - _columnOldWidth = nil; + _mouseDownLocation = CPPointMakeZero(); + _previousTrackingLocation = CPPointMakeZero(); + _activeColumn = -1; + _pressedColumn = -1; + + _isResizing = NO; + _isDragging = NO; + _isTrackingColumn = NO; + + _columnOldWidth = 0.0; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]]; } @@ -297,14 +291,14 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation)) { - if (_isTrackingColumn && _pressedColumn !== CPNotFound) + if (_isTrackingColumn && _pressedColumn !== -1) { if (![self continueTrackingTableColumn:columnIndex at:currentLocation]) return; // Stop tracking the column, because it's being dragged } else [self startTrackingTableColumn:columnIndex at:currentLocation]; - } else if (_isTrackingColumn && _pressedColumn !== CPNotFound) + } else if (_isTrackingColumn && _pressedColumn !== -1) [self stopTrackingTableColumn:_activeColumn at:currentLocation]; } } @@ -348,6 +342,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { [self _setPressedColumn:CPNotFound]; + [self _updateResizeCursor:[CPApp currentEvent]]; } - (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint @@ -422,6 +417,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation { _isDragging = NO; + _isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached [[self tableView] _setDraggedColumn:-1]; [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; @@ -445,20 +441,14 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { _isResizing = YES; - CPLog.debug(@"startResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; [tableColumn setDisableResizingPosting:YES]; [[self tableView] setDisableAutomaticResizing:YES]; - - _resizedColumn = aColumnIndex; } - (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - CPLog.debug(@"continueResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; var newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; @@ -480,10 +470,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)stopResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - CPLog.debug(@"stopResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - - // [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; [tableColumn setDisableResizingPosting:NO]; @@ -492,17 +478,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _isResizing = NO; } -- (void)_updateResizeCursorForTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp -{ - if (![[self tableView] allowsColumnResizing] || (isMouseUp && ![[self window] acceptsMouseMovedEvents])) - { - [[CPCursor arrowCursor] set]; - return; - } - - -} - - (void)_updateResizeCursor:(CPEvent)theEvent { // never get stuck in resize cursor mode (FIXME take out when we turn on tracking rects) @@ -532,12 +507,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [[CPCursor arrowCursor] set]; } -- (void)viewDidMoveToWindow -{ - //if ([_tableView allowsColumnResizing]) - // [[self window] setAcceptsMouseMovedEvents:YES]; -} - - (void)mouseEntered:(CPEvent)theEvent { [self _updateResizeCursor:theEvent]; From e7fc9d991259a8b8416c1460e02c89a38a95817e Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Wed, 5 May 2010 10:38:41 +0200 Subject: [PATCH 10/54] fixed a bug where column reordering would break when the last column was hidden --- AppKit/CPTableHeaderView.j | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 8335069d8..add1d0086 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -350,10 +350,26 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; } +- (CPRect)_headerRectOfLastVisibleColumn +{ + var tableColumns = [[self tableView] tableColumns], + columnIndex = [tableColumns count]; + + while (columnIndex--) + { + var tableColumn = [tableColumns objectAtIndex:columnIndex]; + + if (![tableColumn isHidden]) + return [self headerRectOfColumn:columnIndex]; + } + + return nil; +} + - (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint { var tableColumns = [[self tableView] tableColumns], - lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + lastColumnRect = [self _headerRectOfLastVisibleColumn]; activeColumnRect = [self headerRectOfColumn:_activeColumn]; dragWindow = [theDragView window], frame = [dragWindow frame]; From a0cf7d578704bee476abf1a1303b69a3f9cbe50f Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Wed, 5 May 2010 12:56:23 +0200 Subject: [PATCH 11/54] made table column reordering work in non full-bridged apps --- AppKit/CPTableHeaderView.j | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index add1d0086..4bbb4e006 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -374,12 +374,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal dragWindow = [theDragView window], frame = [dragWindow frame]; + // Convert the frame origin from the global coordinate system to the windows' coordinate system + frame.origin = [[self window] convertGlobalToBase:frame.origin]; + // This effectively clamps the value between the minimum and maximum frame.origin.x = MAX(0.0, MIN(CPRectGetMinX(frame), CPRectGetMaxX(lastColumnRect) - CPRectGetWidth(activeColumnRect))); // Make sure the column cannot move vertically frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); + // Convert the calculated origin back to the global coordinate system + frame.origin = [[self window] convertBaseToGlobal:frame.origin]; + [dragWindow setFrame:frame]; } @@ -406,7 +412,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { [self _constrainDragView:aView at:aPoint]; - var dragWindowFrame = [[aView window] frame]; + var dragWindow = [aView window], + dragWindowFrame = [dragWindow frame]; var hoverPoint = CPPointCreateCopy(aPoint); if (aPoint.x < _previousTrackingLocation.x) @@ -414,13 +421,16 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal else if (aPoint.x > _previousTrackingLocation.x) hoverPoint = CPPointMake(CPRectGetMaxX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); - var hoveredColumn = [self columnAtPoint:hoverPoint], + // Convert the hover point from the global coordinate system to windows' coordinate system + hoverPoint = [[self window] convertGlobalToBase:hoverPoint]; + + var hoveredColumn = [self columnAtPoint:hoverPoint]; if (hoveredColumn !== -1) { var columnRect = [self headerRectOfColumn:hoveredColumn], columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); - + if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x) [self _moveColumn:_activeColumn toColumn:hoveredColumn]; else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x) From 2fd85ab78f6ab924c3b45f7fc76fe5154ae947d8 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Wed, 5 May 2010 14:08:06 +0200 Subject: [PATCH 12/54] made column reordering work with scrolled content --- AppKit/CPTableView.j | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 8d79b93d0..291adc0a6 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1873,24 +1873,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; columnRect = [self rectOfColumn:theColumnIndex], headerView = [tableColumn headerView]; - // Add the column header view - var headerFrame = [headerView frame]; - headerFrame.origin = CPPointMakeZero(); - - columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame]; - [columnHeaderView setStringValue:[headerView stringValue]]; - [columnHeaderView setThemeState:[headerView themeState]]; - [dragView addSubview:columnHeaderView]; - row = [_exposedRows firstIndex]; while (row !== CPNotFound) { var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row]; - // Offset by table header height to make room for the table header + // Only one column is ever dragged so we just place the view at dataViewFrame.origin.x = 0.0; - dataViewFrame.origin.y += 23.0; + + // Offset by table header height - scroll position + dataViewFrame.origin.y = ( CPRectGetMinY(dataViewFrame) - CPRectGetMinY([self _exposedRect]) ) + 23.0; [dataView setFrame:dataViewFrame]; [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; @@ -1899,9 +1892,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; row = [_exposedRows indexGreaterThanIndex:row]; } - // The columns are placed in the drag window at their original locations resulting in the dragged column - // being of when starting the drag, we compensate for this by offseting the drag window by the x coordinate of the column - // theDragViewOffset.x -= columnRect.origin.x; + // Add the column header view + var headerFrame = [headerView frame]; + headerFrame.origin = CPPointMakeZero(); + + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; [dragView setBackgroundColor:[CPColor whiteColor]]; [dragView setAlphaValue:0.7]; From e5873caf04914adc991475e6908c391465fe00e7 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Fri, 7 May 2010 09:38:23 +0200 Subject: [PATCH 13/54] fixed a typo in objectValueForTableColumn:row: --- Tests/Manual/TableTest/AppController.j | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Tests/Manual/TableTest/AppController.j b/Tests/Manual/TableTest/AppController.j index ff2889de2..1e573389a 100644 --- a/Tests/Manual/TableTest/AppController.j +++ b/Tests/Manual/TableTest/AppController.j @@ -129,8 +129,7 @@ tableTestDragType = @"CPTableViewTestDragType"; - (void)sourceList { - - var window3 = [[CPWindow alloc] initWithContentRect:CGRectMake(450, 250, 200, 400) styleMask:CPTitledWindowMask | CPResizableWindowMask]; + var window3 = [[CPWindow alloc] initWithContentRect:CGRectMake(450, 250, 500, 400) styleMask:CPTitledWindowMask | CPResizableWindowMask]; tableView3 = [[CPTableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 500.0)]; @@ -150,6 +149,10 @@ tableTestDragType = @"CPTableViewTestDragType"; [column setMinWidth:50.0]; [column setEditable:YES]; [tableView3 addTableColumn:column]; + + var column = [[CPTableColumn alloc] initWithIdentifier:"sourcelist2"]; + [[column headerView] setStringValue:"Source List 2"]; + [tableView3 addTableColumn:column]; var scrollView3 = [[CPScrollView alloc] initWithFrame:[[window3 contentView] bounds]]; [tableView3 setRowHeight:32.0]; @@ -183,7 +186,7 @@ tableTestDragType = @"CPTableViewTestDragType"; else if (aTableView === tableView2) return String(dataSet2[aRow]); else if(aTableView === tableView3) - return String(dataSet3[row]); + return String(dataSet3[aRow]); } - (void)tableView:(CPTableView)aTableView sortDescriptorsDidChange:(CPArray)oldDescriptors From e68d70cf1d74901162df420711f4cf97787376fd Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Thu, 6 May 2010 12:41:01 -0700 Subject: [PATCH 14/54] Make mouse wheel events work in CPWebView in Firefox 3+ --- AppKit/CPWebView.j | 30 ++++++++++++++++++++-- AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 17 +++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/AppKit/CPWebView.j b/AppKit/CPWebView.j index d8c7dff81..9da31436e 100644 --- a/AppKit/CPWebView.j +++ b/AppKit/CPWebView.j @@ -171,7 +171,32 @@ CPWebViewScrollNative = 2; [self _resizeWebFrame]; } -- (BOOL)_resizeWebFrame +- (void)_attachScrollEventIfNecessary +{ + if (_scrollMode !== CPWebViewScrollAppKit) + return; + + var win = null; + try { win = [self DOMWindow]; } catch (e) {} + + if (win && win.addEventListener) + { + var scrollEventHandler = function(anEvent) + { + var frameBounds = [self bounds], + frameCenter = CGPointMake(CGRectGetMidX(frameBounds), CGRectGetMidY(frameBounds)), + windowOrigin = [self convertPoint:frameCenter toView:nil], + globalOrigin = [[self window] convertBaseToBridge:windowOrigin]; + + anEvent._overrideLocation = globalOrigin; + [[[self window] platformWindow] scrollEvent:anEvent]; + }; + + win.addEventListener("DOMMouseScroll", scrollEventHandler, false); + } +} + +- (void)_resizeWebFrame { if (_scrollMode === CPWebViewScrollAppKit) { @@ -320,7 +345,8 @@ CPWebViewScrollNative = 2; - (void)_finishedLoading { [self _resizeWebFrame]; - + [self _attachScrollEventIfNecessary]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self]; if ([_frameLoadDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 96c542885..a0b9403bb 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -851,12 +851,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; if(!aDOMEvent) aDOMEvent = window.event; + var location = nil; if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15)) { - var x = 0.0, - y = 0.0, + var x = aDOMEvent._offsetX || 0.0, + y = aDOMEvent._offsetY || 0.0, element = aDOMEvent.target; - + while (element.nodeType !== 1) element = element.parentNode; @@ -870,11 +871,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; } while (element = element.offsetParent); } - var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15))); + location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15))); } + else if (aDOMEvent._overrideLocation) + location = aDOMEvent._overrideLocation; else - var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY); - + location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY); + var deltaX = 0.0, deltaY = 0.0, windowNumber = 0, @@ -883,7 +886,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; (aDOMEvent.ctrlKey ? CPControlKeyMask : 0) | (aDOMEvent.altKey ? CPAlternateKeyMask : 0) | (aDOMEvent.metaKey ? CPCommandKeyMask : 0); - + StopDOMEventPropagation = YES; var theWindow = [self hitTest:location]; From 0d35b382822bcab1d787aec176893c85ad6596f2 Mon Sep 17 00:00:00 2001 From: cacaodev Date: Fri, 12 Mar 2010 13:51:33 +0100 Subject: [PATCH 15/54] CPOutlineView: Fix a bug where newly expanded items would have a white disclosure control. In CPTableView, add a method for data view selection. Use it in CPOutlineView for disclosure selection and do not subclass the entire -selectRows:... method. Darken disclosure control when pressed depending on the selected state. --- AppKit/CPOutlineView.j | 47 ++++++++++-------------------------------- AppKit/CPTableView.j | 22 ++++++++++---------- 2 files changed, 22 insertions(+), 47 deletions(-) diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 6711eba89..9b1738768 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -382,43 +382,14 @@ CPOutlineViewDropOnItemIndex = -1; return frame; } -- (void)selectRowIndexes:(CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection +- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context { - // First un highlight the old disclosure controls - var previousSelectedRows = []; - [[self selectedRowIndexes] getIndexes:previousSelectedRows maxCount:-1 inIndexRange:nil]; + [super _performSelection:select forRow:rowIndex context:context]; - var index = [previousSelectedRows count]; - while (index--) - { - var rowIndex = previousSelectedRows[index], - item = [self itemAtRow:rowIndex]; + var control = _disclosureControlsForRows[rowIndex], + selector = select ? @"setThemeState:" : @"unsetThemeState:"; - if (![self isExpandable:item]) - continue; - - var control = _disclosureControlsForRows[rowIndex]; - [control setHighlighted:NO]; - } - - [super selectRowIndexes:rows byExtendingSelection:shouldExtendSelection]; - - // Now highlight the new disclosure controls - var selectedRows = []; - [rows getIndexes:selectedRows maxCount:-1 inIndexRange:nil]; - - var index = [selectedRows count]; - while (index--) - { - var rowIndex = selectedRows[index], - item = [self itemAtRow:rowIndex]; - - if (![self isExpandable:item]) - continue; - - var control = _disclosureControlsForRows[rowIndex]; - [control setHighlighted:YES]; - } + [control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected]; } - (void)setDelegate:(id)aDelegate @@ -619,6 +590,8 @@ CPOutlineViewDropOnItemIndex = -1; _disclosureControlsForRows[row] = control; [control setState:[self isItemExpanded:item] ? CPOnState : CPOffState]; + var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:"; + [control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected]; [control setFrame:frame]; [self addSubview:control]; @@ -1080,8 +1053,10 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt CGContextAddLineToPoint(context, 0.0, 0.0); CGContextClosePath(context); - - CGContextSetFillColor(context, [self isHighlighted] ? [CPColor whiteColor] : [CPColor grayColor]); + var isHighlighted = [self hasThemeState:CPThemeStateHighlighted]; + var color = [self hasThemeState:CPThemeStateSelected] ? (isHighlighted ? [CPColor lightGrayColor] : [CPColor whiteColor]) : (isHighlighted ? [CPColor blackColor] : [CPColor grayColor]); + + CGContextSetFillColor(context, color); CGContextFillPath(context); } diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 1032d9cc8..3a589fdbb 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -817,22 +817,22 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; var count = deselectRows.length; while (count--) - { - var rowIndex = deselectRows[count]; - var view = dataViewsInTableColumn[rowIndex]; - [view unsetThemeState:CPThemeStateSelected]; - } - + [self _performSelection:NO forRow:deselectRows[count] context:dataViewsInTableColumn]; + count = selectRows.length; while (count--) - { - var rowIndex = selectRows[count]; - var view = dataViewsInTableColumn[rowIndex]; - [view setThemeState:CPThemeStateSelected]; - } + [self _performSelection:YES forRow:selectRows[count] context:dataViewsInTableColumn]; } } +- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context +{ + var view = context[rowIndex], + selector = select ? @"setThemeState:" : @"unsetThemeState:"; + + [view performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected]; +} + - (void)_updateHighlightWithOldColumns:(CPIndexSet)oldColumns newColumns:(CPIndexSet)newColumns { var firstExposedColumn = [_exposedColumns firstIndex], From e5275514ddb66029b089c15ad6abed6d4de34e91 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 11 May 2010 00:05:12 -0500 Subject: [PATCH 16/54] OutlineView items auto expand when hovering over them. --- AppKit/CPOutlineView.j | 34 ++++++++++++++++++++++++++++++++++ AppKit/CPTableView.j | 26 ++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j index 9b1738768..7c396f1f9 100644 --- a/AppKit/CPOutlineView.j +++ b/AppKit/CPOutlineView.j @@ -85,6 +85,8 @@ CPOutlineViewDropOnItemIndex = -1; BOOL _shouldRetargetChildIndex; CPInteger _retargedChildIndex; + CPTimer _dragHoverTimer; + id _dropItem; } - (id)initWithFrame:(CGRect)aFrame @@ -108,6 +110,7 @@ CPOutlineViewDropOnItemIndex = -1; _retargedChildIndex = nil; _shouldRetargetChildIndex = NO; + _startHoverTime = nil; [self setIndentationPerLevel:16.0]; [self setIndentationMarkerFollowsDataView:YES]; @@ -505,6 +508,29 @@ CPOutlineViewDropOnItemIndex = -1; - (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex { + if (_dropItem !== theItem && theIndex < 0 && [self isExpandable:theItem] && ![self isItemExpanded:theItem]) + { + if (_dragHoverTimer) + [_dragHoverTimer invalidate]; + + var autoExpandCallBack = function(){ + if (_dropItem) + { + [_dropOperationFeedbackView blink]; + [CPTimer scheduledTimerWithTimeInterval:.3 callback:objj_msgSend(self, "expandItem:", _dropItem) repeats:NO]; //[self expandItem:_dropItem]; + } + } + + _dragHoverTimer = [CPTimer scheduledTimerWithTimeInterval:.8 callback:autoExpandCallBack repeats:NO]; + } + + if (theIndex >= 0) + { + [_dragHoverTimer invalidate]; + _dragHoverTimer = nil; + } + + _dropItem = theItem; _retargetedItem = theItem; _shouldRetargetItem = YES; @@ -512,6 +538,14 @@ CPOutlineViewDropOnItemIndex = -1; _shouldRetargetChildIndex = YES; } +- (void)_draggingEnded +{ + [super _draggingEnded]; + _dropItem = nil; + [_dragHoverTimer invalidate]; + _dragHoverTimer = nil; +} + - (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset { if (_shouldRetargetItem) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 3a589fdbb..130d50b28 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -3299,11 +3299,12 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", unsigned dropOperation @accessors; CPTableView tableView @accessors; int currentRow @accessors; + BOOL isBlinking @accessors; } - (void)drawRect:(CGRect)aRect { - if(tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone) + if(tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone || isBlinking) return; var context = [[CPGraphicsContext currentContext] graphicsPort]; @@ -3369,7 +3370,28 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey", CGContextStrokePath(context); //CGContextStrokeLineSegments(context, [aRect.origin.x + 8, aRect.origin.y + 8, 300 , aRect.origin.y + 8]); } - +} +- (void)blink +{ + if (dropOperation !== CPTableViewDropOn) + return; + + isBlinking = YES; + + var showCallback = function() { + objj_msgSend(self, "setHidden:", NO) + isBlinking = NO; + } + + var hideCallback = function() { + objj_msgSend(self, "setHidden:", YES) + isBlinking = YES; + } + + objj_msgSend(self, "setHidden:", YES); + [CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO]; + [CPTimer scheduledTimerWithTimeInterval:0.19 callback:hideCallback repeats:NO]; + [CPTimer scheduledTimerWithTimeInterval:0.27 callback:showCallback repeats:NO]; } @end From 5b518797d7679d33bbf04bb3dc56e774d9128261 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 11 May 2010 00:18:05 -0500 Subject: [PATCH 17/54] fixed CPTableView moveColumn: Conflicts: AppKit/CPTableView.j --- AppKit/CPTableView.j | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 130d50b28..b3c6add2a 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -691,15 +691,38 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; else _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex); - if (toIndex > fromIndex) - --toIndex; - var tableColumn = _tableColumns[fromIndex]; [_tableColumns removeObjectAtIndex:fromIndex]; [_tableColumns insertObject:tableColumn atIndex:toIndex]; + + [[self headerView] setNeedsLayout]; + [[self headerView] setNeedsDisplay:YES]; - [self setNeedsLayout]; + var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])], + columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)]; + + [self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes]; + // [self setNeedsLayout]; +} + +/*! + @ignore +*/ +- (void)_tableColumnVisibilityDidChange:(CPTableColumn)aColumn +{ + var columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:aColumn]; + + if (_dirtyTableColumnRangeIndex < 0) + _dirtyTableColumnRangeIndex = columnIndex; + else + _dirtyTableColumnRangeIndex = MIN(columnIndex, _dirtyTableColumnRangeIndex); + + [[self headerView] setNeedsLayout]; + [[self headerView] setNeedsDisplay:YES]; + + var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])]; + [self reloadDataForRowIndexes:rowIndexes columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]]; } - (CPArray)tableColumns From 8b168e76af1a0a317aa4de0cc2ef5df4ef40a28b Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Fri, 30 Apr 2010 00:14:59 +0200 Subject: [PATCH 18/54] refactored CPTableHeaderView mouse interaction --- AppKit/CPTableHeaderView.j | 458 +++++++++++++++++++++++++++++-------- 1 file changed, 365 insertions(+), 93 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 8d8d3b9ec..8087a6724 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -147,13 +147,24 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal @implementation CPTableHeaderView : CPView { - int _resizedColumn @accessors(readonly, property=resizedColumn); - int _draggedColumn @accessors(readonly, property=draggedColumn); - int _pressedColumn @accessors(readonly, property=pressedColumn); + CPPoint _previousTrackingLocation; + int _activeColumn; + int _pressedColumn; - float _draggedDistance @accessors(readonly, property=draggedDistance); - float _lastLocation; - float _columnOldWidth; + BOOL _isResizing; + BOOL _isTrackingColumn; + + // CPPoint _previousTrackingLocation; + // + // int _resizedColumn @accessors(readonly, property=resizedColumn); + // int _draggedColumn @accessors(readonly, property=draggedColumn); + // int _pressedColumn @accessors(readonly, property=pressedColumn); + // int _clickedColumn @accessors(readonly, property=clickedColumn); + // BOOL _isTrackingColumn; + // + // float _draggedDistance @accessors(readonly, property=draggedDistance); + // float _lastLocation; + // float _columnOldWidth; CPTableView _tableView @accessors(property=tableView); } @@ -162,7 +173,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { _resizedColumn = -1; _draggedColumn = -1; - _pressedColumn = -1; + _pressedColumn = CPNotFound; _draggedDistance = 0.0; _lastLocation = nil; _columnOldWidth = nil; @@ -182,7 +193,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (int)columnAtPoint:(CGPoint)aPoint { - return [_tableView columnAtPoint:CGPointMake(aPoint.x, 0)]; + return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)]; } - (CGRect)headerRectOfColumn:(int)aColumnIndex @@ -236,104 +247,365 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)mouseDown:(CPEvent)theEvent { - var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil], - clickedColumn = [self columnAtPoint:mouseLocation]; - - // should we send column -1 ? - [_tableView _sendDelegateDidMouseDownInHeader:clickedColumn]; - - var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), - resizedColumn = [self columnAtPoint:resizeLocation]; - - if (resizedColumn == -1) - return; - - // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering - if ([_tableView allowsColumnResizing] - && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation)) - { - _resizedColumn = resizedColumn; - [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; - [_tableView setDisableAutomaticResizing:YES]; - [self trackResizeWithEvent:theEvent]; - } - else - { - [self _setPressedColumn:clickedColumn]; - [self trackMouseWithEvent:theEvent]; - } + [self trackMouse:theEvent]; } -- (void)trackMouseWithEvent:(CPEvent)theEvent +- (void)trackMouse:(CPEvent)theEvent { - var type = [theEvent type]; + var type = [theEvent type], + currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - if (type == CPLeftMouseUp) - { - var location = [self convertPoint:[theEvent locationInWindow] fromView:nil], - clickedColumn = [self columnAtPoint:location]; + // Take the right columns resize tracking area into account + currentLocation.x -= 5.0; - [self _setPressedColumn:-1]; + var columnIndex = [self columnAtPoint:currentLocation], + shouldResize = [self shouldResizeTableColumn:columnIndex at:CPPointMake(currentLocation.x + 5.0, currentLocation.y)]; - if (clickedColumn != -1) - [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]]; - - return; - } - - [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; -} - -- (void)trackResizeWithEvent:(CPEvent)anEvent -{ - var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], - tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], - type = [anEvent type]; - - if (_lastLocation == nil) - _lastLocation = location; - - if (_columnOldWidth == nil) - _columnOldWidth = [tableColumn width]; - if (type === CPLeftMouseUp) - { - [self _updateResizeCursor:anEvent]; - - [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; - [tableColumn setDisableResizingPosting:NO]; - [_tableView setDisableAutomaticResizing:NO]; - - _resizedColumn = -1; - _lastLocation = nil; - _columnOldWidth = nil; - - return; - } - else if (type === CPLeftMouseDragged) { - var newWidth = [tableColumn width] + location.x - _lastLocation.x; - - if (newWidth < [tableColumn minWidth]) - [[CPCursor resizeRightCursor] set]; - else if (newWidth > [tableColumn maxWidth]) - [[CPCursor resizeLeftCursor] set]; + if (shouldResize) + [self stopResizingTableColumn:_activeColumn at:currentLocation]; + else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation]) + { + [[self tableView] _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]]; + [self stopTrackingTableColumn:columnIndex at:currentLocation]; + + _isTrackingColumn = NO; + } + + _activeColumn = CPNotFound; + return; + } + + if (type === CPLeftMouseDown) + { + _activeColumn = columnIndex; + + [[self tableView] _sendDelegateDidMouseDownInHeader:columnIndex]; + + if (shouldResize) + [self startResizingTableColumn:columnIndex at:currentLocation]; else { - _tableView._lastColumnShouldSnap = NO; - [tableColumn setWidth:newWidth]; - // FIXME: there has to be a better way to do this... - // We should refactor the auto resizing crap. - // We need to figure out the exact cocoa behavior here though. - _lastLocation = location; - - [[CPCursor resizeLeftRightCursor] set]; - [self setNeedsLayout]; - [self setNeedsDisplay:YES]; + [self startTrackingTableColumn:columnIndex at:currentLocation]; + _isTrackingColumn = YES; } } + else if (type === CPLeftMouseDragged) + { + if (shouldResize) + [self continueResizingTableColumn:_activeColumn at:currentLocation]; + else + { + if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation)) + { + if (_isTrackingColumn && _pressedColumn !== CPNotFound) + [self continueTrackingTableColumn:columnIndex at:currentLocation]; + else + [self startTrackingTableColumn:columnIndex at:currentLocation]; + } else if (_isTrackingColumn && _pressedColumn !== CPNotFound) + [self stopTrackingTableColumn:_activeColumn at:currentLocation]; + } + } + + _previousTrackingLocation = currentLocation; + [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +} - [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +/*! + @ignore + Determines if the header view should finish the column tracking + Returns YES if the receiver is in a tracking session, the active column is equal to the hovered column + and the header rect of the column contains the current mouse location +*/ +- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return _isTrackingColumn && _activeColumn === aColumnIndex && + CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint); +} + +- (void)startTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"startTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + [self _setPressedColumn:aColumnIndex]; +} + +- (void)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"continueTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); +} + +- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"stopTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + [self _setPressedColumn:CPNotFound]; +} + +/*! + @ignore + Determines if the table column should be resized + Returns YES if the receiver is already resizing a column or when the tableview allows + resizing and the point is in the resize rect of the column +*/ +- (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + if (_isResizing) + return YES; + + if (_isTrackingColumn) + return NO; + + return [[self tableView] allowsColumnResizing] && CPRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint); +} + +- (void)startResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + _isResizing = YES; + + CPLog.debug(@"startResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + + [tableColumn setDisableResizingPosting:YES]; + [[self tableView] setDisableAutomaticResizing:YES]; + + _resizedColumn = aColumnIndex; +} + +- (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"continueResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + + var newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; + + if (newWidth < [tableColumn minWidth]) + [[CPCursor resizeRightCursor] set]; + else if (newWidth > [tableColumn maxWidth]) + [[CPCursor resizeLeftCursor] set]; + else + { + [self tableView]._lastColumnShouldSnap = NO; + [tableColumn setWidth:newWidth]; + + [[CPCursor resizeLeftRightCursor] set]; + [self setNeedsLayout]; + [self setNeedsDisplay:YES]; + } +} + +- (void)stopResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + CPLog.debug(@"stopResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + // [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; + [tableColumn setDisableResizingPosting:NO]; + [[self tableView] setDisableAutomaticResizing:NO]; + + _isResizing = NO; +} + +// - (void)resizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp +// { +// var tableColumn = [[[self tableColumn] tableColumns] objectAtIndex:aColumnIndex]; +// +// if (isMouseUp) +// { +// [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; +// +// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; +// [tableColumn setDisableResizingPosting:NO]; +// [[self tableView] setDisableAutomaticResizing:NO]; +// } +// else +// { +// var newWidth = [tableColumn width] + location - _lastLocation.x; +// +// if (newWidth < [tableColumn minWidth]) +// [[CPCursor resizeRightCursor] set]; +// else if (newWidth > [tableColumn maxWidth]) +// [[CPCursor resizeLeftCursor] set]; +// else +// { +// [self tableView]._lastColumnShouldSnap = NO; +// [tableColumn setWidth:newWidth]; +// +// [[CPCursor resizeLeftRightCursor] set]; +// [self setNeedsLayout]; +// [self setNeedsDisplay:YES]; +// } +// } +// } + + +// - (BOOL)startTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint +// { +// [self _setPressedColumn:aColumnIndex]; +// +// return YES; + + // var resizeLocation = CPPointMake(aPoint.x - 5.0, aPoint.y); + // + // if ([self shouldResizeTableColumn:aColumnIndex at:aPoint]) + // { + // _resizedColumn = aColumnIndex; + // [[[[self tableView] tableColumns] objectAtIndex:_resizedColumn] setDisableResizingPosting:YES]; + // [[self tableView] setDisableAutomaticResizing:YES]; + // + // // // Use point :) + // // [self trackResizeWithEvent:[CPApp currentEvent]]; + // // return NO; + // } + // + // + // return YES; + + // _clickedColumn = [self columnAtPoint:mouseLocation]; + // + // // should we send column -1 ? + // [_tableView _sendDelegateDidMouseDownInHeader:_clickedColumn]; + // + // var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), + // resizedColumn = [self columnAtPoint:resizeLocation]; + // + // if (resizedColumn == -1) + // return; + // + // // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering + // if ([_tableView allowsColumnResizing] + // && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation)) + // { + // _resizedColumn = resizedColumn; + // [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; + // [_tableView setDisableAutomaticResizing:YES]; + // [self trackResizeWithEvent:theEvent]; + // } + // else + // { + // [self _setPressedColumn:_clickedColumn]; + // [self trackMouseWithEvent:theEvent]; + // } +} +// +// - (BOOL)continueTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint +// { +// } +// +// - (void)stopTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint; +// { +// [self _setPressedColumn:-1]; +// } + + + +// - (void)trackMouseWithEvent:(CPEvent)theEvent +// { +// var type = [theEvent type], +// location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; +// +// if (type === CPLeftMouseUp) +// { +// var clickedColumn = [self columnAtPoint:location], +// pressedColumn = _pressedColumn; +// +// [self _setPressedColumn:-1]; +// +// if (pressedColumn === clickedColumn) +// if (clickedColumn !== -1) +// [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]]; +// +// return; +// } +// else if (type === CPLeftMouseDragged) +// { +// var hoveredColumn = [self columnAtPoint:location]; +// +// CPLog.debug(@"hovered: %i pressed: %i", hoveredColumn, _pressedColumn); +// if (hoveredColumn === _clickedColumn) +// [self _setPressedColumn:_clickedColumn]; +// else +// [self _setPressedColumn:-1] +// } +// // CPLog.debug(@"..."); +// // +// // var point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; +// // +// // var view = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds], CPRectGetHeight([[self tableView] bounds])))]; +// // [view setBackgroundColor:[CPColor greenColor]]; +// // var viewLocation = CPPointMake(point.x - CGRectGetWidth(bounds)/2, point.y - CGRectGetHeight(bounds)/2); +// // +// // [self dragView:view at:viewLocation offset:CPPointMakeZero() event:theEvent pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; +// // return; +// // } +// +// [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; +// } + +// - (void)trackResizeWithEvent:(CPEvent)anEvent +// { +// var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], +// tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], +// type = [anEvent type]; +// +// if (_lastLocation == nil) +// _lastLocation = location; +// +// if (_columnOldWidth == nil) +// _columnOldWidth = [tableColumn width]; +// +// if (type === CPLeftMouseUp) +// { +// [self _updateResizeCursor:anEvent]; +// +// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; +// [tableColumn setDisableResizingPosting:NO]; +// [_tableView setDisableAutomaticResizing:NO]; +// +// _resizedColumn = -1; +// _lastLocation = nil; +// _columnOldWidth = nil; +// +// return; +// } +// else if (type === CPLeftMouseDragged) +// { +// var newWidth = [tableColumn width] + location.x - _lastLocation.x; +// +// if (newWidth < [tableColumn minWidth]) +// [[CPCursor resizeRightCursor] set]; +// else if (newWidth > [tableColumn maxWidth]) +// [[CPCursor resizeLeftCursor] set]; +// else +// { +// _tableView._lastColumnShouldSnap = NO; +// [tableColumn setWidth:newWidth]; +// // FIXME: there has to be a better way to do this... +// // We should refactor the auto resizing crap. +// // We need to figure out the exact cocoa behavior here though. +// _lastLocation = location; +// +// [[CPCursor resizeLeftRightCursor] set]; +// [self setNeedsLayout]; +// [self setNeedsDisplay:YES]; +// } +// } +// +// [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +// } + +- (void)_updateResizeCursorForTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp +{ + if (![[self tableView] allowsColumnResizing] || (isMouseUp && ![[self window] acceptsMouseMovedEvents])) + { + [[CPCursor arrowCursor] set]; + return; + } + + } - (void)_updateResizeCursor:(CPEvent)theEvent From fd9dac81229eeb6d17b450fb8a67379ebaa1ae3b Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Mon, 3 May 2010 11:10:45 +0200 Subject: [PATCH 19/54] - refactored mouse interaction - implemented basic column reordering --- AppKit/CPTableHeaderView.j | 255 +++++++++---------------------------- 1 file changed, 63 insertions(+), 192 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 8087a6724..b0b0db4d5 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -147,6 +147,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal @implementation CPTableHeaderView : CPView { + CPPoint _mouseDownLocation; CPPoint _previousTrackingLocation; int _activeColumn; int _pressedColumn; @@ -279,6 +280,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (type === CPLeftMouseDown) { + _mouseDownLocation = currentLocation; _activeColumn = columnIndex; [[self tableView] _sendDelegateDidMouseDownInHeader:columnIndex]; @@ -292,7 +294,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal } } else if (type === CPLeftMouseDragged) - { + { if (shouldResize) [self continueResizingTableColumn:_activeColumn at:currentLocation]; else @@ -300,9 +302,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation)) { if (_isTrackingColumn && _pressedColumn !== CPNotFound) - [self continueTrackingTableColumn:columnIndex at:currentLocation]; - else + { + if (![self continueTrackingTableColumn:columnIndex at:currentLocation]) + return; // Stop tracking the column, because it's being dragged + } else [self startTrackingTableColumn:columnIndex at:currentLocation]; + } else if (_isTrackingColumn && _pressedColumn !== CPNotFound) [self stopTrackingTableColumn:_activeColumn at:currentLocation]; } @@ -330,9 +335,63 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [self _setPressedColumn:aColumnIndex]; } -- (void)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; +} + +- (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { CPLog.debug(@"continueTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); + + if ([self _shouldDragTableColumn:aColumnIndex at:aPoint]) + { + CPLog.debug(@"start drag"); + + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], + columnRect = [self headerRectOfColumn:aColumnIndex], + // offset = CPSizeMake(_mouseDownLocation.x - aPoint.x, _mouseDownLocation.y); + + var frame = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([[self tableView] bounds])), + view = [[CPView alloc] initWithFrame:frame]; + + [view setBackgroundColor:[CPColor greenColor]]; + + [self dragView:view at:aPoint offset:CPSizeMake(0.0, 0.0) event:[CPApp currentEvent] + pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; + + return NO; + } + + return YES; +} + +- (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint +{ + var hoveredColumn = [self columnAtPoint:aPoint], + if (_activeColumn === hoveredColumn) + return; + + var columnRect = [self headerRectOfColumn:hoveredColumn], + columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); + + if (_activeColumn < hoveredColumn && aPoint.x > columnCenterPoint.x) + { + [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; + _activeColumn = hoveredColumn; + } + else if (_activeColumn > hoveredColumn && aPoint.x < columnCenterPoint.x) + { + [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; + _activeColumn = hoveredColumn; + } +} + +- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation +{ + CPLog.debug(@"draggedView view ended at: %@", CPStringFromPoint(aLocation)); + + [self stopTrackingTableColumn:[self columnAtPoint:aLocation] at:aLocation]; } - (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint @@ -409,194 +468,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _isResizing = NO; } -// - (void)resizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp -// { -// var tableColumn = [[[self tableColumn] tableColumns] objectAtIndex:aColumnIndex]; -// -// if (isMouseUp) -// { -// [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; -// -// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; -// [tableColumn setDisableResizingPosting:NO]; -// [[self tableView] setDisableAutomaticResizing:NO]; -// } -// else -// { -// var newWidth = [tableColumn width] + location - _lastLocation.x; -// -// if (newWidth < [tableColumn minWidth]) -// [[CPCursor resizeRightCursor] set]; -// else if (newWidth > [tableColumn maxWidth]) -// [[CPCursor resizeLeftCursor] set]; -// else -// { -// [self tableView]._lastColumnShouldSnap = NO; -// [tableColumn setWidth:newWidth]; -// -// [[CPCursor resizeLeftRightCursor] set]; -// [self setNeedsLayout]; -// [self setNeedsDisplay:YES]; -// } -// } -// } - - -// - (BOOL)startTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint -// { -// [self _setPressedColumn:aColumnIndex]; -// -// return YES; - - // var resizeLocation = CPPointMake(aPoint.x - 5.0, aPoint.y); - // - // if ([self shouldResizeTableColumn:aColumnIndex at:aPoint]) - // { - // _resizedColumn = aColumnIndex; - // [[[[self tableView] tableColumns] objectAtIndex:_resizedColumn] setDisableResizingPosting:YES]; - // [[self tableView] setDisableAutomaticResizing:YES]; - // - // // // Use point :) - // // [self trackResizeWithEvent:[CPApp currentEvent]]; - // // return NO; - // } - // - // - // return YES; - - // _clickedColumn = [self columnAtPoint:mouseLocation]; - // - // // should we send column -1 ? - // [_tableView _sendDelegateDidMouseDownInHeader:_clickedColumn]; - // - // var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), - // resizedColumn = [self columnAtPoint:resizeLocation]; - // - // if (resizedColumn == -1) - // return; - // - // // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering - // if ([_tableView allowsColumnResizing] - // && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation)) - // { - // _resizedColumn = resizedColumn; - // [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES]; - // [_tableView setDisableAutomaticResizing:YES]; - // [self trackResizeWithEvent:theEvent]; - // } - // else - // { - // [self _setPressedColumn:_clickedColumn]; - // [self trackMouseWithEvent:theEvent]; - // } -} -// -// - (BOOL)continueTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint -// { -// } -// -// - (void)stopTrackingColumn:(int)aColumnIndex at:(CPPoint)aPoint; -// { -// [self _setPressedColumn:-1]; -// } - - - -// - (void)trackMouseWithEvent:(CPEvent)theEvent -// { -// var type = [theEvent type], -// location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; -// -// if (type === CPLeftMouseUp) -// { -// var clickedColumn = [self columnAtPoint:location], -// pressedColumn = _pressedColumn; -// -// [self _setPressedColumn:-1]; -// -// if (pressedColumn === clickedColumn) -// if (clickedColumn !== -1) -// [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]]; -// -// return; -// } -// else if (type === CPLeftMouseDragged) -// { -// var hoveredColumn = [self columnAtPoint:location]; -// -// CPLog.debug(@"hovered: %i pressed: %i", hoveredColumn, _pressedColumn); -// if (hoveredColumn === _clickedColumn) -// [self _setPressedColumn:_clickedColumn]; -// else -// [self _setPressedColumn:-1] -// } -// // CPLog.debug(@"..."); -// // -// // var point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; -// // -// // var view = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds], CPRectGetHeight([[self tableView] bounds])))]; -// // [view setBackgroundColor:[CPColor greenColor]]; -// // var viewLocation = CPPointMake(point.x - CGRectGetWidth(bounds)/2, point.y - CGRectGetHeight(bounds)/2); -// // -// // [self dragView:view at:viewLocation offset:CPPointMakeZero() event:theEvent pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; -// // return; -// // } -// -// [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES]; -// } - -// - (void)trackResizeWithEvent:(CPEvent)anEvent -// { -// var location = [self convertPoint:[anEvent locationInWindow] fromView:nil], -// tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn], -// type = [anEvent type]; -// -// if (_lastLocation == nil) -// _lastLocation = location; -// -// if (_columnOldWidth == nil) -// _columnOldWidth = [tableColumn width]; -// -// if (type === CPLeftMouseUp) -// { -// [self _updateResizeCursor:anEvent]; -// -// [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; -// [tableColumn setDisableResizingPosting:NO]; -// [_tableView setDisableAutomaticResizing:NO]; -// -// _resizedColumn = -1; -// _lastLocation = nil; -// _columnOldWidth = nil; -// -// return; -// } -// else if (type === CPLeftMouseDragged) -// { -// var newWidth = [tableColumn width] + location.x - _lastLocation.x; -// -// if (newWidth < [tableColumn minWidth]) -// [[CPCursor resizeRightCursor] set]; -// else if (newWidth > [tableColumn maxWidth]) -// [[CPCursor resizeLeftCursor] set]; -// else -// { -// _tableView._lastColumnShouldSnap = NO; -// [tableColumn setWidth:newWidth]; -// // FIXME: there has to be a better way to do this... -// // We should refactor the auto resizing crap. -// // We need to figure out the exact cocoa behavior here though. -// _lastLocation = location; -// -// [[CPCursor resizeLeftRightCursor] set]; -// [self setNeedsLayout]; -// [self setNeedsDisplay:YES]; -// } -// } -// -// [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; -// } - - (void)_updateResizeCursorForTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp { if (![[self tableView] allowsColumnResizing] || (isMouseUp && ![[self window] acceptsMouseMovedEvents])) From dca66f300db7004907d072371f2ab74f3bce808a Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Mon, 3 May 2010 14:42:52 +0200 Subject: [PATCH 20/54] - gave the drag column a proper 'image' representation - constrained the drags y coordinates - made sure a drag is never out of bounds --- AppKit/CPTableHeaderView.j | 42 ++++++++++++++++++++++++------ AppKit/CPTableView.j | 53 +++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index b0b0db4d5..6e33d0483 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -349,15 +349,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal CPLog.debug(@"start drag"); var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], - columnRect = [self headerRectOfColumn:aColumnIndex], - // offset = CPSizeMake(_mouseDownLocation.x - aPoint.x, _mouseDownLocation.y); + columnRect = [self headerRectOfColumn:aColumnIndex]; - var frame = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([[self tableView] bounds])), - view = [[CPView alloc] initWithFrame:frame]; - - [view setBackgroundColor:[CPColor greenColor]]; + var offset = CPPointMakeZero(), + view = [[self tableView] dragViewForTableColumns:[tableColumn] event:[CPApp currentEvent] offset:offset], + viewLocation = CPPointMakeZero(); - [self dragView:view at:aPoint offset:CPSizeMake(0.0, 0.0) event:[CPApp currentEvent] + viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); + viewLocation.y = CPRectGetMinY(columnRect) + offset.y; + + [view setAlphaValue:0.7]; + + [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent] pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; return NO; @@ -366,10 +369,33 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return YES; } +- (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint +{ + var tableColumns = [[self tableView] tableColumns], + lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + dragWindow = [theDragView window], + frame = [dragWindow frame]; + + // Because the drag window is as wide as the entire tableview, it's start origin is always 0.0 + // The minimal x coordinate is the minimal dragged table columns negated x value + var minimumX = -(CPRectGetMinX([self headerRectOfColumn:_activeColumn])) + maximumX = CPRectGetMinX(lastColumnRect); + + // This effectively clamps the value between the minimal and maximum + // frame.origin.x = MAX(minimumX, MIN(CPRectGetMinX(frame), maximumX)); + + // Make sure the column cannot move vertically + frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); + + [dragWindow setFrame:frame]; +} + - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint { + [self _constrainDragView:aView at:aPoint]; + var hoveredColumn = [self columnAtPoint:aPoint], - if (_activeColumn === hoveredColumn) + if (hoveredColumn === -1 || _activeColumn === hoveredColumn) return; var columnRect = [self headerRectOfColumn:hoveredColumn], diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index b3c6add2a..11a6cab8f 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1803,7 +1803,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)]; } -- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPoint)dragViewOffset +- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)dragViewOffset { var bounds = [self bounds], view = [[CPView alloc] initWithFrame:bounds]; @@ -1839,6 +1839,57 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return view; } +- (CPView)dragViewForTableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset +{ + var bounds = CPRectMake(0.0, 0.0, 0.0, CPRectGetHeight([self bounds]) + 23.0); + index = [theTableColumns count], + dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; + + // Fetch all the data views for the columns and visible rows + // After that copy these add them to a transparent drag view and use that drag view + // to make it appear we are dragging images of those rows (as you would do in regular Cocoa) + while (index--) + { + // Get the tablecolumn and create a rect with it's width so we can use CPRectUnion + // to determine the end result + var tableColumn = [theTableColumns objectAtIndex:index], + columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:tableColumn]; + columnRect = [self rectOfColumn:columnIndex], + headerView = [tableColumn headerView]; + + // Add the column header view + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:[headerView frame]]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; + + bounds = CPRectUnion(bounds, columnRect); + + row = [_exposedRows firstIndex]; + while (row !== CPNotFound) + { + var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], + dataViewFrame = [self frameOfDataViewAtColumn:columnIndex row:row]; + + // Offset by table header height to make room for the table header + dataViewFrame.origin.y += 23.0; + [dataView setFrame:dataViewFrame]; + + [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; + [dragView addSubview:dataView]; + + row = [_exposedRows indexGreaterThanIndex:row]; + } + } + + // The columns are placed in the drag window at their original locations resulting in the dragged column + // being of when started the drag, we compensate for this by offseting the drag window by the x coordinate of the column + theDragViewOffset.x -= columnRect.origin.x; + [dragView setFrame:bounds]; + + return dragView; +} + - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal { //ignoral local for the time being since only one capp app can run at a time... From f7b766cc4a420347a84e9e7d982e085485c0cf81 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 12:06:06 +0200 Subject: [PATCH 21/54] - made the _dragViewForTableColumn:event:offset: method private - removed the multiple column support from _dragViewForTableColumn:event:offset: (Cocoa doesn't allow multiple column selection / dragging) - made the dragview the size of the dragged column --- AppKit/CPTableHeaderView.j | 12 ++---- AppKit/CPTableView.j | 77 +++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 6e33d0483..735b7bfcf 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -346,20 +346,14 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if ([self _shouldDragTableColumn:aColumnIndex at:aPoint]) { - CPLog.debug(@"start drag"); - - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], - columnRect = [self headerRectOfColumn:aColumnIndex]; - - var offset = CPPointMakeZero(), - view = [[self tableView] dragViewForTableColumns:[tableColumn] event:[CPApp currentEvent] offset:offset], + var columnRect = [self headerRectOfColumn:aColumnIndex], + offset = CPPointMakeZero(), + view = [[self tableView] _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset], viewLocation = CPPointMakeZero(); viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); viewLocation.y = CPRectGetMinY(columnRect) + offset.y; - [view setAlphaValue:0.7]; - [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent] pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 11a6cab8f..f8d3f99dc 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1839,52 +1839,51 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return view; } -- (CPView)dragViewForTableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset -{ - var bounds = CPRectMake(0.0, 0.0, 0.0, CPRectGetHeight([self bounds]) + 23.0); - index = [theTableColumns count], - dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; - - // Fetch all the data views for the columns and visible rows - // After that copy these add them to a transparent drag view and use that drag view +/*! + @ignore + // Fetches all the data views (from the datasource) for the column and it's visible rows + // Copy the dataviews add them to a transparent drag view and use that drag view // to make it appear we are dragging images of those rows (as you would do in regular Cocoa) - while (index--) +*/ +- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset +{ + var dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; + tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex], + bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self bounds]) + 23.0), + columnRect = [self rectOfColumn:theColumnIndex], + headerView = [tableColumn headerView]; + + // Add the column header view + var headerFrame = [headerView frame]; + headerFrame.origin = CPPointMakeZero(); + + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; + + row = [_exposedRows firstIndex]; + while (row !== CPNotFound) { - // Get the tablecolumn and create a rect with it's width so we can use CPRectUnion - // to determine the end result - var tableColumn = [theTableColumns objectAtIndex:index], - columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:tableColumn]; - columnRect = [self rectOfColumn:columnIndex], - headerView = [tableColumn headerView]; + var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], + dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row]; + + // Offset by table header height to make room for the table header + dataViewFrame.origin.x = 0.0; + dataViewFrame.origin.y += 23.0; + [dataView setFrame:dataViewFrame]; - // Add the column header view - columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:[headerView frame]]; - [columnHeaderView setStringValue:[headerView stringValue]]; - [columnHeaderView setThemeState:[headerView themeState]]; - [dragView addSubview:columnHeaderView]; - - bounds = CPRectUnion(bounds, columnRect); + [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; + [dragView addSubview:dataView]; - row = [_exposedRows firstIndex]; - while (row !== CPNotFound) - { - var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], - dataViewFrame = [self frameOfDataViewAtColumn:columnIndex row:row]; - - // Offset by table header height to make room for the table header - dataViewFrame.origin.y += 23.0; - [dataView setFrame:dataViewFrame]; - - [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; - [dragView addSubview:dataView]; - - row = [_exposedRows indexGreaterThanIndex:row]; - } + row = [_exposedRows indexGreaterThanIndex:row]; } // The columns are placed in the drag window at their original locations resulting in the dragged column - // being of when started the drag, we compensate for this by offseting the drag window by the x coordinate of the column - theDragViewOffset.x -= columnRect.origin.x; + // being of when starting the drag, we compensate for this by offseting the drag window by the x coordinate of the column + // theDragViewOffset.x -= columnRect.origin.x; + + [dragView setAlphaValue:0.7]; [dragView setFrame:bounds]; return dragView; From 256cc902ebf0b504185a9658520344fead7a4ff4 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 13:52:57 +0200 Subject: [PATCH 22/54] - switch columns when the dragged column is more than halfway over the previous/next column - constrain the horizontal coordinates within the header view --- AppKit/CPTableHeaderView.j | 104 +++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 735b7bfcf..140aacf23 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -317,33 +317,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; } -/*! - @ignore - Determines if the header view should finish the column tracking - Returns YES if the receiver is in a tracking session, the active column is equal to the hovered column - and the header rect of the column contains the current mouse location -*/ -- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - return _isTrackingColumn && _activeColumn === aColumnIndex && - CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint); -} - - (void)startTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - CPLog.debug(@"startTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); [self _setPressedColumn:aColumnIndex]; } -- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; -} - - (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - CPLog.debug(@"continueTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - +{ if ([self _shouldDragTableColumn:aColumnIndex at:aPoint]) { var columnRect = [self headerRectOfColumn:aColumnIndex], @@ -363,20 +343,32 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return YES; } +- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return _isTrackingColumn && _activeColumn === aColumnIndex && + CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint); +} + +- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + [self _setPressedColumn:CPNotFound]; +} + +- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint +{ + return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; +} + - (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint { var tableColumns = [[self tableView] tableColumns], lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + activeColumnRect = [self headerRectOfColumn:_activeColumn]; dragWindow = [theDragView window], frame = [dragWindow frame]; - // Because the drag window is as wide as the entire tableview, it's start origin is always 0.0 - // The minimal x coordinate is the minimal dragged table columns negated x value - var minimumX = -(CPRectGetMinX([self headerRectOfColumn:_activeColumn])) - maximumX = CPRectGetMinX(lastColumnRect); - - // This effectively clamps the value between the minimal and maximum - // frame.origin.x = MAX(minimumX, MIN(CPRectGetMinX(frame), maximumX)); + // This effectively clamps the value between the minimum and maximum + frame.origin.x = MAX(0.0, MIN(CPRectGetMinX(frame), CPRectGetMaxX(lastColumnRect) - CPRectGetWidth(activeColumnRect))); // Make sure the column cannot move vertically frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); @@ -384,48 +376,46 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [dragWindow setFrame:frame]; } +- (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex +{ + [[self tableView] moveColumn:aFromIndex toColumn:aToIndex]; + _activeColumn = aToIndex; + _pressedColumn = _activeColumn; +} + - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint { [self _constrainDragView:aView at:aPoint]; - var hoveredColumn = [self columnAtPoint:aPoint], - if (hoveredColumn === -1 || _activeColumn === hoveredColumn) - return; - - var columnRect = [self headerRectOfColumn:hoveredColumn], - columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); + var dragWindowFrame = [[aView window] frame]; - if (_activeColumn < hoveredColumn && aPoint.x > columnCenterPoint.x) + var hoverPoint = CPPointCreateCopy(aPoint); + if (aPoint.x < _previousTrackingLocation.x) + hoverPoint = CPPointMake(CPRectGetMinX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); + else if (aPoint.x > _previousTrackingLocation.x) + hoverPoint = CPPointMake(CPRectGetMaxX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); + + var hoveredColumn = [self columnAtPoint:hoverPoint], + + if (hoveredColumn !== -1) { - [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; - _activeColumn = hoveredColumn; - } - else if (_activeColumn > hoveredColumn && aPoint.x < columnCenterPoint.x) - { - [[self tableView] moveColumn:_activeColumn toColumn:hoveredColumn]; - _activeColumn = hoveredColumn; + var columnRect = [self headerRectOfColumn:hoveredColumn], + columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); + + if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x) + [self _moveColumn:_activeColumn toColumn:hoveredColumn]; + else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x) + [self _moveColumn:_activeColumn toColumn:hoveredColumn]; } + + _previousTrackingLocation = aPoint; } - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation { - CPLog.debug(@"draggedView view ended at: %@", CPStringFromPoint(aLocation)); - - [self stopTrackingTableColumn:[self columnAtPoint:aLocation] at:aLocation]; + [self stopTrackingTableColumn:_activeColumn at:aLocation]; } -- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint -{ - CPLog.debug(@"stopTrackingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - [self _setPressedColumn:CPNotFound]; -} - -/*! - @ignore - Determines if the table column should be resized - Returns YES if the receiver is already resizing a column or when the tableview allows - resizing and the point is in the resize rect of the column -*/ - (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { if (_isResizing) From 983f0a92b2d87523052344bc5ff127fc48784a55 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 11 May 2010 00:25:19 -0500 Subject: [PATCH 23/54] - fixed a out of bounds error when clicking in the table header outside of any column - made the dragged table column appear gray - gave the tablecolumn drag view a white background Conflicts: AppKit/CPTableView.j --- AppKit/CPTableHeaderView.j | 50 +++++++++++++++++++++----------------- AppKit/CPTableView.j | 38 ++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 140aacf23..3d467997d 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -26,7 +26,7 @@ @implementation _CPTableColumnHeaderView : CPView { - _CPImageAndTextView _textField; + _CPImageAndTextView _textField; } - (void)initWithFrame:(CGRect)frame @@ -153,6 +153,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal int _pressedColumn; BOOL _isResizing; + BOOL _isDragging; BOOL _isTrackingColumn; // CPPoint _previousTrackingLocation; @@ -280,6 +281,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (type === CPLeftMouseDown) { + if (columnIndex === -1) + return; + _mouseDownLocation = currentLocation; _activeColumn = columnIndex; @@ -381,6 +385,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [[self tableView] moveColumn:aFromIndex toColumn:aToIndex]; _activeColumn = aToIndex; _pressedColumn = _activeColumn; + + [[self tableView] _setDraggedColumn:_activeColumn]; +} + +- (void)draggedView:(CPView)aView beganAt:(CPPoint)aPoint +{ + _isDragging = YES; + + [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:YES]; + [[self tableView] _setDraggedColumn:_activeColumn]; + + [self setNeedsDisplay:YES]; } - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint @@ -413,7 +429,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation { + _isDragging = NO; + + [[self tableView] _setDraggedColumn:-1]; + [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; [self stopTrackingTableColumn:_activeColumn at:aLocation]; + + [self setNeedsDisplay:YES]; } - (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint @@ -602,27 +624,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal CGContextClosePath(context); CGContextStrokePath(context); - -/* - var maxY = CGRectGetMaxY([self bounds]); - // draw normal gradient for remaining space - if (supportsCanvasGradient) + + if (_isDragging) { - aRect.origin.x = columnMaxX - 0.5; - aRect.size.width -= columnMaxX; - CGContextBeginPath(context); - CGContextAddRect(context, CGRectMake(columnMaxX + 1, 0, CGRectGetMaxX([self bounds]) - columnMaxX, CGRectGetHeight([self bounds]))); - CGContextClosePath(context); - CGContextDrawLinearGradient(context, [_CPTableColumnHeaderView headerGradient], CGPointMake(0,0), CGPointMake(0, maxY - 1),0); - } - - // Draw bottom line - CGContextBeginPath(context); - CGContextMoveToPoint(context, 0, maxY - 0.5); - CGContextAddLineToPoint(context, CGRectGetMaxX([self bounds]), maxY - 0.5); - CGContextClosePath(context); - CGContextStrokePath(context); -*/ + CGContextSetFillColor(context, [CPColor grayColor]); + CGContextFillRect(context, [self headerRectOfColumn:_activeColumn]) + } } @end @@ -649,4 +656,3 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey"; } @end - diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index f8d3f99dc..73f4ab1f6 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -212,6 +212,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; CPGradient _sourceListActiveGradient; CPColor _sourceListActiveTopLineColor; CPColor _sourceListActiveBottomLineColor; + + int _draggedColumnIndex; + /* CPGradient _sourceListInactiveGradient; CPColor _sourceListInactiveTopLineColor; @@ -309,7 +312,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (!_cornerView) _cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))]; - + + _draggedColumnIndex = -1; + // Gradients for the source list _sourceListActiveGradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0/255.0, 153.0/255.0, 209.0/255.0,1.0, 33.0/255.0, 94.0/255.0, 208.0/255.0,1.0], [0,1], 2); _sourceListActiveTopLineColor = [CPColor colorWithCalibratedRed:(61.0/255.0) green:(123.0/255.0) blue:(218.0/255.0) alpha:1.0]; @@ -672,6 +677,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self setNeedsLayout]; } +- (void)_setDraggedColumn:(int)aColumnIndex +{ + if (_draggedColumnIndex === aColumnIndex) + return; + + _draggedColumnIndex = aColumnIndex; + + [self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:aColumnIndex]]; +} /*! Moves the column and heading at a given index to a new given index. @@ -703,7 +717,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)]; [self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes]; - // [self setNeedsLayout]; } /*! @@ -1849,7 +1862,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; { var dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()]; tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex], - bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self bounds]) + 23.0), + bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self _exposedRect]) + 23.0), columnRect = [self rectOfColumn:theColumnIndex], headerView = [tableColumn headerView]; @@ -1883,6 +1896,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; // being of when starting the drag, we compensate for this by offseting the drag window by the x coordinate of the column // theDragViewOffset.x -= columnRect.origin.x; + [dragView setBackgroundColor:[CPColor whiteColor]]; [dragView setAlphaValue:0.7]; [dragView setFrame:bounds]; @@ -2129,8 +2143,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; for (; columnIndex < columnsCount; ++columnIndex) { var column = columnArray[columnIndex], - tableColumn = _tableColumns[column], - tableColumnUID = [tableColumn UID]; + tableColumn = _tableColumns[column]; + + if ([tableColumn isHidden] || columnIndex === _draggedColumnIndex) + continue; + + var tableColumnUID = [tableColumn UID]; if (!_dataViewsForTableColumns[tableColumnUID]) _dataViewsForTableColumns[tableColumnUID] = []; @@ -2280,6 +2298,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self drawBackgroundInClipRect:exposedRect]; [self drawGridInClipRect:exposedRect]; [self highlightSelectionInClipRect:exposedRect]; + + if (_draggedColumnIndex === -1) + return; + + var context = [[CPGraphicsContext currentContext] graphicsPort], + columnRect = [self rectOfColumn:_draggedColumnIndex]; + + CGContextSetFillColor(context, [CPColor grayColor]); + CGContextFillRect(context, columnRect); } - (void)drawBackgroundInClipRect:(CGRect)aRect @@ -2287,7 +2314,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (!_usesAlternatingRowBackgroundColors) return; - var rowColors = [self alternatingRowBackgroundColors], colorCount = [rowColors count]; From b8c7d6ea86c51de7b41aa507fd747fa61132574b Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 4 May 2010 15:54:13 +0200 Subject: [PATCH 24/54] some cleanup --- AppKit/CPTableHeaderView.j | 63 ++++++++++---------------------------- 1 file changed, 16 insertions(+), 47 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 3d467997d..d820c2e1e 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -156,29 +156,23 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal BOOL _isDragging; BOOL _isTrackingColumn; - // CPPoint _previousTrackingLocation; - // - // int _resizedColumn @accessors(readonly, property=resizedColumn); - // int _draggedColumn @accessors(readonly, property=draggedColumn); - // int _pressedColumn @accessors(readonly, property=pressedColumn); - // int _clickedColumn @accessors(readonly, property=clickedColumn); - // BOOL _isTrackingColumn; - // - // float _draggedDistance @accessors(readonly, property=draggedDistance); - // float _lastLocation; - // float _columnOldWidth; + float _columnOldWidth; - CPTableView _tableView @accessors(property=tableView); + CPTableView _tableView @accessors(property=tableView); } - (void)_init { - _resizedColumn = -1; - _draggedColumn = -1; - _pressedColumn = CPNotFound; - _draggedDistance = 0.0; - _lastLocation = nil; - _columnOldWidth = nil; + _mouseDownLocation = CPPointMakeZero(); + _previousTrackingLocation = CPPointMakeZero(); + _activeColumn = -1; + _pressedColumn = -1; + + _isResizing = NO; + _isDragging = NO; + _isTrackingColumn = NO; + + _columnOldWidth = 0.0; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]]; } @@ -305,14 +299,14 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation)) { - if (_isTrackingColumn && _pressedColumn !== CPNotFound) + if (_isTrackingColumn && _pressedColumn !== -1) { if (![self continueTrackingTableColumn:columnIndex at:currentLocation]) return; // Stop tracking the column, because it's being dragged } else [self startTrackingTableColumn:columnIndex at:currentLocation]; - } else if (_isTrackingColumn && _pressedColumn !== CPNotFound) + } else if (_isTrackingColumn && _pressedColumn !== -1) [self stopTrackingTableColumn:_activeColumn at:currentLocation]; } } @@ -356,6 +350,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { [self _setPressedColumn:CPNotFound]; + [self _updateResizeCursor:[CPApp currentEvent]]; } - (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint @@ -430,6 +425,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation { _isDragging = NO; + _isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached [[self tableView] _setDraggedColumn:-1]; [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; @@ -453,20 +449,14 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { _isResizing = YES; - CPLog.debug(@"startResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; [tableColumn setDisableResizingPosting:YES]; [[self tableView] setDisableAutomaticResizing:YES]; - - _resizedColumn = aColumnIndex; } - (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - CPLog.debug(@"continueResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; var newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; @@ -488,10 +478,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)stopResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - CPLog.debug(@"stopResizingTableColumn: %@ at: %@", aColumnIndex, CPStringFromPoint(aPoint)); - - // [self _updateResizeCursorForTableColumn:aColumnIndex at:aPoint]; - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; [tableColumn setDisableResizingPosting:NO]; @@ -500,17 +486,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _isResizing = NO; } -- (void)_updateResizeCursorForTableColumn:(int)aColumnIndex at:(CPPoint)aPoint mouseIsUp:(BOOL)isMouseUp -{ - if (![[self tableView] allowsColumnResizing] || (isMouseUp && ![[self window] acceptsMouseMovedEvents])) - { - [[CPCursor arrowCursor] set]; - return; - } - - -} - - (void)_updateResizeCursor:(CPEvent)theEvent { // never get stuck in resize cursor mode (FIXME take out when we turn on tracking rects) @@ -540,12 +515,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [[CPCursor arrowCursor] set]; } -- (void)viewDidMoveToWindow -{ - //if ([_tableView allowsColumnResizing]) - // [[self window] setAcceptsMouseMovedEvents:YES]; -} - - (void)mouseEntered:(CPEvent)theEvent { [self _updateResizeCursor:theEvent]; From d7432c376d1d6905c046fdf35e6f9de2b83b116d Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Wed, 5 May 2010 10:38:41 +0200 Subject: [PATCH 25/54] fixed a bug where column reordering would break when the last column was hidden --- AppKit/CPTableHeaderView.j | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index d820c2e1e..0c5b23a28 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -358,10 +358,26 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; } +- (CPRect)_headerRectOfLastVisibleColumn +{ + var tableColumns = [[self tableView] tableColumns], + columnIndex = [tableColumns count]; + + while (columnIndex--) + { + var tableColumn = [tableColumns objectAtIndex:columnIndex]; + + if (![tableColumn isHidden]) + return [self headerRectOfColumn:columnIndex]; + } + + return nil; +} + - (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint { var tableColumns = [[self tableView] tableColumns], - lastColumnRect = [self headerRectOfColumn:[tableColumns indexOfObjectIdenticalTo:[tableColumns lastObject]]], + lastColumnRect = [self _headerRectOfLastVisibleColumn]; activeColumnRect = [self headerRectOfColumn:_activeColumn]; dragWindow = [theDragView window], frame = [dragWindow frame]; From 213c81ed4d13baca7e85fbb9ebaa3484996431a4 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Wed, 5 May 2010 12:56:23 +0200 Subject: [PATCH 26/54] made table column reordering work in non full-bridged apps --- AppKit/CPTableHeaderView.j | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 0c5b23a28..64125b0f7 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -382,12 +382,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal dragWindow = [theDragView window], frame = [dragWindow frame]; + // Convert the frame origin from the global coordinate system to the windows' coordinate system + frame.origin = [[self window] convertGlobalToBase:frame.origin]; + // This effectively clamps the value between the minimum and maximum frame.origin.x = MAX(0.0, MIN(CPRectGetMinX(frame), CPRectGetMaxX(lastColumnRect) - CPRectGetWidth(activeColumnRect))); // Make sure the column cannot move vertically frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); + // Convert the calculated origin back to the global coordinate system + frame.origin = [[self window] convertBaseToGlobal:frame.origin]; + [dragWindow setFrame:frame]; } @@ -414,7 +420,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { [self _constrainDragView:aView at:aPoint]; - var dragWindowFrame = [[aView window] frame]; + var dragWindow = [aView window], + dragWindowFrame = [dragWindow frame]; var hoverPoint = CPPointCreateCopy(aPoint); if (aPoint.x < _previousTrackingLocation.x) @@ -422,13 +429,16 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal else if (aPoint.x > _previousTrackingLocation.x) hoverPoint = CPPointMake(CPRectGetMaxX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); - var hoveredColumn = [self columnAtPoint:hoverPoint], + // Convert the hover point from the global coordinate system to windows' coordinate system + hoverPoint = [[self window] convertGlobalToBase:hoverPoint]; + + var hoveredColumn = [self columnAtPoint:hoverPoint]; if (hoveredColumn !== -1) { var columnRect = [self headerRectOfColumn:hoveredColumn], columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); - + if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x) [self _moveColumn:_activeColumn toColumn:hoveredColumn]; else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x) From 79ba8fecd5b1b69e72cb63ff080a8bebb1c4d3cc Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Wed, 5 May 2010 14:08:06 +0200 Subject: [PATCH 27/54] made column reordering work with scrolled content --- AppKit/CPTableView.j | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 73f4ab1f6..72f4c2033 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1866,24 +1866,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; columnRect = [self rectOfColumn:theColumnIndex], headerView = [tableColumn headerView]; - // Add the column header view - var headerFrame = [headerView frame]; - headerFrame.origin = CPPointMakeZero(); - - columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame]; - [columnHeaderView setStringValue:[headerView stringValue]]; - [columnHeaderView setThemeState:[headerView themeState]]; - [dragView addSubview:columnHeaderView]; - row = [_exposedRows firstIndex]; while (row !== CPNotFound) { var dataView = [self _newDataViewForRow:row tableColumn:tableColumn], dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row]; - // Offset by table header height to make room for the table header + // Only one column is ever dragged so we just place the view at dataViewFrame.origin.x = 0.0; - dataViewFrame.origin.y += 23.0; + + // Offset by table header height - scroll position + dataViewFrame.origin.y = ( CPRectGetMinY(dataViewFrame) - CPRectGetMinY([self _exposedRect]) ) + 23.0; [dataView setFrame:dataViewFrame]; [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; @@ -1892,9 +1885,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; row = [_exposedRows indexGreaterThanIndex:row]; } - // The columns are placed in the drag window at their original locations resulting in the dragged column - // being of when starting the drag, we compensate for this by offseting the drag window by the x coordinate of the column - // theDragViewOffset.x -= columnRect.origin.x; + // Add the column header view + var headerFrame = [headerView frame]; + headerFrame.origin = CPPointMakeZero(); + + columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame]; + [columnHeaderView setStringValue:[headerView stringValue]]; + [columnHeaderView setThemeState:[headerView themeState]]; + [dragView addSubview:columnHeaderView]; [dragView setBackgroundColor:[CPColor whiteColor]]; [dragView setAlphaValue:0.7]; From 0f02e0d8ddd0b613873c9306df188ba36789a2e0 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Tue, 11 May 2010 12:40:37 -0700 Subject: [PATCH 28/54] Revert "added enumerateWithBlock: to CPArray" This reverts commit 39bb8e341896050afa7b5d8d6489493898c3571f. --- Foundation/CPArray.j | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Foundation/CPArray.j b/Foundation/CPArray.j index f4f8be793..e26731db4 100755 --- a/Foundation/CPArray.j +++ b/Foundation/CPArray.j @@ -1224,18 +1224,6 @@ sort(function(lhs, rhs) { return objj_msgSend(lhs, aSelector, rhs); }); } -- (void)enumerateObjectsUsingBlock:(Function)aBlock -{ - for (var i = 0; i < self.length; i++) - { - var shouldStop = NO; - aBlock(self[i], i, shouldStop); - - if (shouldStop) - break; - } -} - @end @implementation CPArray (CPCoding) From bf71045381d9a275c7322fd6e5ca10a14523ec68 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 11 May 2010 19:39:51 -0500 Subject: [PATCH 29/54] Fixed bug where column reordering would be off if the table didn't sit at (0,0) on a window. --- AppKit/CPTableHeaderView.j | 44 ++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 4bbb4e006..3507b18ee 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -373,19 +373,23 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal activeColumnRect = [self headerRectOfColumn:_activeColumn]; dragWindow = [theDragView window], frame = [dragWindow frame]; - + // Convert the frame origin from the global coordinate system to the windows' coordinate system frame.origin = [[self window] convertGlobalToBase:frame.origin]; - + // the from the window to the view + frame.origin = [self convertPoint:frame.origin fromView:nil]; + // This effectively clamps the value between the minimum and maximum - frame.origin.x = MAX(0.0, MIN(CPRectGetMinX(frame), CPRectGetMaxX(lastColumnRect) - CPRectGetWidth(activeColumnRect))); - + frame.origin.x = MAX(0.0, MIN(CGRectGetMinX(frame), CGRectGetMaxX(lastColumnRect) - CGRectGetWidth(activeColumnRect))); + // Make sure the column cannot move vertically - frame.origin.y = CPRectGetMinY([self convertRect:lastColumnRect toView:nil]); - - // Convert the calculated origin back to the global coordinate system + frame.origin.y = CPRectGetMinY(lastColumnRect); + + // Convert the calculated origin back to the window coordinate system + frame.origin = [self convertPoint:frame.origin toView:nil]; + // Then back to the global coordinate system frame.origin = [[self window] convertBaseToGlobal:frame.origin]; - + [dragWindow setFrame:frame]; } @@ -411,32 +415,34 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint { [self _constrainDragView:aView at:aPoint]; - + var dragWindow = [aView window], dragWindowFrame = [dragWindow frame]; - - var hoverPoint = CPPointCreateCopy(aPoint); + + var hoverPoint = CGPointCreateCopy(aPoint); + if (aPoint.x < _previousTrackingLocation.x) - hoverPoint = CPPointMake(CPRectGetMinX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); + hoverPoint = CGPointMake(CGRectGetMinX(dragWindowFrame), CGRectGetMinY(dragWindowFrame)); else if (aPoint.x > _previousTrackingLocation.x) - hoverPoint = CPPointMake(CPRectGetMaxX(dragWindowFrame), CPRectGetMinY(dragWindowFrame)); - + hoverPoint = CGPointMake(CGRectGetMaxX(dragWindowFrame), CGRectGetMinY(dragWindowFrame)); + // Convert the hover point from the global coordinate system to windows' coordinate system hoverPoint = [[self window] convertGlobalToBase:hoverPoint]; - + // then to the view + hoverPoint = [self convertPoint:hoverPoint fromView:nil]; + var hoveredColumn = [self columnAtPoint:hoverPoint]; - + if (hoveredColumn !== -1) { var columnRect = [self headerRectOfColumn:hoveredColumn], - columnCenterPoint = CPPointMake(CPRectGetMidX(columnRect), CPRectGetMidY(columnRect)); - + columnCenterPoint = [self convertPoint:CGPointMake(CGRectGetMidX(columnRect), CGRectGetMidY(columnRect)) fromView:self]; if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x) [self _moveColumn:_activeColumn toColumn:hoveredColumn]; else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x) [self _moveColumn:_activeColumn toColumn:hoveredColumn]; } - + _previousTrackingLocation = aPoint; } From b94174f9e1964247b75a1b1c5f74c02120d1936c Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Tue, 11 May 2010 19:43:01 -0500 Subject: [PATCH 30/54] Updated TableTest to provide a test case for tables that do not sit at (0,0) of a window. --- Tests/Manual/TableTest/AppController.j | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Tests/Manual/TableTest/AppController.j b/Tests/Manual/TableTest/AppController.j index 1e573389a..0c3d818f2 100644 --- a/Tests/Manual/TableTest/AppController.j +++ b/Tests/Manual/TableTest/AppController.j @@ -26,10 +26,10 @@ tableTestDragType = @"CPTableViewTestDragType"; dataSet3[i - 1] = [CPNumber numberWithInt:i+20]; } - var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(50,50,400,400) styleMask:CPClosableWindowMask], + var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(50,50,700,500) styleMask:CPClosableWindowMask], contentView = [theWindow contentView]; - tableView = [[CPTableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 500.0, 500.0)]; + tableView = [[CPTableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 400.0)]; [tableView setAllowsMultipleSelection:YES]; [tableView setAllowsColumnSelection:YES]; @@ -55,7 +55,7 @@ tableTestDragType = @"CPTableViewTestDragType"; var desc = [CPSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; - for (var i = 1; i <= 2; i++) + for (var i = 1; i <= 5; i++) { var column = [[CPTableColumn alloc] initWithIdentifier:String(i)]; [column setSortDescriptorPrototype:desc]; @@ -63,13 +63,15 @@ tableTestDragType = @"CPTableViewTestDragType"; [column setMinWidth:50.0]; [column setMaxWidth:500.0]; - [column setWidth:200.0]; + [column setWidth:75.0]; [column setEditable:YES]; [tableView addTableColumn:column]; } - var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([contentView bounds]), CGRectGetHeight([contentView bounds]))]; + // we offset this scrollview to make sure all the coordinates are calculated correctly + // bad things can happen when the tableview doesn't sit at (0,0) + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(200, 50, CGRectGetWidth([contentView bounds]) - 200, CGRectGetHeight([contentView bounds]) -200)]; [scrollView setDocumentView:tableView]; [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; @@ -384,4 +386,4 @@ tableTestDragType = @"CPTableViewTestDragType"; } } -@end \ No newline at end of file +@end From 4afa2bfada69d51ef4399ea65e56e2a57e06d03c Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Tue, 11 May 2010 23:20:02 -0700 Subject: [PATCH 31/54] clean up style issues --- AppKit/CPTableHeaderView.j | 101 +++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 3507b18ee..490c4cc34 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -36,7 +36,7 @@ { [self _init]; } - + return self; } @@ -44,7 +44,7 @@ { _textField = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(5, 1, CGRectGetWidth([self bounds]) - 10, CGRectGetHeight([self bounds]) - 1)]; [_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable]; - + [_textField setLineBreakMode:CPLineBreakByTruncatingTail]; [_textField setTextColor: [CPColor colorWithHexString: @"333333"]]; [_textField setFont:[CPFont boldSystemFontOfSize:12.0]]; @@ -137,7 +137,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)encodeWithCoder:(CPCoder)aCoder { [super encodeWithCoder:aCoder]; - + [aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey]; [aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey]; [aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey]; @@ -151,13 +151,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal CPPoint _previousTrackingLocation; int _activeColumn; int _pressedColumn; - + BOOL _isResizing; BOOL _isDragging; BOOL _isTrackingColumn; - + float _columnOldWidth; - + CPTableView _tableView @accessors(property=tableView); } @@ -167,11 +167,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _previousTrackingLocation = CPPointMakeZero(); _activeColumn = -1; _pressedColumn = -1; - + _isResizing = NO; _isDragging = NO; _isTrackingColumn = NO; - + _columnOldWidth = 0.0; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]]; @@ -196,10 +196,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { var headerRect = [self bounds], columnRect = [[self tableView] rectOfColumn:aColumnIndex]; - + headerRect.origin.x = CPRectGetMinX(columnRect); headerRect.size.width = CPRectGetWidth(columnRect); - + return headerRect; } @@ -223,13 +223,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal var headerView = [_tableView._tableColumns[_pressedColumn] headerView]; [headerView unsetThemeState:CPThemeStateHighlighted]; } - + if (column != -1) { var headerView = [_tableView._tableColumns[column] headerView]; [headerView setThemeState:CPThemeStateHighlighted]; } - + _pressedColumn = column; } @@ -242,13 +242,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { var type = [theEvent type], currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - + // Take the right columns resize tracking area into account currentLocation.x -= 5.0; var columnIndex = [self columnAtPoint:currentLocation], shouldResize = [self shouldResizeTableColumn:columnIndex at:CPPointMake(currentLocation.x + 5.0, currentLocation.y)]; - + if (type === CPLeftMouseUp) { if (shouldResize) @@ -257,10 +257,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { [[self tableView] _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]]; [self stopTrackingTableColumn:columnIndex at:currentLocation]; - + _isTrackingColumn = NO; } + [self _updateResizeCursor:[CPApp currentEvent]]; + _activeColumn = CPNotFound; return; } @@ -269,7 +271,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { if (columnIndex === -1) return; - + _mouseDownLocation = currentLocation; _activeColumn = columnIndex; @@ -297,12 +299,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal return; // Stop tracking the column, because it's being dragged } else [self startTrackingTableColumn:columnIndex at:currentLocation]; - + } else if (_isTrackingColumn && _pressedColumn !== -1) [self stopTrackingTableColumn:_activeColumn at:currentLocation]; } } - + _previousTrackingLocation = currentLocation; [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; } @@ -320,16 +322,16 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal offset = CPPointMakeZero(), view = [[self tableView] _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset], viewLocation = CPPointMakeZero(); - + viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); viewLocation.y = CPRectGetMinY(columnRect) + offset.y; - + [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent] pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES]; - + return NO; } - + return YES; } @@ -354,15 +356,15 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { var tableColumns = [[self tableView] tableColumns], columnIndex = [tableColumns count]; - + while (columnIndex--) { var tableColumn = [tableColumns objectAtIndex:columnIndex]; - + if (![tableColumn isHidden]) return [self headerRectOfColumn:columnIndex]; } - + return nil; } @@ -398,17 +400,17 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [[self tableView] moveColumn:aFromIndex toColumn:aToIndex]; _activeColumn = aToIndex; _pressedColumn = _activeColumn; - + [[self tableView] _setDraggedColumn:_activeColumn]; } - (void)draggedView:(CPView)aView beganAt:(CPPoint)aPoint { _isDragging = YES; - + [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:YES]; [[self tableView] _setDraggedColumn:_activeColumn]; - + [self setNeedsDisplay:YES]; } @@ -450,11 +452,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { _isDragging = NO; _isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached - + [[self tableView] _setDraggedColumn:-1]; [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; [self stopTrackingTableColumn:_activeColumn at:aLocation]; - + [self setNeedsDisplay:YES]; } @@ -462,7 +464,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { if (_isResizing) return YES; - + if (_isTrackingColumn) return NO; @@ -472,19 +474,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)startResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { _isResizing = YES; - + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; - + [tableColumn setDisableResizingPosting:YES]; [[self tableView] setDisableAutomaticResizing:YES]; } - (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; - - var newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; - + var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], + newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; + if (newWidth < [tableColumn minWidth]) [[CPCursor resizeRightCursor] set]; else if (newWidth > [tableColumn maxWidth]) @@ -493,7 +494,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { [self tableView]._lastColumnShouldSnap = NO; [tableColumn setWidth:newWidth]; - + [[CPCursor resizeLeftRightCursor] set]; [self setNeedsLayout]; [self setNeedsDisplay:YES]; @@ -506,7 +507,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; [tableColumn setDisableResizingPosting:NO]; [[self tableView] setDisableAutomaticResizing:NO]; - + _isResizing = NO; } @@ -522,12 +523,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil], mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y), overColumn = [self columnAtPoint:mouseOverLocation]; - + if (overColumn >= 0 && CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation)) { var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn], width = [tableColumn width]; - + if (width == [tableColumn minWidth]) [[CPCursor resizeRightCursor] set]; else if (width == [tableColumn maxWidth]) @@ -559,12 +560,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { var tableColumns = [_tableView tableColumns], count = [tableColumns count]; - + for (var i = 0; i < count; i++) { var column = [tableColumns objectAtIndex:i], headerView = [column headerView]; - + var frame = [self headerRectOfColumn:i]; frame.size.height -= 0.5; if (i > 0) @@ -572,9 +573,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal frame.origin.x += 0.5; frame.size.width -= 1; } - + [headerView setFrame:frame]; - + if([headerView superview] != self) [self addSubview:headerView]; } @@ -601,23 +602,23 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal var columnArrayIndex = 0, columnArrayCount = columnsArray.length, columnMaxX; - + CGContextBeginPath(context); for(; columnArrayIndex < columnArrayCount; columnArrayIndex++) { // grab each column rect and add vertical lines var columnIndex = columnsArray[columnArrayIndex], columnToStroke = [self headerRectOfColumn:columnIndex]; - + columnMaxX = CGRectGetMaxX(columnToStroke); - + CGContextMoveToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMinY(columnToStroke))); CGContextAddLineToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMaxY(columnToStroke))); } - + CGContextClosePath(context); CGContextStrokePath(context); - + if (_isDragging) { CGContextSetFillColor(context, [CPColor grayColor]); From 337f5d9e73dcfd622cae3ca15120629b66852e62 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Wed, 12 May 2010 08:53:50 -0700 Subject: [PATCH 32/54] Correctly handle targeted links in NativeHost. Reviewed by me. --- Tools/NativeHost/AppController.m | 1 + Tools/NativeHost/NativeHost.xcodeproj/project.pbxproj | 4 ++++ Tools/NativeHost/WebWindow.m | 1 + 3 files changed, 6 insertions(+) diff --git a/Tools/NativeHost/AppController.m b/Tools/NativeHost/AppController.m index aeb2362d3..e45c5d262 100644 --- a/Tools/NativeHost/AppController.m +++ b/Tools/NativeHost/AppController.m @@ -175,6 +175,7 @@ NSString *SERVER_USER = nil; [webView setUIDelegate:self]; [webView setFrameLoadDelegate:self]; [webView setResourceLoadDelegate:self]; + [webView setPolicyDelegate:self]; webViewWindow = [[NSWindow alloc] init]; diff --git a/Tools/NativeHost/NativeHost.xcodeproj/project.pbxproj b/Tools/NativeHost/NativeHost.xcodeproj/project.pbxproj index e32b30318..f7d2bbc37 100644 --- a/Tools/NativeHost/NativeHost.xcodeproj/project.pbxproj +++ b/Tools/NativeHost/NativeHost.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 9E43AC84104DB51400263989 /* WebScripObject+Objective-J.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E43AC83104DB51400263989 /* WebScripObject+Objective-J.m */; }; 9E44CA9D0FD798FE00860A54 /* NSURL+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E44CA9C0FD798FE00860A54 /* NSURL+Additions.m */; }; 9E4EBB4210892BDE0091C8E9 /* BridgedMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E4EBB4110892BDE0091C8E9 /* BridgedMethods.m */; }; + 9E52D2F9119B05EF00B831FC /* AppController+WebPolicyDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E52D2F8119B05EF00B831FC /* AppController+WebPolicyDelegate.m */; }; 9E535D05104F6F4900C119FA /* AppController+MainMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E535D04104F6F4900C119FA /* AppController+MainMenu.m */; }; 9E535D32104F73FB00C119FA /* MenuBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E535D31104F73FB00C119FA /* MenuBridge.m */; }; 9E535D37104F761F00C119FA /* MenuItemBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E535D36104F761F00C119FA /* MenuItemBridge.m */; }; @@ -55,6 +56,7 @@ 9E44CA9C0FD798FE00860A54 /* NSURL+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+Additions.m"; sourceTree = ""; }; 9E4EBB4010892BDE0091C8E9 /* BridgedMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BridgedMethods.h; sourceTree = ""; }; 9E4EBB4110892BDE0091C8E9 /* BridgedMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BridgedMethods.m; sourceTree = ""; }; + 9E52D2F8119B05EF00B831FC /* AppController+WebPolicyDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AppController+WebPolicyDelegate.m"; sourceTree = ""; }; 9E535D04104F6F4900C119FA /* AppController+MainMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AppController+MainMenu.m"; sourceTree = ""; }; 9E535D30104F73FB00C119FA /* MenuBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuBridge.h; sourceTree = ""; }; 9E535D31104F73FB00C119FA /* MenuBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MenuBridge.m; sourceTree = ""; }; @@ -106,6 +108,7 @@ 9ED96C881020072300D24B9C /* AppController+WebFrameLoadDelegate.m */, 9ED96C891020072300D24B9C /* AppController+WebResourceLoadDelegate.m */, 9ED96C871020072300D24B9C /* AppController+WebUIDelegate.m */, + 9E52D2F8119B05EF00B831FC /* AppController+WebPolicyDelegate.m */, 9EB99C940FD8968100AA94A2 /* AppController.h */, 9EB99C950FD8968100AA94A2 /* AppController.m */, 9EA1BEF5107E7EE500CDE684 /* Application.h */, @@ -297,6 +300,7 @@ ADCCEF6810D43C970055BDFD /* WebPasteboardProxy.m in Sources */, 9E43AC84104DB51400263989 /* WebScripObject+Objective-J.m in Sources */, 9E5D4F0D1090FB6E00E76B38 /* WebWindow.m in Sources */, + 9E52D2F9119B05EF00B831FC /* AppController+WebPolicyDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tools/NativeHost/WebWindow.m b/Tools/NativeHost/WebWindow.m index e49121417..631e73a72 100644 --- a/Tools/NativeHost/WebWindow.m +++ b/Tools/NativeHost/WebWindow.m @@ -110,6 +110,7 @@ CGEventRef headTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e [webView setUIDelegate:delegate]; [webView setFrameLoadDelegate:delegate]; [webView setResourceLoadDelegate:delegate]; + [webView setPolicyDelegate:delegate]; [webView setShouldCloseWithWindow:YES]; [shadowView addSubview:webView]; From 6384bed9cc128b62a2cb3132d31c6de8d1a51572 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Wed, 12 May 2010 09:45:58 -0700 Subject: [PATCH 33/54] Properly handle window.location= links as well. Reviewed by me. --- .../AppController+WebPolicyDelegate.m | 35 +++++++++++++++++++ Tools/NativeHost/AppController.h | 4 +++ Tools/NativeHost/AppController.m | 8 +++++ 3 files changed, 47 insertions(+) create mode 100644 Tools/NativeHost/AppController+WebPolicyDelegate.m diff --git a/Tools/NativeHost/AppController+WebPolicyDelegate.m b/Tools/NativeHost/AppController+WebPolicyDelegate.m new file mode 100644 index 000000000..209870a55 --- /dev/null +++ b/Tools/NativeHost/AppController+WebPolicyDelegate.m @@ -0,0 +1,35 @@ +// +// AppController+WebPolicyDelegate.m +// NativeHost +// +// Created by Francisco Tolmasky on 5/11/10. +// Copyright 2010 280 North, Inc. All rights reserved. +// + +#import "NSURL+Additions.h" +#import "AppController.h" + + +@implementation AppController (WebPolicyDelegate) + +- (void)webView:(WebView *)aWebView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)aRequest newFrameName:(NSString *)aFrameName decisionListener:(id < WebPolicyDecisionListener >)aListener +{ + [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]]; + [aListener ignore]; +} + +- (void)webView:(WebView *)aWebView decidePolicyForNavigationAction:(NSDictionary *)aDictionary request:(NSURLRequest *)aRequest frame:(WebFrame *)aWebFrame decisionListener:(id )aDecisionListener +{ + NSURL * requestURL = [aRequest URL]; + + if([aWebView mainFrame] != aWebFrame || + [[baseURL scheme] isEqualTo:[requestURL scheme]] && + ![baseURL host] || [[baseURL host] isEqualTo:[requestURL host]] && + ![baseURL port] || [[baseURL port] isEqualTo:[requestURL port]]) + return [aDecisionListener use]; + + [[NSWorkspace sharedWorkspace] openURL:[aDictionary objectForKey:WebActionOriginalURLKey]]; + [aDecisionListener ignore]; +} + +@end diff --git a/Tools/NativeHost/AppController.h b/Tools/NativeHost/AppController.h index ee59c24fe..0e245965b 100644 --- a/Tools/NativeHost/AppController.h +++ b/Tools/NativeHost/AppController.h @@ -27,8 +27,12 @@ extern NSString *SERVER_USER; NSFileHandle * stdinFileHandle; NSMutableAttributedString * loggedOutput; + + NSURL * baseURL; } +- (NSURL *)baseURL; + - (void)startServer; - (void)startCappuccinoApplication; diff --git a/Tools/NativeHost/AppController.m b/Tools/NativeHost/AppController.m index e45c5d262..da1204bbd 100644 --- a/Tools/NativeHost/AppController.m +++ b/Tools/NativeHost/AppController.m @@ -20,6 +20,7 @@ int SERVER_PORT = 9191; NSString *SERVER_PASSWORD = nil; NSString *SERVER_USER = nil; + @implementation AppController - (id)init @@ -139,6 +140,11 @@ NSString *SERVER_USER = nil; [stdinFileHandle readInBackgroundAndNotify]; } +- (NSURL *)baseURL +{ + return baseURL; +} + - (void)startCappuccinoApplication { NSString *initialURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NHInitialURL"]; @@ -152,10 +158,12 @@ NSString *SERVER_USER = nil; initialResource = @"Application/index.html"; initialURL = [[NSString stringWithFormat:@"file://%@/%@", [[NSBundle mainBundle] resourcePath], initialResource] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + baseURL = [[NSURL alloc] initWithString:@"file:///"]; } else if (prependServer) { initialURL = [NSString stringWithFormat:@"http://127.0.0.1:%d/%@", SERVER_PORT, initialURL]; + baseURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", SERVER_PORT]]; } NHLog(@"STARTUP", [initialURL description]); From d1ae1bd41f72c24578c3c204a83766ed7e73b379 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 12 May 2010 10:36:48 -0700 Subject: [PATCH 34/54] Menu window's should open in the same platform window as the view they are attached to. --- AppKit/CPMenu/CPMenu.j | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j index 1116437b7..687fb7045 100644 --- a/AppKit/CPMenu/CPMenu.j +++ b/AppKit/CPMenu/CPMenu.j @@ -747,6 +747,9 @@ var _CPMenuBarVisible = NO, } // Show it. + if ([CPPlatform isBrowser]) + [menuWindow setPlatformWindow:[[aView window] platformWindow]]; + [menuWindow orderFront:self]; // Track it. @@ -816,6 +819,9 @@ var _CPMenuBarVisible = NO, [menuWindow setFrameOrigin:CGRectIntersection(unconstrainedFrame, constraintRect).origin]; } + if ([CPPlatform isBrowser]) + [menuWindow setPlatformWindow:[[aView window] platformWindow]]; + [menuWindow orderFront:self]; [[_CPMenuManager sharedMenuManager] From d3161422db7b86c37c19548816e716f2c434e5cc Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Wed, 12 May 2010 17:14:25 -0500 Subject: [PATCH 35/54] Updated TableTest adding a checkbox as a dataview for a column. --- Tests/Manual/TableTest/AppController.j | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Tests/Manual/TableTest/AppController.j b/Tests/Manual/TableTest/AppController.j index 0c3d818f2..327c8aa18 100644 --- a/Tests/Manual/TableTest/AppController.j +++ b/Tests/Manual/TableTest/AppController.j @@ -99,6 +99,13 @@ tableTestDragType = @"CPTableViewTestDragType"; [tableView2 setDelegate:self]; [tableView2 setDataSource:self]; + + var checkBox = [[CPCheckBox alloc] initWithFrame:CGRectMake(5,3,24,24)], + checkBoxColumn = [[CPTableColumn alloc] initWithIdentifier:@"checkBox"]; + [checkBoxColumn setDataView:checkBox]; + + [tableView2 addTableColumn:checkBoxColumn]; + var desc = [CPSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; for (var i = 1; i <= 3; i++) { From 61d7fe04e84d1385e283f31b73ed37f02c94ae35 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Wed, 12 May 2010 18:43:56 -0500 Subject: [PATCH 36/54] If we tell the tableview not to draw a selection then we shouldn't draw it... --- AppKit/CPTableView.j | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index fdf194400..18f205602 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -86,7 +86,7 @@ CPTableViewSolidVerticalGridLineMask = 1 << 0; CPTableViewSolidHorizontalGridLineMask = 1 << 1; CPTableViewNoColumnAutoresizing = 0; -CPTableViewUniformColumnAutoresizingStyle = 1; +CPTableViewUniformColumnAutoresizingStyle = 1; // FIX ME: This is FUBAR CPTableViewSequentialColumnAutoresizingStyle = 2; CPTableViewReverseSequentialColumnAutoresizingStyle = 3; CPTableViewLastColumnOnlyAutoresizingStyle = 4; @@ -2459,6 +2459,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; - (void)highlightSelectionInClipRect:(CGRect)aRect { + if (_selectionHighlightStyle === CPTableViewDraggingDestinationFeedbackStyleNone) + return; + var context = [[CPGraphicsContext currentContext] graphicsPort], indexes = [], rectSelector = @selector(rectOfRow:); @@ -2488,9 +2491,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; if (!count) return; - var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1); - - var deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask); + var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1), + deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask); CGContextBeginPath(context); while (count--) From 9eab2071dced51194b698fab408c2055b13bf21e Mon Sep 17 00:00:00 2001 From: Scott Kyle Date: Tue, 9 Mar 2010 11:49:36 -0800 Subject: [PATCH 37/54] In CPImageView, performDragOperation: should return a BOOL --- AppKit/CPImageView.j | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AppKit/CPImageView.j b/AppKit/CPImageView.j index 234f74ceb..7d365f71f 100644 --- a/AppKit/CPImageView.j +++ b/AppKit/CPImageView.j @@ -365,7 +365,7 @@ var LEFT_SHADOW_INSET = 3.0, return _isEditable; } -- (void)performDragOperation:(CPDraggingInfo)aSender +- (BOOL)performDragOperation:(CPDraggingInfo)aSender { var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]]; @@ -374,6 +374,8 @@ var LEFT_SHADOW_INSET = 3.0, [self setImage:images[0]]; [self sendAction:[self action] to:[self target]]; } + + return YES; } @end From ee2f3614250b48b4e0821c0f66b2ec09c003ec60 Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Tue, 16 Feb 2010 14:33:12 +0100 Subject: [PATCH 38/54] Reimplemented setImageDimsWhenDisabled: on CPButton to only dim the image instead of the entire button --- AppKit/CPButton.j | 1 + AppKit/_CPImageAndTextView.j | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j index 8a602a607..00b898233 100644 --- a/AppKit/CPButton.j +++ b/AppKit/CPButton.j @@ -530,6 +530,7 @@ CPButtonStateMixed = CPThemeState("mixed"); [contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]]; [contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]]; [contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]]; + [contentView setDimsImage:[self hasThemeState:CPThemeStateDisabled] && _imageDimsWhenDisabled]; } } diff --git a/AppKit/_CPImageAndTextView.j b/AppKit/_CPImageAndTextView.j index 695598a4d..cee931360 100644 --- a/AppKit/_CPImageAndTextView.j +++ b/AppKit/_CPImageAndTextView.j @@ -63,6 +63,7 @@ var HORIZONTAL_MARGIN = 3.0, CPCellImagePosition _imagePosition; CPImageScaling _imageScaling; + BOOL _shouldDimImage; CPImage _image; CPString _text; @@ -211,6 +212,17 @@ var HORIZONTAL_MARGIN = 3.0, return _imageScaling; } +- (void)setDimsImage:(BOOL)shouldDim +{ + var shouldDimImage = !!shouldDimImage; + + if (_shouldDimImage !== shouldDimImage) + { + _shouldDimImage = shouldDim; + [self setNeedsLayout]; + } +} + - (void)setTextColor:(CPColor)aTextColor { if (_textColor === aTextColor) @@ -572,6 +584,11 @@ var HORIZONTAL_MARGIN = 3.0, imageHeight *= scale; } + if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature)) + imageStyle.filter = @"alpha(opacity=" + _shouldDimImage ? 35 : 100 + ")"; + else + imageStyle.opacity = _shouldDimImage ? 0.35 : 1.0; + _DOMImageElement.width = imageWidth; _DOMImageElement.height = imageHeight; imageStyle.width = MAX(imageWidth, 0) + "px"; From 13a5c7f215f220533e9bd4f4a8129f6110d68304 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 12 May 2010 16:50:58 -0700 Subject: [PATCH 39/54] indexOf is not a safe operation on arrays. --- Foundation/CPRunLoop.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Foundation/CPRunLoop.j b/Foundation/CPRunLoop.j index c5fde7b54..95ea272bd 100644 --- a/Foundation/CPRunLoop.j +++ b/Foundation/CPRunLoop.j @@ -271,7 +271,7 @@ var CPRunLoopLastNativeRunLoop = 0; // FIXME: Hack for not doing this in CommonJS - if (CFBundle.environments().indexOf("Browser") !== -1) + if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound) { if (!_runLoopInsuranceTimer) _runLoopInsuranceTimer = window.setNativeTimeout(function() @@ -293,7 +293,7 @@ var CPRunLoopLastNativeRunLoop = 0; _runLoopLock = YES; // FIXME: Hack for not doing this in CommonJS - if (CFBundle.environments().indexOf("Browser") !== -1) + if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound) { if (_runLoopInsuranceTimer) { From c31786c4c1f12bc62822020cc6123d5a9b6a09d8 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Wed, 12 May 2010 19:01:28 -0500 Subject: [PATCH 40/54] Refactored autoresizing --- AppKit/CPTableView.j | 77 +++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index 18f205602..75e096ce5 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -1283,68 +1283,63 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; return _CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow)); } -//FIX ME: We should refactor this! - (void)resizeWithOldSuperviewSize:(CGSize)aSize { [super resizeWithOldSuperviewSize:aSize]; - + if (_disableAutomaticResizing) return; var mask = _columnAutoResizingStyle; if(mask === CPTableViewUniformColumnAutoresizingStyle) - { [self _resizeAllColumnUniformlyWithOldSize:aSize]; - } - - if(mask === CPTableViewLastColumnOnlyAutoresizingStyle) - { + else if(mask === CPTableViewLastColumnOnlyAutoresizingStyle) [self sizeLastColumnToFit]; - } + else if(mask === CPTableViewFirstColumnOnlyAutoresizingStyle) + [self _autoResizeFirstColumn]; +} - if(mask === CPTableViewFirstColumnOnlyAutoresizingStyle) - { - var superview = [self superview]; +- (void)_autoResizeFirstColumn +{ + var superview = [self superview]; - if (!superview) - return; + if (!superview) + return; - var superviewSize = [superview bounds].size; + var superviewSize = [superview bounds].size; - UPDATE_COLUMN_RANGES_IF_NECESSARY(); + UPDATE_COLUMN_RANGES_IF_NECESSARY(); - var count = NUMBER_OF_COLUMNS(); + var count = NUMBER_OF_COLUMNS(), + visColumns = [[CPArray alloc] init], + totalWidth = 0, + i = 0; - var visColumns = [[CPArray alloc] init]; - var totalWidth = 0; + for(; i < count; i++) + { + if(![_tableColumns[i] isHidden]) + { + [visColumns addObject:i]; + totalWidth += [_tableColumns[i] width]; + } + } - for(var i=0; i < count; i++) - { - if(![_tableColumns[i] isHidden]) - { - [visColumns addObject:i]; - totalWidth += [_tableColumns[i] width]; - } - } + count = [visColumns count]; - count = [visColumns count]; + //if there are rows + if (count > 0) + { + var columnToResize = _tableColumns[visColumns[0]]; + var newWidth = superviewSize.width - totalWidth;// - [columnToResize width]; + newWidth += [columnToResize width]; + newWidth = (newWidth < [columnToResize minWidth]) ? [columnToResize minWidth] : newWidth; + newWidth = (newWidth > [columnToResize maxWidth]) ? [columnToResize maxWidth] : newWidth; - //if there are rows - if (count > 0) - { - var columnToResize = _tableColumns[visColumns[0]]; - var newWidth = superviewSize.width - totalWidth;// - [columnToResize width]; - newWidth += [columnToResize width]; - newWidth = (newWidth < [columnToResize minWidth]) ? [columnToResize minWidth] : newWidth; - newWidth = (newWidth > [columnToResize maxWidth]) ? [columnToResize maxWidth] : newWidth; - - [columnToResize setWidth:FLOOR(newWidth)]; - } - - [self setNeedsLayout]; - } + [columnToResize setWidth:FLOOR(newWidth)]; + } + [self setNeedsLayout]; } - (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize From e0a3a683a510d517f4854c79c4bf10ea21e4ec3a Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Wed, 12 May 2010 19:44:07 -0500 Subject: [PATCH 41/54] access ivars directly from within CPTableHeaderView class. --- AppKit/CPTableHeaderView.j | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 490c4cc34..073db4e72 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -195,7 +195,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (CGRect)headerRectOfColumn:(int)aColumnIndex { var headerRect = [self bounds], - columnRect = [[self tableView] rectOfColumn:aColumnIndex]; + columnRect = [_tableView rectOfColumn:aColumnIndex]; headerRect.origin.x = CPRectGetMinX(columnRect); headerRect.size.width = CPRectGetWidth(columnRect); @@ -255,7 +255,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [self stopResizingTableColumn:_activeColumn at:currentLocation]; else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation]) { - [[self tableView] _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]]; + [_tableView _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]]; [self stopTrackingTableColumn:columnIndex at:currentLocation]; _isTrackingColumn = NO; @@ -275,7 +275,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _mouseDownLocation = currentLocation; _activeColumn = columnIndex; - [[self tableView] _sendDelegateDidMouseDownInHeader:columnIndex]; + [_tableView _sendDelegateDidMouseDownInHeader:columnIndex]; if (shouldResize) [self startResizingTableColumn:columnIndex at:currentLocation]; @@ -320,7 +320,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal { var columnRect = [self headerRectOfColumn:aColumnIndex], offset = CPPointMakeZero(), - view = [[self tableView] _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset], + view = [_tableView _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset], viewLocation = CPPointMakeZero(); viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x ); @@ -349,12 +349,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - return [[self tableView] allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; + return [_tableView allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0; } - (CPRect)_headerRectOfLastVisibleColumn { - var tableColumns = [[self tableView] tableColumns], + var tableColumns = [_tableView tableColumns], columnIndex = [tableColumns count]; while (columnIndex--) @@ -370,7 +370,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint { - var tableColumns = [[self tableView] tableColumns], + var tableColumns = [_tableView tableColumns], lastColumnRect = [self _headerRectOfLastVisibleColumn]; activeColumnRect = [self headerRectOfColumn:_activeColumn]; dragWindow = [theDragView window], @@ -397,19 +397,19 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex { - [[self tableView] moveColumn:aFromIndex toColumn:aToIndex]; + [_tableView moveColumn:aFromIndex toColumn:aToIndex]; _activeColumn = aToIndex; _pressedColumn = _activeColumn; - [[self tableView] _setDraggedColumn:_activeColumn]; + [_tableView _setDraggedColumn:_activeColumn]; } - (void)draggedView:(CPView)aView beganAt:(CPPoint)aPoint { _isDragging = YES; - [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:YES]; - [[self tableView] _setDraggedColumn:_activeColumn]; + [[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:YES]; + [_tableView _setDraggedColumn:_activeColumn]; [self setNeedsDisplay:YES]; } @@ -453,8 +453,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal _isDragging = NO; _isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached - [[self tableView] _setDraggedColumn:-1]; - [[[[[self tableView] tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; + [_tableView _setDraggedColumn:-1]; + [[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO]; [self stopTrackingTableColumn:_activeColumn at:aLocation]; [self setNeedsDisplay:YES]; @@ -468,22 +468,22 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal if (_isTrackingColumn) return NO; - return [[self tableView] allowsColumnResizing] && CPRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint); + return [_tableView allowsColumnResizing] && CPRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint); } - (void)startResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { _isResizing = YES; - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex]; [tableColumn setDisableResizingPosting:YES]; - [[self tableView] setDisableAutomaticResizing:YES]; + [_tableView setDisableAutomaticResizing:YES]; } - (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex], + var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex], newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x; if (newWidth < [tableColumn minWidth]) @@ -492,7 +492,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal [[CPCursor resizeLeftCursor] set]; else { - [self tableView]._lastColumnShouldSnap = NO; + _tableView._lastColumnShouldSnap = NO; [tableColumn setWidth:newWidth]; [[CPCursor resizeLeftRightCursor] set]; @@ -503,10 +503,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal - (void)stopResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint { - var tableColumn = [[[self tableView] tableColumns] objectAtIndex:aColumnIndex]; + var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex]; [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; [tableColumn setDisableResizingPosting:NO]; - [[self tableView] setDisableAutomaticResizing:NO]; + [_tableView setDisableAutomaticResizing:NO]; _isResizing = NO; } From 23b76874df61717c57d1a6afc26a34921d6741fd Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 12 May 2010 18:21:46 -0700 Subject: [PATCH 42/54] A few IE fixes for web view. --- AppKit/CPWebView.j | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AppKit/CPWebView.j b/AppKit/CPWebView.j index 9da31436e..a198c0214 100644 --- a/AppKit/CPWebView.j +++ b/AppKit/CPWebView.j @@ -110,6 +110,7 @@ CPWebViewScrollNative = 2; _iframe.style.width = "100%"; _iframe.style.height = "100%"; _iframe.style.borderWidth = "0px"; + _iframe.frameBorder = "0"; [self setDrawsBackground:YES]; @@ -245,7 +246,10 @@ CPWebViewScrollNative = 2; - (void)_setScrollMode:(int)aScrollMode { - _scrollMode = aScrollMode; + if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine)) + _scrollMode = CPWebViewScrollNative; + else + _scrollMode = aScrollMode; _ignoreLoadStart = YES; _ignoreLoadEnd = YES; From ac81ab458cf26aa63b8a46906421e2ffba1c8f60 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Wed, 12 May 2010 18:41:14 -0700 Subject: [PATCH 43/54] Fix for same html appearing multiple times in CPWebView when using loadHTMLString: many times in succession. Reviewed by me. --- AppKit/CPWebView.j | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/AppKit/CPWebView.j b/AppKit/CPWebView.j index a198c0214..bf36a7773 100644 --- a/AppKit/CPWebView.j +++ b/AppKit/CPWebView.j @@ -69,11 +69,13 @@ CPWebViewScrollNative = 2; CPString _url; CPString _html; - + Function _loadCallback; - + int _scrollMode; CGSize _scrollSize; + + int _loadHTMLStringTimer; } - (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName @@ -327,8 +329,15 @@ CPWebViewScrollNative = 2; // clear the iframe _iframe.src = ""; + if (_loadHTMLStringTimer !== nil) + { + window.clearTimeout(_loadHTMLStringTimer); + _loadHTMLStringTimer = nil; + } + // need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document - window.setTimeout(function() { + _loadHTMLStringTimer = window.setTimeout(function() + { var win = [self DOMWindow]; win.document.write(_html); From 80b70ec6b98b57cde1ba57bae385e7142de49055 Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Wed, 12 May 2010 19:08:30 -0700 Subject: [PATCH 44/54] Can't sprited resources whos resulting dataURL is larger than 32k, not resources which themselves are over 32k. --- Objective-J/CommonJS/lib/objective-j/jake/bundletask.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js b/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js index 9cf34552b..13e3d7a8b 100644 --- a/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js +++ b/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js @@ -453,7 +453,9 @@ BundleTask.prototype.resourcesPath = function() // Don't sprite images larger than 32KB, IE 8 doesn't like it. BundleTask.isSpritable = function(aResourcePath) { - return isImage(aResourcePath) && FILE.size(aResourcePath) < 32768; + return isImage(aResourcePath) && FILE.size(aResourcePath) < 32768 && + ("data:" + mimeType(aResourcePath) + ";base64," + + base64.encode(FILE.read(aResourcePath, "b"))).length < 32768; } BundleTask.prototype.defineResourceTask = function(aResourcePath, aDestinationPath) From 5a89dfe8f4dd643ffa6cfdc35b18ded9cfaa3372 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Wed, 12 May 2010 19:22:31 -0700 Subject: [PATCH 45/54] Fix for identifying when we can use platform windows. Reviewed by me. --- AppKit/Platform/CPPlatformWindow.j | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j index 1a31d068f..a0f46cc52 100644 --- a/AppKit/Platform/CPPlatformWindow.j +++ b/AppKit/Platform/CPPlatformWindow.j @@ -74,6 +74,15 @@ var PrimaryPlatformWindow = NULL; return [CPSet set]; } ++ (BOOL)supportsMultipleInstances +{ +#if PLATFORM(DOM) + return !CPBrowserIsEngine(CPInternetExplorerBrowserEngine); +#else + return NO; +#endif +} + + (CPPlatformWindow)primaryPlatformWindow { return PrimaryPlatformWindow; From fc8525e4d8861a23f4281ebcf6b34d59bfb66a24 Mon Sep 17 00:00:00 2001 From: Paul Baumgart Date: Mon, 10 May 2010 18:11:19 -0700 Subject: [PATCH 46/54] throw a regular Error() exception in Runtime.js because objj_exception doesn't exist anymore --- Objective-J/Runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index fda9ad563..1df7ab26f 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -386,7 +386,7 @@ DISPLAY_NAME(objj_registerClassPair); GLOBAL(class_createInstance) = function(/*Class*/ aClass) { if (!aClass) - objj_exception_throw(new objj_exception(OBJJNilClassException, "*** Attempting to create object with Nil class.")); + throw new Error("*** Attempting to create object with Nil class."); var object = new aClass.allocator(); From bc5a21d54500b5ac5cbb1d2535eb447b287c99a7 Mon Sep 17 00:00:00 2001 From: Paul Baumgart Date: Mon, 10 May 2010 18:20:48 -0700 Subject: [PATCH 47/54] Change objj_exception_throw to manually throw an exception, because objj_exception_throw doesn't exist anymore. --- Foundation/CPNumber.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Foundation/CPNumber.j b/Foundation/CPNumber.j index 3b95e242d..8712b2ac2 100644 --- a/Foundation/CPNumber.j +++ b/Foundation/CPNumber.j @@ -217,14 +217,14 @@ FIXME: Do we need this? */ - (CPDecimal)decimalValue { - objj_throw_exception("decimalValue: NOT YET IMPLEMENTED"); + throw new Error("decimalValue: NOT YET IMPLEMENTED"); } - (CPString)descriptionWithLocale:(CPDictionary)aDictionary { if (!aDictionary) return toString(); - objj_throw_exception("descriptionWithLocale: NOT YET IMPLEMENTED"); + throw new Error("descriptionWithLocale: NOT YET IMPLEMENTED"); } - (CPString)description From 66180f8de49a7f79a16177eb7df5b1f99d97a2a5 Mon Sep 17 00:00:00 2001 From: Paul Baumgart Date: Mon, 10 May 2010 14:55:49 -0700 Subject: [PATCH 48/54] change @property to @accessors in pre-processor error messages --- Objective-J/Preprocessor.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Objective-J/Preprocessor.js b/Objective-J/Preprocessor.js index b95b4e61b..d66d47144 100644 --- a/Objective-J/Preprocessor.js +++ b/Objective-J/Preprocessor.js @@ -244,19 +244,19 @@ Preprocessor.prototype.accessors = function(tokens) value = true; if (!IS_WORD(name)) - throw new SyntaxError(this.error_message("*** @property attribute name not valid.")); + throw new SyntaxError(this.error_message("*** @accessors attribute name not valid.")); if ((token = tokens.skip_whitespace()) == TOKEN_EQUAL) { value = tokens.skip_whitespace(); if (!IS_WORD(value)) - throw new SyntaxError(this.error_message("*** @property attribute value not valid.")); + throw new SyntaxError(this.error_message("*** @accessors attribute value not valid.")); if (name == "setter") { if ((token = tokens.next()) != TOKEN_COLON) - throw new SyntaxError(this.error_message("*** @property setter attribute requires argument with \":\" at end of selector name.")); + throw new SyntaxError(this.error_message("*** @accessors setter attribute requires argument with \":\" at end of selector name.")); value += ":"; } @@ -270,7 +270,7 @@ Preprocessor.prototype.accessors = function(tokens) break; if (token != TOKEN_COMMA) - throw new SyntaxError(this.error_message("*** Expected ',' or ')' in @property attribute list.")); + throw new SyntaxError(this.error_message("*** Expected ',' or ')' in @accessors attribute list.")); } return attributes; From fddcde757f6944aa61b9144f2b4b0b6476aa41cc Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Sat, 15 May 2010 12:22:29 -0700 Subject: [PATCH 49/54] Add a more specific cache header. Closes #649. --- Foundation/CPURLRequest.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Foundation/CPURLRequest.j b/Foundation/CPURLRequest.j index 5d6b7fc9b..b18b9bd81 100644 --- a/Foundation/CPURLRequest.j +++ b/Foundation/CPURLRequest.j @@ -68,7 +68,7 @@ _HTTPMethod = @"GET"; _HTTPHeaderFields = [CPDictionary dictionary]; - [self setValue:"Thu, 1 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"]; + [self setValue:"Thu, 01 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"]; [self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"]; [self setValue:"XMLHttpRequest" forHTTPHeaderField:"X-Requested-With"]; } From 791e65c88b838e78bb29d132cf3e73dee2ceeb27 Mon Sep 17 00:00:00 2001 From: Alexander Ljungberg Date: Fri, 30 Apr 2010 15:11:28 -0400 Subject: [PATCH 50/54] Improved CPArray sortUsingDescriptors performance by about 3% by pulling the descriptor count out of the sort function. --- Foundation/CPArray.j | 13 ++++--- Tests/Foundation/CPArrayPerformance.j | 56 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 Tests/Foundation/CPArrayPerformance.j diff --git a/Foundation/CPArray.j b/Foundation/CPArray.j index e26731db4..4e22b591a 100755 --- a/Foundation/CPArray.j +++ b/Foundation/CPArray.j @@ -490,10 +490,11 @@ */ - (unsigned)indexOfObject:(id)anObject sortedByDescriptors:(CPArray)descriptors { + var count = [descriptors count]; + return [self indexOfObject:anObject sortedByFunction:function(lhs, rhs) { var i = 0, - count = [descriptors count], result = CPOrderedSame; while (i < count) @@ -971,21 +972,22 @@ - (unsigned)insertObject:(id)anObject inArraySortedByDescriptors:(CPArray)descriptors { + var count = [descriptors count]; + var index = [self _indexOfObject:anObject sortedByFunction:function(lhs, rhs) { var i = 0, - count = [descriptors count], result = CPOrderedSame; while (i < count) - if ((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame) + if((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame) return result; return result; } context:nil]; if (index < 0) - index = -index - 1; + index = -index-1; [self insertObject:anObject atIndex:index]; return index; @@ -1191,10 +1193,11 @@ - (CPArray)sortUsingDescriptors:(CPArray)descriptors { + var count = [descriptors count]; + sort(function(lhs, rhs) { var i = 0, - count = [descriptors count], result = CPOrderedSame; while (i < count) diff --git a/Tests/Foundation/CPArrayPerformance.j b/Tests/Foundation/CPArrayPerformance.j new file mode 100644 index 000000000..a41c16dce --- /dev/null +++ b/Tests/Foundation/CPArrayPerformance.j @@ -0,0 +1,56 @@ +@import +@import +@import +@import + +@implementation CPArrayPerformance : OJTestCase + +- (void)testSortUsingDescriptorsSpeed +{ + + var ELEMENTS = 1000, + REPEATS = 10, + array = []; + for (var i=0; i Date: Mon, 10 May 2010 22:17:52 -0400 Subject: [PATCH 51/54] Added documentation in the form of source code comments; verified using doxygen and the included recipe file. --- AppKit/CPAccordionView.j | 41 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/AppKit/CPAccordionView.j b/AppKit/CPAccordionView.j index c9bcf71a7..ec1798a67 100644 --- a/AppKit/CPAccordionView.j +++ b/AppKit/CPAccordionView.j @@ -30,7 +30,12 @@ #import "CoreGraphics/CGGeometry.h" - +/*! + @ingroup appkit + @class CPAccordionViewItem + +

A CPAccordionViewItem represents a single section of a CPAccordionView.

+*/ @implementation CPAccordionViewItem : CPObject { CPString _identifier @accessors(property=identifier); @@ -43,6 +48,10 @@ return [self initWithIdentifier:@""]; } +/*! + Initializes a new CPAccordionViewItem with the specified identifier. This identifier may + then be used in subsequent methods to provide abstract introspection of the CPAccordionView. +*/ - (id)initWithIdentifier:(CPString)anIdentifier { self = [super init]; @@ -55,6 +64,25 @@ @end +/*! + @ingroup appkit + @class CPAccordionView + +

CPAccordionView provides a container for CPAccordionViewItem objects and manages layout state + for all sublayout items.

+ + Example
+
+var myAccordionView = [[CPAccordionView alloc] initWithFrame:CGRectMakeZero()];
+var firstItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"firstSection"]];
+[firstItem setView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
+var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection"]];
+[secondItem setView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
+[myAccordionView addItem:firstItem];
+[myAccordionView addItem:secondItem];
+[myAccordionView setAutoresizingMask: CPViewWidthSizable | CPViewHeightSizable];
+  
+*/ @implementation CPAccordionView : CPView { CPInteger _dirtyItemIndex; @@ -64,7 +92,10 @@ CPMutableArray _itemViews; CPIndexSet _expandedItemIndexes; } - +/*! + Initializes the receiver for usage with the specified bounding rectangle + @return the initialized view +*/ - (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; @@ -95,7 +126,11 @@ { return _items; } - +/*! + Append a CPAccordionViewItem to the receiver. Note that the CPAccordionViewItem must contain + a valid CPView derived component or a TypeError will be generated when the contents of the + ViewItem are disclosed. +*/ - (void)addItem:(CPAccordionViewItem)anItem { [self insertItem:anItem atIndex:_items.length]; From 4520715b5bf92794cf2504dab54e3e7922655ce4 Mon Sep 17 00:00:00 2001 From: Saikat Chakrabarti Date: Thu, 8 Apr 2010 20:38:34 -0700 Subject: [PATCH 52/54] Making CPURLConnection authentication challenges happen before the delegate gets a response --- Foundation/CPURLConnection.j | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/Foundation/CPURLConnection.j b/Foundation/CPURLConnection.j index 0d8c7b2a7..368173e34 100644 --- a/Foundation/CPURLConnection.j +++ b/Foundation/CPURLConnection.j @@ -238,24 +238,22 @@ var CPURLConnectionDelegate = nil; var statusCode = _HTTPRequest.status(), URL = [_request URL]; - if ([_delegate respondsToSelector:@selector(connection:didReceiveResponse:)]) + if (statusCode === 401 && [CPURLConnectionDelegate respondsToSelector:@selector(connectionDidReceiveAuthenticationChallenge:)]) + [CPURLConnectionDelegate connectionDidReceiveAuthenticationChallenge:self]; + else { - if (_isLocalFileConnection) - [_delegate connection:self didReceiveResponse:[[CPURLResponse alloc] initWithURL:URL]]; - else - { - var response = [[CPHTTPURLResponse alloc] initWithURL:URL]; - - [response _setStatusCode:statusCode]; - - [_delegate connection:self didReceiveResponse:response]; + if ([_delegate respondsToSelector:@selector(connection:didReceiveResponse:)]) + { + if (_isLocalFileConnection) + [_delegate connection:self didReceiveResponse:[[CPURLResponse alloc] initWithURL:URL]]; + else + { + var response = [[CPHTTPURLResponse alloc] initWithURL:URL]; + [response _setStatusCode:statusCode]; + [_delegate connection:self didReceiveResponse:response]; + } } - } - if (!_isCanceled) - { - if (statusCode === 401 && [CPURLConnectionDelegate respondsToSelector:@selector(connectionDidReceiveAuthenticationChallenge:)]) - [CPURLConnectionDelegate connectionDidReceiveAuthenticationChallenge:self]; - else + if (!_isCanceled) { if ([_delegate respondsToSelector:@selector(connection:didReceiveData:)]) [_delegate connection:self didReceiveData:_HTTPRequest.responseText()]; From 61b9c7a1eea8429c678f1a467acd5d1431fa3330 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sun, 16 May 2010 13:19:28 -0500 Subject: [PATCH 53/54] Moved depreciated CPGeometry methods to CGGeomotry and fixed the filename in the header. --- AppKit/CPViewAnimation.j | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/AppKit/CPViewAnimation.j b/AppKit/CPViewAnimation.j index 692523584..feb6884c0 100644 --- a/AppKit/CPViewAnimation.j +++ b/AppKit/CPViewAnimation.j @@ -1,5 +1,5 @@ /* - * CPFlashView.j + * CPViewAnimation.j * AppKit * * Created by Klaas Pieter Annema on September 3, 2009. @@ -22,6 +22,8 @@ @import +#include "CoreGraphics/CGGeometry.h" + CPViewAnimationTargetKey = @"CPViewAnimationTarget"; CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrame"; CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrame"; @@ -80,14 +82,14 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut"; view = [self _targetView:dictionary] startFrame = [self _startFrame:dictionary] endFrame = [self _endFrame:dictionary] - differenceFrame = CPRectMakeZero(); + differenceFrame = _CGRectMakeZero(); differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x; differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y; differenceFrame.size.width = endFrame.size.width - startFrame.size.width; differenceFrame.size.height = endFrame.size.height - startFrame.size.height; - var intermediateFrame = CPRectMakeZero(); + var intermediateFrame = _CGRectMakeZero(); intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress; intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress; intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress; @@ -103,7 +105,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut"; [view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress]; if (progress === 1.0) - [view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0]; + [view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0]; } } @@ -124,7 +126,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut"; else if (effect === CPViewAnimationFadeOutEffect) [view setAlphaValue:0.0]; - [view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0]; + [view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0]; } [super stopAnimation]; @@ -139,7 +141,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut"; return targetView; } -- (CPRect)_startFrame:(CPDictionary)dictionary +- (CGRect)_startFrame:(CPDictionary)dictionary { var startFrame = [dictionary valueForKey:CPViewAnimationStartFrameKey]; if (!startFrame) @@ -148,7 +150,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut"; return startFrame; } -- (CPRect)_endFrame:(CPDictionary)dictionary +- (CGRect)_endFrame:(CPDictionary)dictionary { var endFrame = [dictionary valueForKey:CPViewAnimationEndFrameKey]; if (!endFrame) From 202243f7111234928bc5b7c05427fab855ab4270 Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sun, 16 May 2010 13:41:09 -0500 Subject: [PATCH 54/54] fixed typo in CPViewAnimation. --- AppKit/CPViewAnimation.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/CPViewAnimation.j b/AppKit/CPViewAnimation.j index feb6884c0..b1bc4d414 100644 --- a/AppKit/CPViewAnimation.j +++ b/AppKit/CPViewAnimation.j @@ -71,7 +71,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut"; [super startAnimation]; } -- (void)setCurrentProgress:(NSAnimationProgress)progress +- (void)setCurrentProgress:(CPAnimationProgress)progress { [super setCurrentProgress:progress];