* NSCell.m: changed implementation of trackMouse method so that it does

not hightlight the cell.  The new behavior is as described in the spec
		for NSControl, NSMatrix and NSCell.  According to the spec it is the
		responsibility of the control to highlight the cell prior to calling
		cell's track method.
	* NSMatrix.m: rewrote mousedown to more closely mimic the NS/OS behavior.
	* NSButton.m: modified to support new behavior of NSCell's track mode.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2865 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Felipe A. Rodriguez 1998-07-26 01:15:17 +00:00
parent dbf75faa59
commit 753def7785
3 changed files with 217 additions and 247 deletions

View file

@ -314,6 +314,8 @@ id gnustep_gui_nsbutton_class = nil;
e = theEvent;
while (!done)
{
[cell highlight: YES withFrame: bounds inView: self]; // highlight cell
[self setNeedsDisplayInRect:bounds];
mouseUp = [cell trackMouse: e inRect: bounds
ofView:self untilMouseUp:YES];
e = [theApp currentEvent];

View file

@ -646,17 +646,8 @@
if (![self startTrackingAt: point inView: controlView])
return NO;
// If point is in cellFrame then highlight the cell
if ([controlView mouse: point inRect: cellFrame]) {
[self highlight:YES withFrame:cellFrame inView:controlView];
#if 1
[controlView setNeedsDisplayInRect:cellFrame];
#else
[[controlView window] flushWindow];
#endif
}
else
return NO;
if (![controlView mouse: point inRect: cellFrame])
return NO; // point is not in cell
if ([theEvent type] == NSLeftMouseDown
&& (action_mask & NSLeftMouseDownMask))
@ -696,40 +687,14 @@
pointIsInCell = NO;
// unhighlight cell is highlighted
if (cell_highlighted) {
[self highlight: NO withFrame: cellFrame
inView: controlView];
#if 1
[controlView setNeedsDisplayInRect:cellFrame];
#else
[self drawWithFrame: cellFrame inView: controlView];
[[controlView window] flushWindow];
#endif
}
// Do we now return or keep tracking
if (!([[self class] prefersTrackingUntilMouseUp] && flag)) {
// Do we return now or keep tracking
if (![[self class] prefersTrackingUntilMouseUp] && flag) {
NSDebugLog(@"NSCell return immediately\n");
done = YES;
}
}
else {
// Point is in cell
pointIsInCell = YES;
// highlight cell if not highlighted
if (!cell_highlighted) {
[self highlight: YES withFrame: cellFrame
inView: controlView];
#if 1
[controlView setNeedsDisplayInRect:cellFrame];
#else
//[self drawWithFrame: cellFrame inView: controlView];
[[controlView window] flushWindow];
#endif
}
}
else
pointIsInCell = YES; // Point is in cell
// should we continue tracking?
if (!done
@ -743,7 +708,7 @@
NSDebugLog(@"NSCell mouse went up\n");
mouseWentUp = YES;
done = YES;
if ((action_mask & NSLeftMouseUpMask))
if ((action_mask & NSLeftMouseUpMask))
[(NSControl*)controlView sendAction:action to:target];
}
else {

View file

@ -775,14 +775,13 @@ static int mouseDownFlags = 0;
[self display];
}
- (void)selectCellAtRow:(int)row
column:(int)column
- (void)selectCellAtRow:(int)row column:(int)column
{
NSCell* aCell = [self cellAtRow:row column:column];
if (mode == NSRadioModeMatrix) {
/* Don't allow loosing of selection if in radio mode and empty selection
not allowed. Otherwise deselect the selected cell. */
/* Don't allow loss of selection if in radio mode and empty selection
is not allowed. Otherwise deselect the selected cell. */
if (!aCell && !allowsEmptySelection)
return;
else if (selectedCell)
@ -885,13 +884,18 @@ static int mouseDownFlags = 0;
- (void)selectText:(id)sender
{
fprintf(stderr, " NSMatrix: selectText --- ");
// TODO
}
- (id)selectTextAtRow:(int)row
column:(int)column
- (id)selectTextAtRow:(int)row column:(int)column
{
// TODO
NSCell* aCell = [self cellAtRow:row column:column];
fprintf(stderr, " NSMatrix: selectTextAtRow --- ");
return nil;
}
@ -1131,223 +1135,222 @@ static int mouseDownFlags = 0;
- (void)mouseDown:(NSEvent*)theEvent
{
BOOL isBetweenCells, insideBounds;
int row, column;
unsigned eventMask = NSLeftMouseUpMask | NSLeftMouseDownMask
| NSMouseMovedMask | NSLeftMouseDraggedMask | NSPeriodicMask;
NSPoint lastLocation = [theEvent locationInWindow];
NSEvent* lastEvent = nil;
BOOL done = NO;
NSRect rect;
id aCell, previousCell = nil;
NSRect previousCellRect;
MPoint anchor;
BOOL isBetweenCells, insideBounds;
int row, column;
unsigned eventMask = NSLeftMouseUpMask | NSLeftMouseDownMask | NSMouseMovedMask
| NSLeftMouseDraggedMask | NSPeriodicMask;
NSPoint lastLocation = [theEvent locationInWindow];
NSEvent* lastEvent = nil;
BOOL done = NO;
NSRect rect;
id aCell, previousCell = nil, selectedCellTarget;
NSRect previousCellRect;
static MPoint anchor = {0, 0};
mouseDownFlags = [theEvent modifierFlags];
lastLocation = [self convertPoint:lastLocation fromView:nil];
if (mode != NSTrackModeMatrix)
[NSEvent startPeriodicEventsAfterDelay:0.05 withPeriod:0.05];
ASSIGN(lastEvent, theEvent);
mouseDownFlags = [theEvent modifierFlags];
lastLocation = [self convertPoint:lastLocation fromView:nil];
if ((mode != NSTrackModeMatrix) && (mode != NSHighlightModeMatrix))
[NSEvent startPeriodicEventsAfterDelay:0.05 withPeriod:0.05];
ASSIGN(lastEvent, theEvent);
// capture mouse
[[self window] captureMouse: self];
[[self window] captureMouse: self]; // grab the mouse
[self lockFocus];
// selection occurs in two stages, the first stage loops
// until the mouse goes up while the second stage completes
// the process by sending actions and displaying the cell
// as it should appear after the selection process
while (!done)
{ // begin selection
BOOL shouldProceedEvent = NO;
[self lockFocus];
insideBounds = [self _getRow:&row
column:&column
forPoint:lastLocation
above:NO right:NO
isBetweenCells:&isBetweenCells];
if (insideBounds && !isBetweenCells)
{
aCell = [self cellAtRow:row column:column];
rect = [self cellFrameAtRow:row column:column];
while (!done) {
BOOL shouldProceedEvent = NO;
switch (mode)
{
case NSTrackModeMatrix: // in Track mode
ASSIGN(selectedCell, aCell); // the cell should
selectedRow = row; // track the mouse
selectedColumn = column; // until the cursor
// either leaves
if([aCell trackMouse:lastEvent // the cellframe or
inRect:rect // mouse goes up
ofView:self
untilMouseUp:YES]) // YES if mouse
done = YES; // went up in cell
break;
insideBounds = [self _getRow:&row
column:&column
forPoint:lastLocation
above:NO right:NO
isBetweenCells:&isBetweenCells];
if (insideBounds && !isBetweenCells) {
aCell = [self cellAtRow:row column:column];
rect = [self cellFrameAtRow:row column:column];
case NSHighlightModeMatrix:
[aCell highlight: YES withFrame: rect inView: self];
[self setNeedsDisplayInRect:rect]; // Highlight mode
ASSIGN(selectedCell, aCell); // is like Track
selectedRow = row; // mode except that
selectedColumn = column; // the cell is lit
// before it begins
if([aCell trackMouse:lastEvent // tracking and
inRect:rect // unlit afterwards
ofView:self
untilMouseUp:YES]) // YES if mouse
done = YES; // went up in cell
[aCell highlight: NO withFrame: rect inView: self];
[self setNeedsDisplayInRect:rect];
break;
switch (mode) {
case NSTrackModeMatrix:
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
case NSRadioModeMatrix: // Radio mode allows no
if (previousCell == aCell) // more than one cell
break; // to be selected
[selectedCell trackMouse:lastEvent
inRect:rect
ofView:self
untilMouseUp:YES];
done = YES;
break;
[selectedCell setState:0]; // deselect previous
if (!previousCell) // selection
previousCellRect = [self cellFrameAtRow:selectedRow
column:selectedColumn];
[selectedCell highlight:NO
withFrame:previousCellRect
inView:self];
((tMatrix)selectedCells)->matrix[selectedRow]
[selectedColumn] = NO;
[self setNeedsDisplayInRect:previousCellRect];
case NSHighlightModeMatrix:
if (previousCell == aCell)
break;
ASSIGN(selectedCell, aCell); // select current
selectedRow = row; // selection
selectedColumn = column;
[aCell setState:1];
[aCell highlight:YES withFrame:rect inView:self];
((tMatrix)selectedCells)->matrix[row][column] = YES;
[self setNeedsDisplayInRect:rect];
break;
[previousCell highlight:NO withFrame:previousCellRect inView:self];
[self setNeedsDisplayInRect:previousCellRect];
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
[selectedCell highlight:YES withFrame:rect inView:self];
[self setNeedsDisplayInRect:rect];
break;
case NSListModeMatrix: // List mode allows
{ // multiple selection
unsigned modifiers = [lastEvent modifierFlags];
case NSRadioModeMatrix:
if (previousCell == aCell)
break;
if (previousCell == aCell)
break; // When the user first clicks on a cell
// we clear the existing selection
if (!previousCell) // unless the Alternate or Shift keys
{ // have been pressed.
if (!(modifiers & NSShiftKeyMask) &&
!(modifiers & NSAlternateKeyMask))
{
[self deselectAllCells];
anchor = MakePoint (column, row);
} // Consider the selected cell as the
// anchor from which to extend the
// selection to the current cell
if (!(modifiers & NSAlternateKeyMask))
{
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
[selectedCell setState:1];
[selectedCell highlight:YES
withFrame:rect
inView:self];
((tMatrix)selectedCells)->matrix[row][column] =YES;
[self setNeedsDisplayInRect:rect];
break;
}
}
if (selectionByRect)
[self _selectRectUsingAnchor:anchor
last:MakePoint (selectedColumn, selectedRow)
current:MakePoint (column, row)];
else
[self _selectContinuousUsingAnchor:anchor
last:MakePoint (selectedColumn, selectedRow)
current:MakePoint (column, row)];
/* At the first click, deselect the selected cell */
if (!previousCell) {
NSRect f = [self cellFrameAtRow:selectedRow column:selectedColumn];
[selectedCell highlight:NO withFrame:f inView:self]; // FAR
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
break;
}
}
previousCell = aCell;
previousCellRect = rect;
[self scrollRectToVisible:rect];
}
[self deselectSelectedCell];
[self deselectAllCells]; // FAR
[self setNeedsDisplayInRect:f];
}
else {
[previousCell highlight:NO withFrame:previousCellRect inView:self];
[self setNeedsDisplayInRect:previousCellRect];
}
if (done) // if done break out of
break; // the selection loop
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
[selectedCell highlight:YES withFrame:rect inView:self];
((tMatrix)selectedCells)->matrix[row][column] = YES; // FAR
// [self setNeedsDisplayInRect:rect]; // FAR
while (!shouldProceedEvent)
{ // Get the next event
theEvent = [[NSApplication sharedApplication]
nextEventMatchingMask:eventMask
untilDate:[NSDate distantFuture]
inMode:NSEventTrackingRunLoopMode
dequeue:YES];
switch ([theEvent type])
{
case NSPeriodic:
NSDebugLog(@"NSMatrix: got NSPeriodic event\n");
shouldProceedEvent = YES;
break;
case NSLeftMouseUp:
done = YES;
case NSLeftMouseDown:
default: // if in Track or Highlight modes break
// out and check if mouse is in a cell
if ((mode == NSTrackModeMatrix) ||
(mode == NSHighlightModeMatrix))
shouldProceedEvent = YES;
NSDebugLog(@"NSMatrix: got event of type: %d\n",
[theEvent type]);
ASSIGN(lastEvent, theEvent);
continue;
}
}
lastLocation = [lastEvent locationInWindow];
lastLocation = [self convertPoint:lastLocation fromView:nil];
} // a mouse up terminates the selection
// loop. we then need to complete the
// selection process and send actions
[[self window] releaseMouse: self]; // Release the mouse
[self selectCellAtRow:row column:column];
if ([lastEvent clickCount] > 1) // double click
[target performSelector:doubleAction withObject:self];
break;
case NSListModeMatrix: {
unsigned modifiers = [lastEvent modifierFlags];
if (previousCell == aCell)
break;
/* When the user first clicks on a cell we clear the existing
selection unless Alternate or Shift key modifiers have been
pressed. */
if (!previousCell) {
if (!(modifiers & NSShiftKeyMask) &&
!(modifiers & NSAlternateKeyMask))
[self deselectAllCells];
if ((modifiers & NSAlternateKeyMask))
/* Consider the selected cell as the anchor to allow extending
the selection to the current cell. */
anchor = MakePoint (selectedColumn, selectedRow);
else {
anchor = MakePoint (column, row);
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
[selectedCell setState:1];
[selectedCell highlight:YES withFrame:rect inView:self];
((tMatrix)selectedCells)->matrix[row][column] = YES;
[self setNeedsDisplayInRect:rect];
break;
}
}
if (selectionByRect)
[self _selectRectUsingAnchor:anchor
last:MakePoint (selectedColumn, selectedRow)
current:MakePoint (column, row)];
else
[self _selectContinuousUsingAnchor:anchor
last:MakePoint (selectedColumn, selectedRow)
current:MakePoint (column, row)];
ASSIGN(selectedCell, aCell);
selectedRow = row;
selectedColumn = column;
break;
}
}
previousCell = aCell;
previousCellRect = rect;
[self scrollRectToVisible:rect];
}
if (done)
break;
/* Get the next event */
while (!shouldProceedEvent) {
theEvent = [[NSApplication sharedApplication]
nextEventMatchingMask:eventMask
untilDate:[NSDate distantFuture]
inMode:NSEventTrackingRunLoopMode
dequeue:YES];
switch ([theEvent type]) {
case NSPeriodic:
NSDebugLog(@"NSMatrix: got NSPeriodic event\n");
shouldProceedEvent = YES;
break;
case NSLeftMouseUp:
done = YES;
// shouldProceedEvent = YES;
ASSIGN(lastEvent, theEvent);
break;
case NSLeftMouseDown:
// shouldProceedEvent = YES;
ASSIGN(lastEvent, theEvent);
break;
default:
NSDebugLog(@"NSMatrix: got event type: %d\n", [theEvent type]);
ASSIGN(lastEvent, theEvent);
continue;
}
}
lastLocation = [lastEvent locationInWindow];
lastLocation = [self convertPoint:lastLocation fromView:nil];
}
// Release mouse
[[self window] releaseMouse: self];
/* Finalize the selection */
switch (mode) {
case NSTrackModeMatrix:
case NSHighlightModeMatrix:
[selectedCell setState:![selectedCell state]];
[selectedCell highlight:NO withFrame:rect inView:self];
[self setNeedsDisplayInRect:rect];
break;
case NSRadioModeMatrix:
[selectedCell setState:1];
[selectedCell highlight:NO withFrame:rect inView:self];
[self setNeedsDisplayInRect:rect];
break;
case NSListModeMatrix:
break;
}
if ([selectedCell target]) // send single click action
[[selectedCell target] performSelector:[selectedCell action]
withObject:self];
else
{
if (target)
switch (mode) // Finalize the selection
{
case NSTrackModeMatrix:
case NSHighlightModeMatrix:
[selectedCell setState:![selectedCell state]];
case NSRadioModeMatrix:
[selectedCell highlight:NO withFrame:rect inView:self];
[self setNeedsDisplayInRect:rect];
break;
case NSListModeMatrix: // save last position after
anchor = MakePoint (column, row); // mouse up as new anchor
break; // point in List mode
}
// in Track or Highlight modes the single click
// action has already been sent by the cell to
// it's target (if it has one)
if ((mode != NSTrackModeMatrix) && (mode != NSHighlightModeMatrix) &&
(selectedCellTarget = [selectedCell target]))
[selectedCellTarget performSelector:[selectedCell action]
withObject:self];
else // selected cell has no target
{ // so send single click action
if (target) // to matrix's (self) target
[target performSelector:action withObject:self];
}
if (target && ([lastEvent clickCount] > 1)) // send double click action
// click count > 1 indicates a mouse double click
if (target && doubleAction && ([lastEvent clickCount] > 1))
[target performSelector:doubleAction withObject:self];
[self unlockFocus];
if (mode != NSTrackModeMatrix)
[NSEvent stopPeriodicEvents];
[lastEvent release];
[self unlockFocus];
if ((mode != NSTrackModeMatrix) && (mode != NSHighlightModeMatrix))
[NSEvent stopPeriodicEvents];
[lastEvent release];
[self setNeedsDisplayInRect:rect];
}