gnustep-dev
[Top][All Lists]
Advanced

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

Re: [Gnustep-cvs] gnustep/core/gui ChangeLog Source/NSTableView.m


From: Matt Rice
Subject: Re: [Gnustep-cvs] gnustep/core/gui ChangeLog Source/NSTableView.m
Date: Sat, 4 Jun 2005 02:22:17 -0700 (PDT)

--- Enrico Sersale <address@hidden> wrote:

> On 2005-05-28 06:34:22 +0300 Matt Rice
> <address@hidden> wrote:
> 
> > --- Enrico Sersale <address@hidden> wrote:
> >> On 2005-05-26 16:38:12 +0300 Fred Kiefer
> >> <address@hidden> wrote:
> >> 
> >>> CVSROOT:  /cvsroot/gnustep
> >>> Module name:      gnustep
> >>> Branch:   
> >>> Changes by:       Fred Kiefer
> >> <address@hidden>   05/05/26 13:38:11
> >>>> Modified files:
> >>>   core/gui       : ChangeLog      core/gui/Source:
> >> NSTableView.m
> >>> Log message:
> >>>   Improved mouseDown call handling for table
> view.
> >>>> CVSWeb URLs:
> >>> 
> >> 
> >
>
http://savannah.gnu.org/cgi-bin/viewcvs/gnustep/gnustep/core/gui/ChangeLog.diff?tr1=1.2528&tr2=1.2529&r1=text&r2=text
> >>> 
> >> 
> >
>
http://savannah.gnu.org/cgi-bin/viewcvs/gnustep/gnustep/core/gui/Source/NSTableView.m.diff?tr1=1.116&tr2=1.117&r1=text&r2=text
> >> 
> >> I think that it would be a good habit to try to
> run
> >> one or two of the (few) GNUstep applications
> before
> >> committing changes that can break things...
> >> 
> > 
> > just to elaborate.. this breaks (at least)
> > gworkspace's
> > view->list segfaults when selecting a row.
> 
> Just to be more precise :) ... I'm not referring to
> this; I've fixed it implementing -copyWithZone: in
> my cell class when I've seen that gworkspace
> segfaults trying to release an ivar of this class.
> The real problem is that it is not possible anymore
> to start a drag from a cell (this is visible in
> GNUMail, too). Making -startTrackingAt:inView: to
> return NO in the cell class fixes this problem too,
> but I think that there is something wrong in
> -mouseDown: because, before theese changes, both the
> apps worked well.
> 

