* Source/NSTableView.m: Add new private methods.

(-mouseDown:): Reorganize and don't track cells until dragging
        has been ruled out.
        * Source/NSCell.m (trackMouse:inRect:ofView:untilMouseUp:):
        Handle events no longer in the queue.
        * Source/GSDragView.m: Change NSLog to NSDebugLLog.



git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@24007 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Matt Rice 2006-11-01 09:50:00 +00:00
parent 1a7c5c309c
commit 3d20848a26
4 changed files with 178 additions and 131 deletions

View file

@ -1,3 +1,12 @@
2006-11-01 Matt Rice <ratmice@yahoo.com>
* Source/NSTableView.m: Add new private methods.
(-mouseDown:): Reorganize and don't track cells until dragging
has been ruled out.
* Source/NSCell.m (trackMouse:inRect:ofView:untilMouseUp:):
Handle events no longer in the queue.
* Source/GSDragView.m: Change NSLog to NSDebugLLog.
2006-10-31 Matt Rice <ratmice@yahoo.com>
* Tools/gopen.m

View file

@ -756,7 +756,7 @@ static GSDragView *sharedDragView = nil;
break;
default:
NSLog(@"Internal: dropped NSAppKitDefined (%d) event", sub);
NSDebugLLog(@"NSDragging", @"dropped NSAppKitDefined (%d) event", sub);
break;
}
}

View file

@ -1548,15 +1548,19 @@ static NSColor *shadowCol;
NSDebugLLog(@"NSCell", @"cell get mouse events\n");
mouseWentUp = NO;
done = NO;
if (theEvent != [NSApp currentEvent])
theEvent = [NSApp currentEvent];
else
theEvent = [theApp nextEventMatchingMask: event_mask
untilDate: nil
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
while (!done)
{
NSEventType eventType;
BOOL pointIsInCell;
theEvent = [theApp nextEventMatchingMask: event_mask
untilDate: nil
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
eventType = [theEvent type];
if (eventType != NSPeriodic || periodCount == 4)
@ -1626,6 +1630,12 @@ static NSColor *shadowCol;
&& (_action_mask & NSPeriodicMask))))
[(NSControl*)controlView sendAction: action to: target];
}
if (!done)
theEvent = [theApp nextEventMatchingMask: event_mask
untilDate: nil
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
}
// Hook called when stop tracking

View file

