gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NSTableView keyboard control


From: Matt Rice
Subject: NSTableView keyboard control
Date: Sat, 4 Nov 2006 03:13:27 -0800 (PST)

heres an initial implementation of keyboard control
up, down, page up, page down, home, end and modifiers
for NSTableView..

its not exactly pretty 

where NSTableView -mouseDown:
can save the initial row started by dragging to select
multiple rows and what not keyDown: cannot

so i sortof hijacked _clickedRow for that;

mouse down does the same thing with the
oldSelectedRows
indexed set (no ivar to hijack there.), and i'm not
exactly sure you could use it if there was one.
so i pass nil for that to computeNewSelection..

this will mean the behaviours of shift->drag and
click->drag may differ between shift->up, up, up and
what not.

btw, it should not conflict with the other NSTableView
patches i've posted here recently.



 
__________________________________________________________________________________________
Check out the New Yahoo! Mail - Fire up a more powerful email and get things 
done faster. 
(http://advision.webevents.yahoo.com/mailbeta) 
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,118 @@
     }
 }
 
+- (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)
+    {
+      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);
+      [self scrollRowToVisible:currentRow];
+      [self displayIfNeeded];
+    }
+}
+
 /* 
  * Auxiliary Components 
  */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]