indeed I don't think that should be required either.
(though looking at the docs i noticed that
-startTrackingAt:inView:... returns NO if the view
doesn't send actions on dragging or periodic events

it isn't clear whether this affects the return value
of trackMouse:inRect:... 

anyhow a little testing shows you are correct.

this changes the behaviour of trackMouse:inRect:..
slightly to cope with an event that happened in the pa

in a dragging source table view
trackMouse:mouseDownEvent will be sent after the mouse
has gone up (when it is clear that no dragging has
been started).. though this severely limits the cells
which will work with one

sure isn't pretty though, that's probably fixable..



                
__________________________________ 
Discover Yahoo! 
Get on-the-go sports scores, stock quotes, news and more. Check it out! 
http://discover.yahoo.com/mobile.html
Index: NSTableView.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSTableView.m,v
retrieving revision 1.118
diff -u -r1.118 NSTableView.m
--- NSTableView.m       30 May 2005 17:01:21 -0000      1.118
+++ NSTableView.m       4 Jun 2005 08:51:50 -0000
@@ -3332,7 +3332,32 @@
 {
   NSPoint initialLocation = [theEvent locationInWindow];
   NSPoint location;
-  int clickCount;
+  // Selection
+  unsigned int modifiers = [theEvent modifierFlags];
+  unsigned int eventMask = (NSLeftMouseUpMask 
+                           | NSLeftMouseDownMask
+                           | NSLeftMouseDraggedMask 
+                           | NSPeriodicMask);
+  unsigned selectionMode;
+  NSPoint mouseLocationWin;
+  NSPoint mouseLocationView;
+  NSDate *distantFuture = [NSDate distantFuture];
+  NSEvent *lastEvent;
+  NSIndexSet *oldSelectedRows;
+  BOOL startedPeriodicEvents = NO;
+  BOOL mouseUp = NO;
+  BOOL done = NO;
+  BOOL mouseMoved = NO;
+  BOOL draggingPossible = [self _isDraggingSource];
+  BOOL getNextEvent = YES;
+  NSRect visibleRect = [self convertRect: [self visibleRect]
+                                 toView: nil];
+  float minYVisible = NSMinY (visibleRect);
+  float maxYVisible = NSMaxY (visibleRect);
+  float oldPeriod = 0;
+  int originalRow;
+  int oldRow = -1;
+  int currentRow = -1;
 
   // Pathological case -- ignore mouse down
   if ((_numberOfRows == 0) || (_numberOfColumns == 0))
@@ -3341,240 +3366,258 @@
       return; 
     }
   
-  clickCount = [theEvent clickCount];
-  if (clickCount > 2)
-    {
-      return;
-    }
-
   // Determine row and column which were clicked
   location = [self convertPoint: initialLocation fromView: nil];
   _clickedRow  = [self rowAtPoint: location];
+  originalRow = _clickedRow;
   _clickedColumn = [self columnAtPoint: location];
 
-  if (clickCount == 2)
+      
+  selectionMode = 0;
+  if (_allowsMultipleSelection == YES)
     {
-      // Double-click event
-      NSTableColumn *tb;
-
-      if ([self isRowSelected: _clickedRow] == NO)
-        {
-         return;
-       }
+      selectionMode |= ALLOWS_MULTIPLE;
+    }
 
-      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: YES];
-       }
-    }
-  else 
-    {
-      // Selection
-      unsigned int modifiers = [theEvent modifierFlags];
-      unsigned int eventMask = (NSLeftMouseUpMask 
-                               | NSLeftMouseDownMask
-                               | NSLeftMouseDraggedMask 
-                               | NSPeriodicMask);
-      unsigned selectionMode;
-      NSPoint mouseLocationWin;
-      NSPoint mouseLocationView;
-      NSDate *distantFuture = [NSDate distantFuture];
-      NSEvent *lastEvent;
-      NSIndexSet *oldSelectedRows;
-      BOOL startedPeriodicEvents = NO;
-      BOOL mouseUp = NO;
-      BOOL done = NO;
-      BOOL mouseMoved = NO;
-      BOOL draggingPossible = [self _isDraggingSource];
-      NSRect visibleRect = [self convertRect: [self visibleRect]
-                                toView: nil];
-      float minYVisible = NSMinY (visibleRect);
-      float maxYVisible = NSMaxY (visibleRect);
-      float oldPeriod = 0;
-      int originalRow = _clickedRow;
-      int oldRow = -1;
-      int currentRow = -1;
+  if (_allowsEmptySelection == YES)
+    {
+      selectionMode |= ALLOWS_EMPTY;
+    }
       
-      selectionMode = 0;
-      if (_allowsMultipleSelection == YES)
-       {
-         selectionMode |= ALLOWS_MULTIPLE;
-       }
-
-      if (_allowsEmptySelection == YES)
-       {
-         selectionMode |= ALLOWS_EMPTY;
-       }
+  if (modifiers & NSShiftKeyMask)
+    {
+      selectionMode |= SHIFT_DOWN;
+    }
       
-      if (modifiers & NSShiftKeyMask)
+  if (![_selectedRows containsIndex: _clickedRow])
+    {
+      selectionMode |= ADDING_ROW;
+    }
+
+  if (modifiers & NSControlKeyMask)
+    {
+      selectionMode |= CONTROL_DOWN;
+      if (_allowsMultipleSelection == YES)
        {
+         originalRow = _selectedRow;
          selectionMode |= SHIFT_DOWN;
-       }
-      
-      if (![_selectedRows containsIndex: _clickedRow])
-       {
          selectionMode |= ADDING_ROW;
        }
-
-      if (modifiers & NSControlKeyMask)
-       {
-         selectionMode |= CONTROL_DOWN;
-         if (_allowsMultipleSelection == YES)
-           {
-             originalRow = _selectedRow;
-             selectionMode |= SHIFT_DOWN;
-             selectionMode |= ADDING_ROW;
-           }
-       }
+    }
       
       // is the delegate ok for a new selection ?
-      if ([self _shouldSelectionChange] == NO)
-       {
-         return;
-       }
+  if ([self _shouldSelectionChange] == NO)
+    {
+      return;
+    }
 
-      // if we are in column selection mode, stop it
-      [self _setSelectingColumns: NO];
+  // if we are in column selection mode, stop it
+  [self _setSelectingColumns: NO];
 
-      // let's sort the _selectedRows
-      oldSelectedRows = [_selectedRows copy];
-      mouseLocationView = location;
-      lastEvent = theEvent;
+  // 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
-         tb = [_tableColumns objectAtIndex: _clickedColumn];
-         // It is unclear, if we should copy the cell here, as we do on 
editing.
-         cell = [tb dataCellForRow: _clickedRow];
-         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 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];
-         [self setNeedsDisplayInRect: cellFrame];
-         lastEvent = [NSApp currentEvent];
-       }
-
-      while (done != YES)
-       {
-         /*
-         Wrap each iteration in an autorelease pool. Otherwise, we end
-         up allocating huge amounts of objects if the button is held
-         down for a long time.
-         */
-         CREATE_AUTORELEASE_POOL(arp);
-         BOOL shouldComputeNewSelection = NO;
+  while (done != YES)
+    {
+      /*
+         Wrap each iteration in an autorelease pool. Otherwise, we end
+         up allocating huge amounts of objects if the button is held
+         down for a long time.
+       */
+      CREATE_AUTORELEASE_POOL(arp);
+      BOOL shouldComputeNewSelection = NO;
 
-         switch ([lastEvent type])
-           {
-           case NSLeftMouseUp:
-             mouseLocationWin = [lastEvent locationInWindow]; 
-             if ((mouseLocationWin.y > minYVisible) 
+      switch ([lastEvent type])
+        {
+         case NSLeftMouseUp:
+           mouseLocationWin = [lastEvent locationInWindow]; 
+           if ((mouseLocationWin.y > minYVisible) 
                  && (mouseLocationWin.y < maxYVisible))
-               {
-                 // mouse dragged within table
-                 if (startedPeriodicEvents == YES)
-                   {
-                     [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;
-                   }
-               }
-             else
-               {
-                 // Mouse dragged out of the table
-                 // we don't care
-               }
-             done = YES;
-             break;
+             {
+               // mouse dragged within table
+               if (startedPeriodicEvents == YES)
+                 {
+                   [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 = NO;
+                    computeNewSelection(self,
+                                  oldSelectedRows,
+                                  _selectedRows,
+                                  originalRow,
+                                  oldRow,
+                                  currentRow,
+                                  &_selectedRow,
+                                  selectionMode);
+                   [self displayIfNeeded]; 
+                 }
+               
+               if (draggingPossible == YES)
+                 {
+                   NSTableColumn *tb;
+                   NSCell *cell;
+                   NSRect cellFrame;
+                   id originalValue;
+                     
+                   tb = [_tableColumns objectAtIndex: _clickedColumn];
+                   cell = [tb dataCellForRow: _clickedRow];
+                   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];
+                   /* send the orignal mouse down event
+                    * NSCell -trackMouse:... needs to be able to handle
+                    * mouseUp being the -[NSApp currentEvent]
+                    * this also means that cells which are continuous or
+                    * rely on NSLeftMouseDragged wont work if dragging is
+                    * possible.
+                    */
+                    if ([cell trackMouse: theEvent 
+                                  inRect: cellFrame
+                                  ofView: self
+                            untilMouseUp:[[cell class]
+                                            prefersTrackingUntilMouseUp]])
+                      {
+                        id newValue = [cell objectValue];
+
+                        if ([tb isEditable]
+                            && ![originalValue isEqual: newValue])
+                          {
+                            [self _setObjectValue: newValue 
+                                   forTableColumn: tb
+                                              row: _clickedRow];
+                          }
+                      }
+                    RELEASE(originalValue);    
+                    [cell setHighlighted: NO];
+                    [self setNeedsDisplayInRect: cellFrame];
+                 }
+             }
+           else
+             {
+               // Mouse dragged out of the table
+               // we don't care
+             }
+           done = YES;
+         break;
 
-           case NSLeftMouseDown:
-           case NSLeftMouseDragged:
-             mouseLocationWin = [lastEvent locationInWindow];
-             mouseLocationView = [self convertPoint: mouseLocationWin 
+         case NSLeftMouseDown:
+         case NSLeftMouseDragged:
+           if ([lastEvent type] == NSLeftMouseDown
+               && [lastEvent 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
+                   NSTableColumn *tb;
+                   NSCell *cell;
+                   NSRect cellFrame;
+                   id originalValue;
+                   
+                   tb = [_tableColumns objectAtIndex: _clickedColumn];
+                   cell = [tb dataCellForRow: _clickedRow];
+                   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: theEvent
+                               inRect: cellFrame
+                               ofView: self
+                               untilMouseUp:[[cell class]
+                                             prefersTrackingUntilMouseUp]])
+                     {
+                       id newValue = [cell objectValue];
+
+                       if ([tb isEditable] &&
+                           ![originalValue isEqual: newValue])
+                         {
+                           [self _setObjectValue: newValue 
+                                       forTableColumn: tb
+                                       row: _clickedRow];
+                         }
+                     }
+                   RELEASE(originalValue);    
+                   [cell setHighlighted: NO];
+                   [self setNeedsDisplayInRect: cellFrame];
+                   getNextEvent = (lastEvent == [NSApp currentEvent]);
+                   [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];
+                 }
+             }
+           else
+             {
+               mouseLocationWin = [lastEvent locationInWindow];
+               mouseLocationView = [self convertPoint: mouseLocationWin 
                                        fromView: nil];
 
-             if (fabs(mouseLocationWin.x - initialLocation.x) > 1
-                 || fabs(mouseLocationWin.y - initialLocation.y) > 1)
-               {
-                 mouseMoved = YES;
-               }
-
-             if (draggingPossible == YES)
-               {
-                 if (mouseLocationWin.y - initialLocation.y > 2
-                     || mouseLocationWin.y - initialLocation.y < -2)
-                   {
-                     draggingPossible = NO;
-                   }
-                 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.
-                            select the new row before dragging */
-                         computeNewSelection(self,
+               if (fabs(mouseLocationWin.x - initialLocation.x) > 1
+                   || fabs(mouseLocationWin.y - initialLocation.y) > 1)
+                 {
+                   mouseMoved = YES;
+                 }
+
+               if (draggingPossible == YES)
+                 {
+                   if (mouseLocationWin.y - initialLocation.y > 2
+                       || mouseLocationWin.y - initialLocation.y < -2)
+                     {
+                       draggingPossible = NO;
+                     }
+                   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.
+                              select the new row before dragging */
+                           computeNewSelection(self,
                                              oldSelectedRows, 
                                              _selectedRows,
                                              originalRow,
@@ -3582,177 +3625,222 @@
                                              currentRow,
                                              &_selectedRow,
                                              selectionMode);
-                       }
+                         }
 
-                     rows = [self _selectedRowArray];
-                     pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
-                     if ([self _writeRows: rows
+                       rows = [self _selectedRowArray];
+                       pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+                       if ([self _writeRows: rows
                                toPasteboard: pboard] == YES)
-                       {
-                         NSPoint       p = NSZeroPoint;
-                         NSImage       *dragImage;
-                         NSSize        s;
+                         {
+                           NSPoint     p = NSZeroPoint;
+                           NSImage     *dragImage;
+                           NSSize      s;
 
-                         dragImage = [self dragImageForRows: rows
+                           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;
+                           /*
+                            * 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
+                           [self dragImage: dragImage
                                       at: p
                                   offset: NSMakeSize(0, 0)
                                    event: theEvent
                               pasteboard: pboard
                                   source: self
                                slideBack: YES];
-                         return;
-                       }
-                     else
-                       {
-                         draggingPossible = NO;
-                       }
-                   }
-               }
-             else if ((mouseLocationWin.y > minYVisible) 
-                      && (mouseLocationWin.y < maxYVisible))
-               {
-                 // mouse dragged within table
-                 if (startedPeriodicEvents == YES)
-                   {
-                     [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;
-                   }
-               }
-             else
-               {
-                 // Mouse dragged out of the table
-                 float period = computePeriod(mouseLocationWin, 
-                                              minYVisible, 
-                                              maxYVisible);
-
-                 if (startedPeriodicEvents == YES)
-                   {
-                     /* Check - if the mouse did not change zone, 
-                        we do nothing */
-                     if (period == oldPeriod)
-                       break;
-
-                     [NSEvent stopPeriodicEvents];
-                   }
-                 /* Start periodic events */
-                 oldPeriod = period;
-                 [NSEvent startPeriodicEventsAfterDelay: 0
-                          withPeriod: oldPeriod];
-                 startedPeriodicEvents = YES;
-                 if (mouseLocationWin.y <= minYVisible) 
-                   mouseUp = NO;
-                 else
-                   mouseUp = YES;
-               }
-             break;
-           case NSPeriodic:
-             if (mouseUp == NO)
-               {
-                 /* mouse below the table */
-                 if (currentRow < _numberOfRows - 1)
-                   {
-                     oldRow = currentRow;
-                     currentRow++;
-                     [self scrollRowToVisible: currentRow];
-                     if (draggingPossible == NO)
-                       shouldComputeNewSelection = YES;
-                   }
-               }
-             else
-               {
-                 if (currentRow > 0)
-                   {
-                     /* mouse above the table */
-                     oldRow = currentRow;
-                     currentRow--;
-                     [self scrollRowToVisible: currentRow];
-                     if (draggingPossible == NO)
-                       shouldComputeNewSelection = YES;
-                   }
-               }
-             break;
-           default:
+                           return;
+                         }
+                       else
+                         {
+                           draggingPossible = NO;
+                         }
+                     }
+                 }
+               else if ((mouseLocationWin.y > minYVisible) 
+                        && (mouseLocationWin.y < maxYVisible))
+                 {
+                   NSTableColumn *tb;
+                   NSCell *cell;
+                   NSRect cellFrame;
+                   id originalValue;
+                   // Prepare the cell
+                   // mouse dragged within table
+                   if (startedPeriodicEvents == YES)
+                     {
+                       [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;
+                     }
+                   
+                   tb = [_tableColumns objectAtIndex: _clickedColumn];
+                   cell = [tb dataCellForRow: _clickedRow];
+                   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: theEvent
+                               inRect: cellFrame
+                               ofView: self
+                               untilMouseUp:[[cell class]
+                                             prefersTrackingUntilMouseUp]])
+                     {
+                       id newValue = [cell objectValue];
+
+                       if ([tb isEditable] &&
+                           ![originalValue isEqual: newValue])
+                         {
+                           [self _setObjectValue: newValue 
+                                       forTableColumn: tb
+                                       row: _clickedRow];
+                         }
+                     }
+                   RELEASE(originalValue);    
+                   [cell setHighlighted: NO];
+                   [self setNeedsDisplayInRect: cellFrame];
+                   getNextEvent = (lastEvent == [NSApp currentEvent]);
+                 }
+               else
+                 {
+                   // Mouse dragged out of the table
+                   float period = computePeriod(mouseLocationWin, 
+                                                minYVisible, 
+                                                maxYVisible);
+
+                   if (startedPeriodicEvents == YES)
+                     {
+                       /* Check - if the mouse did not change zone, 
+                          we do nothing */
+                       if (period == oldPeriod)
+                         break;
+
+                       [NSEvent stopPeriodicEvents];
+                     }
+                   /* Start periodic events */
+                   oldPeriod = period;
+                   [NSEvent startPeriodicEventsAfterDelay: 0
+                            withPeriod: oldPeriod];
+                   startedPeriodicEvents = YES;
+                   if (mouseLocationWin.y <= minYVisible) 
+                     mouseUp = NO;
+                   else
+                     mouseUp = YES;
+                 }
+             }      
              break;
-           }
+         case NSPeriodic:
+           if (mouseUp == NO)
+             {
+               /* mouse below the table */
+               if (currentRow < _numberOfRows - 1)
+                 {
+                   oldRow = currentRow;
+                   currentRow++;
+                   [self scrollRowToVisible: currentRow];
+                   if (draggingPossible == NO)
+                     shouldComputeNewSelection = YES;
+                 }
+             }
+           else
+             {
+               if (currentRow > 0)
+                 {
+                   /* mouse above the table */
+                   oldRow = currentRow;
+                   currentRow--;
+                   [self scrollRowToVisible: currentRow];
+                   if (draggingPossible == NO)
+                     shouldComputeNewSelection = YES;
+                 }
+             }
+           break;
+         default:
+           break;
+         }
 
-         if (shouldComputeNewSelection == YES)
-           {
-             computeNewSelection(self,
-                                 oldSelectedRows, 
-                                 _selectedRows,
-                                 originalRow,
-                                 oldRow,
-                                 currentRow,
-                                 &_selectedRow,
-                                 selectionMode);
-             [self displayIfNeeded];
-           }
-         if (done == NO)
-           {
+       if (shouldComputeNewSelection == YES)
+         {
+           computeNewSelection(self,
+                               oldSelectedRows, 
+                               _selectedRows,
+                               originalRow,
+                               oldRow,
+                               currentRow,
+                               &_selectedRow,
+                               selectionMode);
+           [self displayIfNeeded];
+         }
+       if (done == NO)
+         {
+           if (getNextEvent == YES)
              lastEvent = [NSApp nextEventMatchingMask: eventMask 
                                 untilDate: distantFuture
                                 inMode: NSEventTrackingRunLoopMode 
-                                dequeue: YES]; 
-           }
-         DESTROY(arp);
-       }
+                                dequeue: YES];
+           else
+             {
+               lastEvent = [NSApp currentEvent];
+               getNextEvent = YES;
+             }
+         }
+       
+       DESTROY(arp);
+    }
 
