Started to clean up mouse down handling.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@19531 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
FredKiefer 2004-06-16 00:30:43 +00:00
parent 83afdc41e6
commit a1f385f74a
2 changed files with 142 additions and 169 deletions

View file

@ -1,3 +1,10 @@
2004-06-16 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSTableView.m: (-mouseDown:) Reordered code and
simplified. (-textShouldEndEditing:) Get formatter from
_editedCell not _cell. (-_unselectAllColumns) Clear the header
view as well.
2004-06-15 Fred Kiefer <FredKiefer@gmx.de> 2004-06-15 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSComboBoxCell.m: (-copyWithZone:) Added missing method. * Source/NSComboBoxCell.m: (-copyWithZone:) Added missing method.

View file

@ -104,6 +104,7 @@ static unsigned currentDragOperation;
@end @end
@interface NSTableView (SelectionHelper) @interface NSTableView (SelectionHelper)
- (void) _setSelectingColumns: (BOOL)flag;
- (NSArray *) _selectedRowArray; - (NSArray *) _selectedRowArray;
- (BOOL) _selectRow: (int)rowIndex; - (BOOL) _selectRow: (int)rowIndex;
- (BOOL) _selectUnselectedRow: (int)rowIndex; - (BOOL) _selectUnselectedRow: (int)rowIndex;
@ -2331,7 +2332,6 @@ _isCellEditable (id delegate, NSArray *tableColumns,
} }
[self deselectColumn: columnIndex]; [self deselectColumn: columnIndex];
// [self setNeedsDisplayInRect: [self rectOfColumn: columnIndex]];
return; return;
} }
else // column is not selected else // column is not selected
@ -2358,7 +2358,6 @@ _isCellEditable (id delegate, NSArray *tableColumns,
{ {
return; return;
} }
{ {
NSTableColumn *tc = [_tableColumns objectAtIndex: columnIndex]; NSTableColumn *tc = [_tableColumns objectAtIndex: columnIndex];
@ -2376,25 +2375,12 @@ _isCellEditable (id delegate, NSArray *tableColumns,
if (newSelection == YES) if (newSelection == YES)
{ {
/* No shift or alternate key pressed: clear the old selection */ /* No shift or alternate key pressed: clear the old selection */
/* Compute rect to redraw to clear the old selection */
/*
int column, i, count = [_selectedColumns count];
for (i = 0; i < count; i++)
{
column = [[_selectedColumns objectAtIndex: i] intValue];
[self setNeedsDisplayInRect: [self rectOfColumn: column]];
}
*/
/* Draw the new selection */
[self selectColumn: columnIndex byExtendingSelection: NO]; [self selectColumn: columnIndex byExtendingSelection: NO];
// [self setNeedsDisplayInRect: [self rectOfColumn: columnIndex]];
} }
else /* Simply add to the old selection */ else
{ {
/* Simply add to the old selection */
[self selectColumn: columnIndex byExtendingSelection: YES]; [self selectColumn: columnIndex byExtendingSelection: YES];
// [self setNeedsDisplayInRect: [self rectOfColumn: columnIndex]];
} }
} }
} }
@ -2536,13 +2522,7 @@ _isCellEditable (id delegate, NSArray *tableColumns,
only column - because we have been called to select it. */ only column - because we have been called to select it. */
if (_numberOfColumns > 1) if (_numberOfColumns > 1)
{ {
[_selectedColumns removeAllIndexes]; [self _unselectAllColumns];
[self setNeedsDisplay: YES];
if (_headerView)
{
[_headerView setNeedsDisplay: YES];
}
_selectedColumn = -1;
} }
} }
else // flag == YES else // flag == YES
@ -2621,9 +2601,7 @@ byExtendingSelection: (BOOL)flag
only row - because we have been called to select it. */ only row - because we have been called to select it. */
if (_numberOfRows > 1) if (_numberOfRows > 1)
{ {
[_selectedRows removeAllIndexes]; [self _unselectAllRows];
_selectedRow = -1;
[self setNeedsDisplay: YES];
} }
} }
else // flag == YES else // flag == YES
@ -3041,8 +3019,6 @@ byExtendingSelection: (BOOL)flag
[self _postSelectionDidChangeNotification]; [self _postSelectionDidChangeNotification];
} }
- (void) deselectAll: (id) sender - (void) deselectAll: (id) sender
{ {
if (_allowsEmptySelection == NO) if (_allowsEmptySelection == NO)
@ -3324,37 +3300,41 @@ byExtendingSelection: (BOOL)flag
return _editedColumn; return _editedColumn;
} }
- (void) _setSelectingColumns: (BOOL)flag
inline float computePeriod(NSPoint mouseLocationWin,
float minYVisible,
float maxYVisible)
{ {
if (flag == _selectingColumns) /* We have three zones of speed.
return; 0 - 50 pixels: period 0.2 <zone 1>
50 - 100 pixels: period 0.1 <zone 2>
if (flag == NO) 100 - 150 pixels: period 0.01 <zone 3> */
{ float distance = 0;
[self _unselectAllColumns];
_selectingColumns = NO; if (mouseLocationWin.y < minYVisible)
} {
else distance = minYVisible - mouseLocationWin.y;
{ }
[self _unselectAllRows]; else if (mouseLocationWin.y > maxYVisible)
_selectingColumns = YES; {
} distance = mouseLocationWin.y - maxYVisible;
}
if (distance < 50)
return 0.2;
else if (distance < 100)
return 0.1;
else
return 0.01;
} }
- (void) mouseDown: (NSEvent *)theEvent - (void) mouseDown: (NSEvent *)theEvent
{ {
NSPoint location = [theEvent locationInWindow];
NSPoint initialLocation = [theEvent locationInWindow]; NSPoint initialLocation = [theEvent locationInWindow];
NSTableColumn *tb; NSPoint location;
int clickCount; int clickCount;
BOOL shouldEdit;
int _originalRow;
int _oldRow = -1;
int _currentRow = -1;
//
// Pathological case -- ignore mouse down // Pathological case -- ignore mouse down
//
if ((_numberOfRows == 0) || (_numberOfColumns == 0)) if ((_numberOfRows == 0) || (_numberOfColumns == 0))
{ {
[super mouseDown: theEvent]; [super mouseDown: theEvent];
@ -3362,21 +3342,45 @@ byExtendingSelection: (BOOL)flag
} }
clickCount = [theEvent clickCount]; clickCount = [theEvent clickCount];
if (clickCount > 2) if (clickCount > 2)
return; {
return;
}
// Determine row and column which were clicked // Determine row and column which were clicked
location = [self convertPoint: location fromView: nil]; location = [self convertPoint: initialLocation fromView: nil];
_clickedRow = [self rowAtPoint: location]; _clickedRow = [self rowAtPoint: location];
_clickedColumn = [self columnAtPoint: location]; _clickedColumn = [self columnAtPoint: location];
_originalRow = _clickedRow;
// Selection if (clickCount == 2)
if (clickCount == 1)
{ {
// Double-click event
NSTableColumn *tb;
if ([self isRowSelected: _clickedRow] == NO)
{
return;
}
tb = [_tableColumns objectAtIndex: _clickedColumn];
if (([tb isEditable] == NO) ||
([self _shouldEditTableColumn: tb
row: _clickedRow] == NO))
{
// Send double-action but don't edit
[self sendAction: _doubleAction to: _target];
}
else
{
// It is OK to edit column. Go on, do it.
[self editColumn: _clickedColumn row: _clickedRow
withEvent: theEvent select: NO];
}
}
else
{
// Selection
unsigned int modifiers = [theEvent modifierFlags]; unsigned int modifiers = [theEvent modifierFlags];
BOOL startedPeriodicEvents = NO;
unsigned int eventMask = (NSLeftMouseUpMask unsigned int eventMask = (NSLeftMouseUpMask
| NSLeftMouseDownMask | NSLeftMouseDownMask
| NSLeftMouseDraggedMask | NSLeftMouseDraggedMask
@ -3386,40 +3390,19 @@ byExtendingSelection: (BOOL)flag
NSDate *distantFuture = [NSDate distantFuture]; NSDate *distantFuture = [NSDate distantFuture];
NSEvent *lastEvent; NSEvent *lastEvent;
NSIndexSet *_oldSelectedRows; NSIndexSet *_oldSelectedRows;
BOOL startedPeriodicEvents = NO;
BOOL mouseUp = NO; BOOL mouseUp = NO;
BOOL done = NO; BOOL done = NO;
BOOL mouseMoved = NO;
BOOL draggingPossible = [self _isDraggingSource]; BOOL draggingPossible = [self _isDraggingSource];
NSRect visibleRect = [self convertRect: [self visibleRect] NSRect visibleRect = [self convertRect: [self visibleRect]
toView: nil]; toView: nil];
float minYVisible = NSMinY (visibleRect); float minYVisible = NSMinY (visibleRect);
float maxYVisible = NSMaxY (visibleRect); float maxYVisible = NSMaxY (visibleRect);
BOOL mouseMoved = NO;
/* We have three zones of speed.
0 - 50 pixels: period 0.2 <zone 1>
50 - 100 pixels: period 0.1 <zone 2>
100 - 150 pixels: period 0.01 <zone 3> */
float oldPeriod = 0; float oldPeriod = 0;
inline float computePeriod(void) int originalRow = _clickedRow;
{ int oldRow = -1;
float distance = 0; int currentRow = -1;
if (mouseLocationWin.y < minYVisible)
{
distance = minYVisible - mouseLocationWin.y;
}
else if (mouseLocationWin.y > maxYVisible)
{
distance = mouseLocationWin.y - maxYVisible;
}
if (distance < 50)
return 0.2;
else if (distance < 100)
return 0.1;
else
return 0.01;
}
selectionMode = 0; selectionMode = 0;
if (_allowsMultipleSelection == YES) if (_allowsMultipleSelection == YES)
@ -3447,7 +3430,7 @@ byExtendingSelection: (BOOL)flag
selectionMode |= CONTROL_DOWN; selectionMode |= CONTROL_DOWN;
if (_allowsMultipleSelection == YES) if (_allowsMultipleSelection == YES)
{ {
_originalRow = _selectedRow; originalRow = _selectedRow;
selectionMode |= SHIFT_DOWN; selectionMode |= SHIFT_DOWN;
selectionMode |= ADDING_ROW; selectionMode |= ADDING_ROW;
} }
@ -3460,20 +3443,7 @@ byExtendingSelection: (BOOL)flag
} }
// if we are in column selection mode, stop it // if we are in column selection mode, stop it
if (_selectingColumns == YES) [self _setSelectingColumns: NO];
{
if (_headerView)
{
int i;
for (i = 0; i < _numberOfColumns; i++)
{
if ([self isColumnSelected: i])
[_headerView setNeedsDisplayInRect:
[_headerView headerRectOfColumn: i]];
}
}
[self _setSelectingColumns: NO];
}
// let's sort the _selectedRows // let's sort the _selectedRows
_oldSelectedRows = [_selectedRows copy]; _oldSelectedRows = [_selectedRows copy];
@ -3488,14 +3458,15 @@ byExtendingSelection: (BOOL)flag
*/ */
CREATE_AUTORELEASE_POOL(arp); CREATE_AUTORELEASE_POOL(arp);
BOOL shouldComputeNewSelection = NO; BOOL shouldComputeNewSelection = NO;
switch ([lastEvent type]) switch ([lastEvent type])
{ {
case NSLeftMouseUp: case NSLeftMouseUp:
mouseLocationWin = [lastEvent locationInWindow]; mouseLocationWin = [lastEvent locationInWindow];
if ((mouseLocationWin.y > minYVisible) if ((mouseLocationWin.y > minYVisible)
&& (mouseLocationWin.y < maxYVisible)) && (mouseLocationWin.y < maxYVisible))
// mouse dragged within table
{ {
// mouse dragged within table
NSPoint mouseLocationView; NSPoint mouseLocationView;
if (startedPeriodicEvents == YES) if (startedPeriodicEvents == YES)
@ -3503,20 +3474,19 @@ byExtendingSelection: (BOOL)flag
[NSEvent stopPeriodicEvents]; [NSEvent stopPeriodicEvents];
startedPeriodicEvents = NO; startedPeriodicEvents = NO;
} }
mouseLocationView = [self convertPoint: mouseLocationView = [self convertPoint: mouseLocationWin
mouseLocationWin
fromView: nil]; 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;
} }
} }
else else
// Mouse dragged out of the table
{ {
// Mouse dragged out of the table
// we don't care // we don't care
} }
done = YES; done = YES;
@ -3539,35 +3509,36 @@ byExtendingSelection: (BOOL)flag
{ {
draggingPossible = NO; draggingPossible = NO;
} }
else if (mouseLocationWin.x - initialLocation.x >=4 else if (mouseLocationWin.x - initialLocation.x >= 4
|| mouseLocationWin.x - initialLocation.x <= -4) || mouseLocationWin.x - initialLocation.x <= -4)
{ {
NSPoint mouseLocationView; NSPoint mouseLocationView;
NSPasteboard *pboard; NSPasteboard *pboard;
NSArray *rows; NSArray *rows;
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
mouseLocationView = [self convertPoint: mouseLocationView = [self convertPoint:
mouseLocationWin mouseLocationWin
fromView: nil]; 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)
{ {
/* Mouse drag in a row that wasn't selected. /* Mouse drag in a row that wasn't selected.
select the new row before dragging */ select the new row before dragging */
computeNewSelection(self, computeNewSelection(self,
_oldSelectedRows, _oldSelectedRows,
_selectedRows, _selectedRows,
_originalRow, originalRow,
_oldRow, oldRow,
_currentRow, currentRow,
&_selectedRow, &_selectedRow,
selectionMode); selectionMode);
} }
rows = [self _selectedRowArray]; rows = [self _selectedRowArray];
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
if ([self _writeRows: rows if ([self _writeRows: rows
toPasteboard: pboard] == YES) toPasteboard: pboard] == YES)
{ {
@ -3594,8 +3565,8 @@ byExtendingSelection: (BOOL)flag
} }
else if ((mouseLocationWin.y > minYVisible) else if ((mouseLocationWin.y > minYVisible)
&& (mouseLocationWin.y < maxYVisible)) && (mouseLocationWin.y < maxYVisible))
// mouse dragged within table
{ {
// mouse dragged within table
NSPoint mouseLocationView; NSPoint mouseLocationView;
if (startedPeriodicEvents == YES) if (startedPeriodicEvents == YES)
@ -3603,33 +3574,35 @@ byExtendingSelection: (BOOL)flag
[NSEvent stopPeriodicEvents]; [NSEvent stopPeriodicEvents];
startedPeriodicEvents = NO; startedPeriodicEvents = NO;
} }
mouseLocationView = [self convertPoint:
mouseLocationWin mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil]; 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;
} }
} }
else else
// Mouse dragged out of the table
{ {
// Mouse dragged out of the table
float period = computePeriod(mouseLocationWin,
minYVisible,
maxYVisible);
if (startedPeriodicEvents == YES) if (startedPeriodicEvents == YES)
{ {
/* Check - if the mouse did not change zone, /* Check - if the mouse did not change zone,
we do nothing */ we do nothing */
if (computePeriod () == oldPeriod) if (period == oldPeriod)
break; break;
[NSEvent stopPeriodicEvents]; [NSEvent stopPeriodicEvents];
} }
/* Start periodic events */ /* Start periodic events */
oldPeriod = computePeriod (); oldPeriod = period;
[NSEvent startPeriodicEventsAfterDelay: 0 [NSEvent startPeriodicEventsAfterDelay: 0
withPeriod: oldPeriod]; withPeriod: oldPeriod];
startedPeriodicEvents = YES; startedPeriodicEvents = YES;
@ -3643,23 +3616,23 @@ byExtendingSelection: (BOOL)flag
if (mouseUp == NO) if (mouseUp == NO)
{ {
/* mouse below the table */ /* mouse below the table */
if (_currentRow < _numberOfRows - 1) if (currentRow < _numberOfRows - 1)
{ {
_oldRow = _currentRow; oldRow = currentRow;
_currentRow++; currentRow++;
[self scrollRowToVisible: _currentRow]; [self scrollRowToVisible: currentRow];
if (draggingPossible == NO) if (draggingPossible == NO)
shouldComputeNewSelection = YES; shouldComputeNewSelection = YES;
} }
} }
else else
{ {
if (_currentRow > 0) if (currentRow > 0)
{ {
/* mouse above the table */ /* mouse above the table */
_oldRow = _currentRow; oldRow = currentRow;
_currentRow--; currentRow--;
[self scrollRowToVisible: _currentRow]; [self scrollRowToVisible: currentRow];
if (draggingPossible == NO) if (draggingPossible == NO)
shouldComputeNewSelection = YES; shouldComputeNewSelection = YES;
} }
@ -3668,14 +3641,15 @@ byExtendingSelection: (BOOL)flag
default: default:
break; break;
} }
if (shouldComputeNewSelection == YES) if (shouldComputeNewSelection == YES)
{ {
computeNewSelection(self, computeNewSelection(self,
_oldSelectedRows, _oldSelectedRows,
_selectedRows, _selectedRows,
_originalRow, originalRow,
_oldRow, oldRow,
_currentRow, currentRow,
&_selectedRow, &_selectedRow,
selectionMode); selectionMode);
[self displayIfNeeded]; [self displayIfNeeded];
@ -3693,7 +3667,7 @@ byExtendingSelection: (BOOL)flag
if (startedPeriodicEvents == YES) if (startedPeriodicEvents == YES)
[NSEvent stopPeriodicEvents]; [NSEvent stopPeriodicEvents];
if (![_selectedRows isEqualToIndexSet: _oldSelectedRows]) if (![_selectedRows isEqualToIndexSet: _oldSelectedRows])
{ {
[self _postSelectionDidChangeNotification]; [self _postSelectionDidChangeNotification];
} }
@ -3712,35 +3686,6 @@ byExtendingSelection: (BOOL)flag
} }
return; return;
} }
// Double-click events
if ([self isRowSelected: _clickedRow] == NO)
return;
tb = [_tableColumns objectAtIndex: _clickedColumn];
shouldEdit = YES;
if ([tb isEditable] == NO)
{
shouldEdit = NO;
}
else if ([self _shouldEditTableColumn: tb
row: _clickedRow] == NO)
{
shouldEdit = NO;
}
if (shouldEdit == NO)
{
// Send double-action but don't edit
[self sendAction: _doubleAction to: _target];
return;
}
// It is OK to edit column. Go on, do it.
[self editColumn: _clickedColumn row: _clickedRow
withEvent: theEvent select: NO];
} }
/* /*
@ -4824,8 +4769,7 @@ byExtendingSelection: (BOOL)flag
[self setNeedsDisplayInRect: [self setNeedsDisplayInRect:
[self frameOfCellAtColumn: _editedColumn row: _editedRow]]; [self frameOfCellAtColumn: _editedColumn row: _editedRow]];
_textObject = nil; _textObject = nil;
RELEASE (_editedCell); DESTROY (_editedCell);
_editedCell = nil;
/* Save values */ /* Save values */
row = _editedRow; row = _editedRow;
column = _editedColumn; column = _editedColumn;
@ -4897,7 +4841,7 @@ byExtendingSelection: (BOOL)flag
NSFormatter *formatter; NSFormatter *formatter;
id newObjectValue; id newObjectValue;
formatter = [_cell formatter]; formatter = [_editedCell formatter];
if ([formatter getObjectValue: &newObjectValue if ([formatter getObjectValue: &newObjectValue
forString: [_textObject text] forString: [_textObject text]
@ -5925,6 +5869,23 @@ byExtendingSelection: (BOOL)flag
@implementation NSTableView (SelectionHelper) @implementation NSTableView (SelectionHelper)
- (void) _setSelectingColumns: (BOOL)flag
{
if (flag == _selectingColumns)
return;
if (flag == NO)
{
[self _unselectAllColumns];
_selectingColumns = NO;
}
else
{
[self _unselectAllRows];
_selectingColumns = YES;
}
}
- (NSArray *) _selectedRowArray - (NSArray *) _selectedRowArray
{ {
NSMutableArray *selected = [NSMutableArray array]; NSMutableArray *selected = [NSMutableArray array];
@ -6023,6 +5984,11 @@ byExtendingSelection: (BOOL)flag
while (column != NSNotFound) while (column != NSNotFound)
{ {
[self setNeedsDisplayInRect: [self rectOfColumn: column]]; [self setNeedsDisplayInRect: [self rectOfColumn: column]];
if (_headerView)
{
[_headerView setNeedsDisplayInRect:
[_headerView headerRectOfColumn: column]];
}
column = [_selectedColumns indexGreaterThanIndex: column]; column = [_selectedColumns indexGreaterThanIndex: column];
} }
[_selectedColumns removeAllIndexes]; [_selectedColumns removeAllIndexes];