[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSTableView keyboard control
From: |
Matt Rice |
Subject: |
Re: NSTableView keyboard control |
Date: |
Sat, 4 Nov 2006 04:27:09 -0800 (PST) |
--- Matt Rice <address@hidden> wrote:
>
>
> --- Matt Rice <address@hidden> wrote:
>
> > heres an initial implementation of keyboard
> control
> > up, down, page up, page down, home, end and
> > modifiers
> > for NSTableView..
> >
> > its not exactly pretty
>
> alright well, my abuse of computeNewSelection()
> doesn't seem to be fully functional, for instance it
> will post SelectionIsChangingNotification but not
> SelectionDidChangeNotification sometimes.
>
oops... because its not supposed to send it..
updated...
____________________________________________________________________________________
Want to start your own business? Learn how on Yahoo! Small Business
(http://smallbusiness.yahoo.com)
Index: NSTableView.m
===================================================================
--- NSTableView.m (revision 24019)
+++ NSTableView.m (working copy)
@@ -1432,6 +1432,13 @@
*_selectedRow = i;
notified = YES;
}
+ else if ([_selectedRows containsIndex:i])
+ {
+ [tv setNeedsDisplayInRect: [tv rectOfRow: i]];
+ [_selectedRows removeIndex:i];
+ *_selectedRow = _currentRow;
+ notified = YES;
+ }
}
if (notified == YES)
{
@@ -1491,6 +1498,14 @@
*_selectedRow = i;
notified = YES;
}
+ else if ([_selectedRows containsIndex:i])
+ {
+ [tv setNeedsDisplayInRect: [tv rectOfRow: i]];
+ [_selectedRows removeIndex:i];
+ *_selectedRow = _currentRow;
+ notified = YES;
+ }
+
}
if (notified == YES)
@@ -2615,6 +2630,7 @@
[self validateEditing];
[self abortEditing];
}
+ _clickedRow = rowIndex;
return;
}
@@ -2644,11 +2660,13 @@
/* Now select the row and post notification only if needed */
if ([self _selectUnselectedRow: rowIndex])
{
+ _clickedRow = rowIndex;
[self _postSelectionDidChangeNotification];
}
else /* Otherwise simply change the last selected row */
{
_selectedRow = rowIndex;
+ _clickedRow = rowIndex;
}
}
@@ -3455,6 +3473,42 @@
return NO;
}
+- (unsigned) _selectionModeForModifiers:(unsigned int)modifiers row:(int)row
+{
+ unsigned selectionMode = 0;
+ if (_allowsMultipleSelection == YES)
+ {
+ selectionMode |= ALLOWS_MULTIPLE;
+ }
+
+ if (_allowsEmptySelection == YES)
+ {
+ selectionMode |= ALLOWS_EMPTY;
+ }
+
+ if (modifiers & NSShiftKeyMask)
+ {
+ selectionMode |= SHIFT_DOWN;
+ }
+
+ if (![_selectedRows containsIndex: row])
+ {
+ selectionMode |= ADDING_ROW;
+ }
+
+ if (modifiers & NSControlKeyMask)
+ {
+ selectionMode |= CONTROL_DOWN;
+
+ if (_allowsMultipleSelection == YES && _selectedRow != -1)
+ {
+ selectionMode |= SHIFT_DOWN;
+ selectionMode |= ADDING_ROW;
+ }
+ }
+ return selectionMode;
+}
+
- (void) mouseDown: (NSEvent *)theEvent
{
NSPoint initialLocation = [theEvent locationInWindow];
@@ -3535,37 +3589,15 @@
int currentRow = -1;
BOOL getNextEvent = YES;
- if (_allowsMultipleSelection == YES)
- {
- selectionMode |= ALLOWS_MULTIPLE;
- }
-
- if (_allowsEmptySelection == YES)
- {
- selectionMode |= ALLOWS_EMPTY;
- }
-
- if (modifiers & NSShiftKeyMask)
- {
- selectionMode |= SHIFT_DOWN;
- }
-
- if (![_selectedRows containsIndex: _clickedRow])
- {
- selectionMode |= ADDING_ROW;
- }
-
+ selectionMode = [self _selectionModeForModifiers:modifiers
row:_clickedRow];
if (modifiers & NSControlKeyMask)
{
- selectionMode |= CONTROL_DOWN;
if (_allowsMultipleSelection == YES && _selectedRow != -1)
{
originalRow = _selectedRow;
- selectionMode |= SHIFT_DOWN;
- selectionMode |= ADDING_ROW;
}
}
-
+
// is the delegate ok for a new selection ?
if ([self _shouldSelectionChange] == NO)
{
@@ -3823,6 +3855,125 @@
}
}
+- (void) keyDown:(NSEvent *)theEvent
+{
+ int oldRow = -1;
+ int currentRow = _selectedRow;
+ int originalRow = - 1;
+ NSString *characters = [theEvent characters];
+ unsigned int len = [characters length];
+ unsigned int modifiers = [theEvent modifierFlags];
+ unsigned int selectionMode = 0;
+ unsigned int i;
+
+ [self _setSelectingColumns: NO];
+
+ if (modifiers & NSControlKeyMask)
+ {
+ originalRow = _clickedRow;
+ if (_allowsMultipleSelection == YES && _selectedRow != -1)
+ {
+ oldRow = _selectedRow;
+ }
+ }
+
+ if (modifiers & NSShiftKeyMask)
+ {
+ originalRow = _clickedRow;
+ oldRow = _selectedRow;
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ unichar c = [characters characterAtIndex:i];
+ int isPageDown = 0;
+
+ switch(c)
+ {
+ case NSUpArrowFunctionKey:
+ currentRow--;
+ break;
+ case NSDownArrowFunctionKey:
+ currentRow++;
+ break;
+ case NSPageDownFunctionKey:
+ isPageDown = 1;
+ case NSPageUpFunctionKey:
+ {
+ NSRect visibleRect = [self visibleRect];
+ /* number of rows that fit in the table view visible area. */
+ int visRows = 0;
+ if (visibleRect.size.height > 0)
+ {
+ visRows = fabs(visibleRect.size.height / [self rowHeight]);
+ }
+ if (isPageDown)
+ {
+ currentRow += visRows;
+ if (currentRow >= _numberOfRows)
+ currentRow = _numberOfRows - 1;
+ }
+ else
+ {
+ currentRow -= visRows;
+ if (currentRow < 0)
+ currentRow = 0;
+ }
+ }
+ break;
+ case NSHomeFunctionKey:
+ currentRow = 0;
+ break;
+ case NSEndFunctionKey:
+ currentRow = _numberOfRows - 1;
+ break;
+ case NSLeftArrowFunctionKey:
+ case NSRightArrowFunctionKey:
+ // TODO
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (_numberOfRows
+ && currentRow < _numberOfRows
+ && currentRow >= 0)
+ {
+ NSIndexSet *prevSelection = [_selectedRows copy];
+ selectionMode = [self _selectionModeForModifiers:modifiers
+ row:currentRow];
+
+ if (originalRow == -1)
+ {
+ originalRow = currentRow;
+ _clickedRow = currentRow;
+ }
+
+ if (_clickedRow == -1)
+ {
+ _clickedRow = currentRow;
+ }
+
+ computeNewSelection(self,
+ nil,
+ _selectedRows,
+ originalRow,
+ oldRow,
+ currentRow,
+ &_selectedRow,
+ selectionMode);
+
+ if (![_selectedRows isEqual:prevSelection])
+ {
+ [self _postSelectionDidChangeNotification];
+ }
+
+ [self scrollRowToVisible:currentRow];
+ [self displayIfNeeded];
+ }
+}
+
/*
* Auxiliary Components
*/