-      if (startedPeriodicEvents == YES)
-       [NSEvent stopPeriodicEvents];
+  if (startedPeriodicEvents == YES)
+    [NSEvent stopPeriodicEvents];
 
-      if (![_selectedRows isEqualToIndexSet: oldSelectedRows])
-       {
-         [self _postSelectionDidChangeNotification];
-       }
+  if (![_selectedRows isEqualToIndexSet: oldSelectedRows])
+    {
+      [self _postSelectionDidChangeNotification];
+    }
 
       /* If this was a simple click (ie. no dragging), we send our action. */
-      if (!mouseMoved)
-       {
-         /*
-         _clickedRow and _clickedColumn are already set at the start of
-         this function.
-
-         TODO: should we ask the data source/column for the cell for this
-         row/column and check whether it has its own action/target?
-         */
-         [self sendAction: _action  to: _target];
-       }
-      return;
+  if (!mouseMoved)
+    {
+      /*
+        _clickedRow and _clickedColumn are already set at the start of
+        this function.
+
+        cell action is already taken care of in the trackMouse:... code above.
+       */
+       [self sendAction: _action  to: _target];
     }
+      return;
 }
 
 /* 
Index: NSCell.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSCell.m,v
retrieving revision 1.170
diff -u -r1.170 NSCell.m
--- NSCell.m    26 May 2005 02:52:43 -0000      1.170
+++ NSCell.m    4 Jun 2005 08:51:53 -0000
@@ -1362,8 +1362,10 @@
       NSEventType      eventType;
       BOOL             pointIsInCell;
       unsigned         periodCount = 0;
-
-      theEvent = [theApp nextEventMatchingMask: event_mask
+      if (theEvent != [NSApp currentEvent])
+       theEvent = [NSApp currentEvent];
+      else
+        theEvent = [theApp nextEventMatchingMask: event_mask
                                     untilDate: nil
                                        inMode: NSEventTrackingRunLoopMode
                                       dequeue: YES];

reply via email to

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