* 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:
ratmice 2006-11-01 09:50:00 +00:00
parent e2b7911921
commit c8a1031081
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> 2006-10-31 Matt Rice <ratmice@yahoo.com>
* Tools/gopen.m * Tools/gopen.m

View file

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

View file

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

View file

@ -146,7 +146,10 @@ typedef struct _tableViewFlags
- (void) _unselectAllColumns; - (void) _unselectAllColumns;
@end @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 * A specific struct and its associated quick sort function
@ -3341,11 +3344,114 @@ static inline float computePeriod(NSPoint mouseLocationWin,
return 0.01; 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 - (void) mouseDown: (NSEvent *)theEvent
{ {
NSPoint initialLocation = [theEvent locationInWindow]; NSPoint initialLocation = [theEvent locationInWindow];
NSPoint location; NSPoint location;
int clickCount;
// Pathological case -- ignore mouse down // Pathological case -- ignore mouse down
if ((_numberOfRows == 0) || (_numberOfColumns == 0)) if ((_numberOfRows == 0) || (_numberOfColumns == 0))
@ -3353,12 +3459,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
return; return;
} }
clickCount = [theEvent clickCount];
if (clickCount > 2)
{
return;
}
/* Stop editing if any */ /* Stop editing if any */
if (_textObject != nil) if (_textObject != nil)
{ {
@ -3370,8 +3470,9 @@ static inline float computePeriod(NSPoint mouseLocationWin,
location = [self convertPoint: initialLocation fromView: nil]; location = [self convertPoint: initialLocation fromView: nil];
_clickedRow = [self rowAtPoint: location]; _clickedRow = [self rowAtPoint: location];
_clickedColumn = [self columnAtPoint: location]; _clickedColumn = [self columnAtPoint: location];
if (clickCount == 2) if ([theEvent type] == NSLeftMouseDown
&& [theEvent clickCount] > 1)
{ {
// Double-click event // Double-click event
@ -3383,14 +3484,19 @@ static inline float computePeriod(NSPoint mouseLocationWin,
if (![self _isCellEditableColumn: _clickedColumn row: _clickedRow ]) if (![self _isCellEditableColumn: _clickedColumn row: _clickedRow ])
{ {
// Send double-action but don't edit // Send double-action but don't edit
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
if (_clickedRow != -1) if (_clickedRow != -1)
[self sendAction: _doubleAction to: _target]; [self sendAction: _doubleAction to: _target];
} }
else else
{ {
// It is OK to edit column. Go on, do it. // It is OK to edit column. Go on, do it.
[self editColumn: _clickedColumn row: _clickedRow [self editColumn: _clickedColumn
withEvent: theEvent select: YES]; row: _clickedRow
withEvent: theEvent
select: YES];
} }
} }
else else
@ -3401,7 +3507,7 @@ static inline float computePeriod(NSPoint mouseLocationWin,
| NSLeftMouseDownMask | NSLeftMouseDownMask
| NSLeftMouseDraggedMask | NSLeftMouseDraggedMask
| NSPeriodicMask); | NSPeriodicMask);
unsigned selectionMode; unsigned selectionMode = 0;
NSPoint mouseLocationWin; NSPoint mouseLocationWin;
NSPoint mouseLocationView; NSPoint mouseLocationView;
NSDate *distantFuture = [NSDate distantFuture]; NSDate *distantFuture = [NSDate distantFuture];
@ -3420,8 +3526,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
int originalRow = _clickedRow; int originalRow = _clickedRow;
int oldRow = -1; int oldRow = -1;
int currentRow = -1; int currentRow = -1;
BOOL getNextEvent = YES;
selectionMode = 0;
if (_allowsMultipleSelection == YES) if (_allowsMultipleSelection == YES)
{ {
selectionMode |= ALLOWS_MULTIPLE; selectionMode |= ALLOWS_MULTIPLE;
@ -3464,67 +3570,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
// let's sort the _selectedRows // let's sort the _selectedRows
oldSelectedRows = [_selectedRows copy]; oldSelectedRows = [_selectedRows copy];
mouseLocationView = location;
lastEvent = theEvent; 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) while (done != YES)
{ {
/* /*
@ -3535,10 +3582,13 @@ static inline float computePeriod(NSPoint mouseLocationWin,
CREATE_AUTORELEASE_POOL(arp); CREATE_AUTORELEASE_POOL(arp);
BOOL shouldComputeNewSelection = NO; BOOL shouldComputeNewSelection = NO;
mouseLocationWin = [lastEvent locationInWindow];
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
switch ([lastEvent type]) switch ([lastEvent type])
{ {
case NSLeftMouseUp: case NSLeftMouseUp:
mouseLocationWin = [lastEvent locationInWindow];
if ((mouseLocationWin.y > minYVisible) if ((mouseLocationWin.y > minYVisible)
&& (mouseLocationWin.y < maxYVisible)) && (mouseLocationWin.y < maxYVisible))
{ {
@ -3548,15 +3598,21 @@ static inline float computePeriod(NSPoint mouseLocationWin,
[NSEvent stopPeriodicEvents]; [NSEvent stopPeriodicEvents];
startedPeriodicEvents = NO; startedPeriodicEvents = NO;
} }
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
mouseLocationView.x = _bounds.origin.x; mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow; oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView]; currentRow = [self rowAtPoint: mouseLocationView];
if (oldRow != currentRow) if (oldRow != currentRow)
{ {
shouldComputeNewSelection = YES; shouldComputeNewSelection = YES;
} }
if (draggingPossible == YES)
{
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
}
} }
else else
{ {
@ -3568,10 +3624,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
case NSLeftMouseDown: case NSLeftMouseDown:
case NSLeftMouseDragged: case NSLeftMouseDragged:
mouseLocationWin = [lastEvent locationInWindow];
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
if (fabs(mouseLocationWin.x - initialLocation.x) > 1 if (fabs(mouseLocationWin.x - initialLocation.x) > 1
|| fabs(mouseLocationWin.y - initialLocation.y) > 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) else if (fabs(mouseLocationWin.x - initialLocation.x) >= 4)
{ {
NSPasteboard *pboard;
NSArray *rows;
mouseLocationView.x = _bounds.origin.x; mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow; oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView]; currentRow = [self rowAtPoint: mouseLocationView];
if (![_selectedRows containsIndex: currentRow]) if (![_selectedRows containsIndex: currentRow])
{ {
/* Mouse drag in a row that wasn't selected. /* Mouse drag in a row that wasn't selected.
@ -3607,46 +3657,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
selectionMode); selectionMode);
} }
rows = [self _selectedRowArray]; if ([self _startDragOperationWithEvent:theEvent])
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; return;
} }
else else
@ -3665,8 +3677,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
startedPeriodicEvents = NO; startedPeriodicEvents = NO;
} }
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
mouseLocationView.x = _bounds.origin.x; mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow; oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView]; currentRow = [self rowAtPoint: mouseLocationView];
@ -3674,6 +3684,11 @@ static inline float computePeriod(NSPoint mouseLocationWin,
{ {
shouldComputeNewSelection = YES; shouldComputeNewSelection = YES;
} }
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
getNextEvent = (lastEvent == [NSApp currentEvent]);
} }
else else
{ {
@ -3753,12 +3768,25 @@ static inline float computePeriod(NSPoint mouseLocationWin,
selectionMode); selectionMode);
[self displayIfNeeded]; [self displayIfNeeded];
} }
if (done == NO) 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 untilDate: distantFuture
inMode: NSEventTrackingRunLoopMode inMode: NSEventTrackingRunLoopMode
dequeue: YES]; dequeue: YES];
}
else
{
lastEvent = [NSApp currentEvent];
getNextEvent = YES;
}
} }
DESTROY(arp); DESTROY(arp);
} }