@ -146,7 +146,10 @@ typedef struct _tableViewFlags
- (void) _unselectAllColumns;
@end
@interface NSTableView (EventLoopHelper)
- (void) _trackCellAtColumn:(int)column row:(int)row withEvent:(NSEvent *)ev;
- (BOOL) _startDragOperationWithEvent:(NSEvent *)theEvent;
@end
/*
* A specific struct and its associated quick sort function
@ -3341,11 +3344,114 @@ static inline float computePeriod(NSPoint mouseLocationWin,
return 0.01;
}
- (void) _trackCellAtColumn:(int)columnIndex
row:(int)rowIndex
withEvent:(NSEvent *)theEvent
{
NSTableColumn *tb;
NSCell *cell;
NSRect cellFrame;
id originalValue;
if (rowIndex == -1 || columnIndex == -1)
{
return;
}
tb = [_tableColumns objectAtIndex: columnIndex];
/* we should copy the cell here, as we do on editing.
otherwise validation on a cell being edited could
cause the cell we are selecting to get it's objectValue */
cell = [[tb dataCellForRow: rowIndex] copy];
originalValue = RETAIN([self _objectValueForTableColumn:tb
row:rowIndex]);
[cell setObjectValue: originalValue];
cellFrame = [self frameOfCellAtColumn: columnIndex
row: rowIndex];
[cell setHighlighted: YES];
[self setNeedsDisplayInRect: cellFrame];
/* give delegate a chance to i.e set target */
[self _willDisplayCell: cell
forTableColumn: tb
row: rowIndex];
if ([cell trackMouse: theEvent
inRect: cellFrame
ofView: self
untilMouseUp:[[cell class]
prefersTrackingUntilMouseUp]])
{
id newValue = [cell objectValue];
if ([tb isEditable]
&& originalValue != newValue
&& ![originalValue isEqual: newValue])
{
[self _setObjectValue: newValue
forTableColumn: tb
row: rowIndex];
}
}
RELEASE(originalValue);
[cell setHighlighted: NO];
[self setNeedsDisplayInRect: cellFrame];
RELEASE(cell);
}
- (BOOL) _startDragOperationWithEvent:(NSEvent *)theEvent
{
NSPasteboard *pboard;
NSArray *rows;
rows = [self _selectedRowArray];
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
if ([self _writeRows: rows
toPasteboard: pboard] == YES)
{
NSPoint p = NSZeroPoint;
NSImage *dragImage;
NSSize s;
dragImage = [self dragImageForRows: rows
event: theEvent
dragImageOffset: &p];
/*
* Store image offset in s ... the returned
* value is the position of the center of
* the image, so we adjust to the bottom left
* corner.
*/
s = [dragImage size];
s.width = p.x - s.width/2;
s.height = p.y + s.height/2; // View is flipped
/*
* Find the current mouse location and adjust
* it to determine the location of the bottom
* left corner of the image in this view's
* coordinate system.
*/
p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
p.x += s.width;
p.y += s.height;
[self dragImage: dragImage
at: p
offset: NSMakeSize(0, 0)
event: theEvent
pasteboard: pboard
source: self
slideBack: YES];
return YES;
}
return NO;
}
- (void) mouseDown: (NSEvent *)theEvent
{
NSPoint initialLocation = [theEvent locationInWindow];
NSPoint location;
int clickCount;
// Pathological case -- ignore mouse down
if ((_numberOfRows == 0) || (_numberOfColumns == 0))
@ -3353,12 +3459,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
return;
}
clickCount = [theEvent clickCount];
if (clickCount > 2)
{
return;
}
/* Stop editing if any */
if (_textObject != nil)
{
@ -3370,8 +3470,9 @@ static inline float computePeriod(NSPoint mouseLocationWin,
location = [self convertPoint: initialLocation fromView: nil];
_clickedRow = [self rowAtPoint: location];
_clickedColumn = [self columnAtPoint: location];
if (clickCount == 2)
if ([theEvent type] == NSLeftMouseDown
&& [theEvent clickCount] > 1)
{
// Double-click event
@ -3383,14 +3484,19 @@ static inline float computePeriod(NSPoint mouseLocationWin,
if (![self _isCellEditableColumn: _clickedColumn row: _clickedRow ])
{
// Send double-action but don't edit
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
if (_clickedRow != -1)
[self sendAction: _doubleAction to: _target];
}
else
{
// It is OK to edit column. Go on, do it.
[self editColumn: _clickedColumn row: _clickedRow
withEvent: theEvent select: YES];
[self editColumn: _clickedColumn
row: _clickedRow
withEvent: theEvent
select: YES];
}
}
else
@ -3401,7 +3507,7 @@ static inline float computePeriod(NSPoint mouseLocationWin,
| NSLeftMouseDownMask
| NSLeftMouseDraggedMask
| NSPeriodicMask);
unsigned selectionMode;
unsigned selectionMode = 0;
NSPoint mouseLocationWin;
NSPoint mouseLocationView;
NSDate *distantFuture = [NSDate distantFuture];
@ -3420,8 +3526,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
int originalRow = _clickedRow;
int oldRow = -1;
int currentRow = -1;
selectionMode = 0;
BOOL getNextEvent = YES;
if (_allowsMultipleSelection == YES)
{
selectionMode |= ALLOWS_MULTIPLE;
@ -3464,67 +3570,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
// let's sort the _selectedRows
oldSelectedRows = [_selectedRows copy];
mouseLocationView = location;
lastEvent = theEvent;
if ([self mouse: mouseLocationView inRect: _bounds])
{
NSTableColumn *tb;
NSCell *cell;
NSRect cellFrame;
id originalValue;
// Prepare the cell
if (_clickedRow != -1)
{
tb = [_tableColumns objectAtIndex: _clickedColumn];
/* we should copy the cell here, as we do on editing.
otherwise validation on a cell being edited could
cause the cell we are selecting to get it's objectValue */
cell = [[tb dataCellForRow: _clickedRow] copy];
originalValue = RETAIN([self _objectValueForTableColumn:tb row:_clickedRow]);
[cell setObjectValue: originalValue];
cellFrame = [self frameOfCellAtColumn: _clickedColumn
row: _clickedRow];
[cell setHighlighted: YES];
[self setNeedsDisplayInRect: cellFrame];
/* give delegate a chance to i.e set target */
[self _willDisplayCell: cell
forTableColumn: tb
row: _clickedRow];
if ([cell trackMouse: lastEvent
inRect: cellFrame
ofView: self
untilMouseUp: [[cell class] prefersTrackingUntilMouseUp]])
{
id newValue = [cell objectValue];
if ([tb isEditable] && originalValue != newValue
&& ![originalValue isEqual: newValue])
{
[self _setObjectValue: newValue
forTableColumn: tb
row: _clickedRow];
}
done = YES;
currentRow = _clickedRow;
computeNewSelection(self,
oldSelectedRows,
_selectedRows,
originalRow,
oldRow,
currentRow,
&_selectedRow,
selectionMode);
}
RELEASE(originalValue);
[cell setHighlighted: NO];
RELEASE(cell);
[self setNeedsDisplayInRect: cellFrame];
lastEvent = [NSApp currentEvent];
}
}
while (done != YES)
{
/*
@ -3535,10 +3582,13 @@ static inline float computePeriod(NSPoint mouseLocationWin,
CREATE_AUTORELEASE_POOL(arp);
BOOL shouldComputeNewSelection = NO;
mouseLocationWin = [lastEvent locationInWindow];
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
switch ([lastEvent type])
{
case NSLeftMouseUp:
mouseLocationWin = [lastEvent locationInWindow];
if ((mouseLocationWin.y > minYVisible)
&& (mouseLocationWin.y < maxYVisible))
{
@ -3548,15 +3598,21 @@ static inline float computePeriod(NSPoint mouseLocationWin,
[NSEvent stopPeriodicEvents];
startedPeriodicEvents = NO;
}
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView];
if (oldRow != currentRow)
{
shouldComputeNewSelection = YES;
}
if (draggingPossible == YES)
{
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
}
}
else
{
@ -3568,10 +3624,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
case NSLeftMouseDown:
case NSLeftMouseDragged:
mouseLocationWin = [lastEvent locationInWindow];
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
if (fabs(mouseLocationWin.x - initialLocation.x) > 1
|| fabs(mouseLocationWin.y - initialLocation.y) > 1)
{
@ -3587,12 +3639,10 @@ static inline float computePeriod(NSPoint mouseLocationWin,
}
else if (fabs(mouseLocationWin.x - initialLocation.x) >= 4)
{
NSPasteboard *pboard;
NSArray *rows;
mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView];
if (![_selectedRows containsIndex: currentRow])
{
/* Mouse drag in a row that wasn't selected.
@ -3607,46 +3657,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
selectionMode);
}
rows = [self _selectedRowArray];
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
if ([self _writeRows: rows
toPasteboard: pboard] == YES)
if ([self _startDragOperationWithEvent:theEvent])
{
NSPoint p = NSZeroPoint;
NSImage *dragImage;
NSSize s;
dragImage = [self dragImageForRows: rows
event: theEvent
dragImageOffset: &p];
/*
* Store image offset in s ... the returned
* value is the position of the center of
* the image, so we adjust to the bottom left
* corner.
*/
s = [dragImage size];
s.width = p.x - s.width/2;
s.height = p.y + s.height/2; // View is flipped
/*
* Find the current mouse location and adjust
* it to determine the location of the bottom
* left corner of the image in this view's
* coordinate system.
*/
p = [self convertPoint:
[theEvent locationInWindow] fromView: nil];
p.x += s.width;
p.y += s.height;
[self dragImage: dragImage
at: p
offset: NSMakeSize(0, 0)
event: theEvent
pasteboard: pboard
source: self
slideBack: YES];
return;
}
else
@ -3665,8 +3677,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
startedPeriodicEvents = NO;
}
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView];
@ -3674,6 +3684,11 @@ static inline float computePeriod(NSPoint mouseLocationWin,
{
shouldComputeNewSelection = YES;
}
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
getNextEvent = (lastEvent == [NSApp currentEvent]);
}
else
{
@ -3753,12 +3768,25 @@ static inline float computePeriod(NSPoint mouseLocationWin,
selectionMode);
[self displayIfNeeded];
}
if (done == NO)
{
lastEvent = [NSApp nextEventMatchingMask: eventMask
/* in certain cases we are working with events that have already
* occured and been dequeued by NSCell classes, in these cases
* we set getNextEvent to NO, and get the current event.
*/
if (getNextEvent == YES)
{
lastEvent = [NSApp nextEventMatchingMask: eventMask
untilDate: distantFuture
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
}
else
{
lastEvent = [NSApp currentEvent];
getNextEvent = YES;
}
}
DESTROY(arp);
}