Implemented focus rings around cell so editable cells in a NSTableView appear by default with a focus ring when being edited. Some minor adjustments will be required to make it work perfectly with other controls, such as NSMatrix, NSForm, and NSPopUpButton.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/gnustep_testplant_branch@36066 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Frank Le Grand 2013-02-06 20:32:45 +00:00
parent 21e571b923
commit bca3428387
6 changed files with 73 additions and 18 deletions

View file

@ -146,6 +146,8 @@ NSDrawBezel(const NSRect aRect, const NSRect clipRect)
NSDrawGrayBezel(aRect, clipRect); NSDrawGrayBezel(aRect, clipRect);
} }
APPKIT_EXPORT void NSFocusRingFrameRect(NSRect aRect);
/** Draws a rectangle along the inside of aRect. The rectangle will be /** Draws a rectangle along the inside of aRect. The rectangle will be
black, dotted (using 1 point dashes), and will have a line width black, dotted (using 1 point dashes), and will have a line width
of 1 point. */ of 1 point. */

View file

@ -44,6 +44,7 @@
#import "AppKit/NSView.h" #import "AppKit/NSView.h"
#import "AppKit/NSWindow.h" #import "AppKit/NSWindow.h"
#import "AppKit/DPSOperators.h" #import "AppKit/DPSOperators.h"
#import "AppKit/NSBezierPath.h"
char **NSArgv = NULL; char **NSArgv = NULL;
@ -642,6 +643,7 @@ NSRectFillListWithColorsUsingOperation(const NSRect *rects,
/* Various functions for drawing bordered rectangles. */ /* Various functions for drawing bordered rectangles. */
// TODO: Should we retire NSDottedFrameRect in favor of NSFocusRingFrameRect?
void NSDottedFrameRect(const NSRect aRect) void NSDottedFrameRect(const NSRect aRect)
{ {
float dot_dash[] = {1.0, 1.0}; float dot_dash[] = {1.0, 1.0};
@ -656,6 +658,22 @@ void NSDottedFrameRect(const NSRect aRect)
DPSgrestore(ctxt); DPSgrestore(ctxt);
} }
void NSFocusRingFrameRect(const NSRect aRect)
{
NSGraphicsContext *ctxt = GSCurrentContext();
[ctxt saveGraphicsState];
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(NSMinX(aRect) - 1.0, NSMinY(aRect) - 1.0, NSWidth(aRect) + 2.0, NSHeight(aRect) + 2.0)
xRadius:3
yRadius:3];
[path setLineWidth:2];
// TODO: Use system color for the focus ring
//NSColor *ringColor = [NSColor keyboardFocusIndicatorColor];
NSColor *ringColor = [NSColor colorWithCalibratedRed:0.49 green:0.68 blue:0.85 alpha:1.0];
[ringColor set];
[path stroke];
[ctxt restoreGraphicsState];
}
void NSFrameRect(const NSRect aRect) void NSFrameRect(const NSRect aRect)
{ {
NSFrameRectWithWidth(aRect, 1.0); NSFrameRectWithWidth(aRect, 1.0);

View file

@ -299,7 +299,7 @@
- (void) drawFocusFrame: (NSRect) frame view: (NSView*) view - (void) drawFocusFrame: (NSRect) frame view: (NSView*) view
{ {
NSDottedFrameRect(frame); NSFocusRingFrameRect(frame);
} }
- (void) drawWindowBackground: (NSRect) frame view: (NSView*) view - (void) drawWindowBackground: (NSRect) frame view: (NSView*) view
@ -2647,7 +2647,12 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
tb = [tableColumns objectAtIndex: i]; tb = [tableColumns objectAtIndex: i];
cell = [tb dataCellForRow: rowIndex]; cell = [tb dataCellForRow: rowIndex];
if (i == editedColumn && rowIndex == editedRow) if (i == editedColumn && rowIndex == editedRow)
{
[cell _setInEditing: YES]; [cell _setInEditing: YES];
[cell setShowsFirstResponder:YES];
[cell setFocusRingType:NSFocusRingTypeDefault];
}
[tableView _willDisplayCell: cell [tableView _willDisplayCell: cell
forTableColumn: tb forTableColumn: tb
row: rowIndex]; row: rowIndex];
@ -2658,7 +2663,11 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil};
row: rowIndex]; row: rowIndex];
[cell drawWithFrame: drawingRect inView: tableView]; [cell drawWithFrame: drawingRect inView: tableView];
if (i == editedColumn && rowIndex == editedRow) if (i == editedColumn && rowIndex == editedRow)
{
[cell _setInEditing: NO]; [cell _setInEditing: NO];
[cell setShowsFirstResponder:NO];
[cell setFocusRingType:NSFocusRingTypeNone];
}
} }
} }
@end @end

View file

@ -67,7 +67,8 @@
#import "GSBindingHelpers.h" #import "GSBindingHelpers.h"
#import "GNUstepGUI/GSTheme.h" #import "GNUstepGUI/GSTheme.h"
#import "GSGuiPrivate.h" #import "GSGuiPrivate.h"
#import "AppKit/NSTextFieldCell.h"
#import "AppKit/NSSearchFieldCell.h"
static Class colorClass; static Class colorClass;
static Class cellClass; static Class cellClass;
static Class fontClass; static Class fontClass;
@ -215,7 +216,6 @@ static NSColor *dtxtCol;
_action_mask = NSLeftMouseUpMask; _action_mask = NSLeftMouseUpMask;
_menu = [object_getClass(self) defaultMenu]; _menu = [object_getClass(self) defaultMenu];
[self setFocusRingType: [object_getClass(self) defaultFocusRingType]]; [self setFocusRingType: [object_getClass(self) defaultFocusRingType]];
return self; return self;
} }
@ -2232,7 +2232,13 @@ static NSColor *dtxtCol;
[textObject setDelegate: anObject]; [textObject setDelegate: anObject];
[[controlView window] makeFirstResponder: textObject]; [[controlView window] makeFirstResponder: textObject];
_cell.shows_first_responder = YES;
_cell.in_editing = YES; _cell.in_editing = YES;
// FIXME: we need to draw the focus ring, this works but
// there's something wrong about telling the view to come
// back here and draw.
[controlView setKeyboardFocusRingNeedsDisplayInRect:NSMakeRect (aRect.origin.x - 2.0, aRect.origin.y - 2.0, aRect.size.width + 4.0, aRect.size.height + 4.0)];
NSLog(@"Edited Cell: %@", self);
} }
/**<p>Ends any text editing. This method sets the text object's delegate /**<p>Ends any text editing. This method sets the text object's delegate
@ -2244,6 +2250,7 @@ static NSColor *dtxtCol;
NSClipView *clipView; NSClipView *clipView;
_cell.in_editing = NO; _cell.in_editing = NO;
_cell.shows_first_responder = NO;
[textObject setString: @""]; [textObject setString: @""];
[textObject setDelegate: nil]; [textObject setDelegate: nil];
@ -2255,6 +2262,9 @@ static NSColor *dtxtCol;
} }
else else
[textObject removeFromSuperview]; [textObject removeFromSuperview];
// FIXME: This is brutal but clears the focus ring clean.
[[self controlView] setNeedsDisplay:YES];
} }
/* /*
@ -2939,21 +2949,31 @@ static NSColor *dtxtCol;
// Private helper method // Private helper method
- (void) _drawFocusRingWithFrame: (NSRect)cellFrame inView: (NSView*)controlView - (void) _drawFocusRingWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
{ {
if (_cell.shows_first_responder BOOL inFocus = NO;
&& [[controlView window] firstResponder] == controlView) inFocus = (([[controlView window] firstResponder] == controlView)
|| ([[[controlView window] firstResponder] isKindOfClass:[NSTextView class]]
&& [[controlView window] fieldEditor:NO forObject:nil]!=nil
&& (controlView == (id)[(NSTextView *)[[controlView window] firstResponder]delegate])));
if (inFocus && [self showsFirstResponder]) // _cell.in_editing)
{ {
switch (_cell.focus_ring_type) switch (_cell.focus_ring_type)
{ {
case NSFocusRingTypeDefault: case NSFocusRingTypeDefault:
case NSFocusRingTypeExterior:
case NSFocusRingTypeNone:
// The GNUstep implementation of NSFocusRingTypeDefault draws inside
// the bezeled border of controls, this is not what appears to happen
// in Cocoa, so we force it to behave like NSFocusRingTypeExterior
[[GSTheme theme] drawFocusFrame: [self drawingRectForBounds: [[GSTheme theme] drawFocusFrame: [self drawingRectForBounds:
cellFrame] cellFrame]
view: controlView]; view: controlView];
break; break;
case NSFocusRingTypeExterior: // case NSFocusRingTypeExterior:
[[GSTheme theme] drawFocusFrame: cellFrame // [[GSTheme theme] drawFocusFrame: cellFrame
view: controlView]; // view: controlView];
break; // break;
case NSFocusRingTypeNone: // case NSFocusRingTypeNone:
default: default:
break; break;
} }

View file

@ -968,7 +968,11 @@ static NSImage *unexpandable = nil;
tb = [_tableColumns objectAtIndex: i]; tb = [_tableColumns objectAtIndex: i];
cell = [self _dataCellForTableColumn: tb row: rowIndex]; cell = [self _dataCellForTableColumn: tb row: rowIndex];
if (i == _editedColumn && rowIndex == _editedRow) if (i == _editedColumn && rowIndex == _editedRow)
{
[cell _setInEditing: YES]; [cell _setInEditing: YES];
[cell setShowsFirstResponder:YES];
[cell setFocusRingType:NSFocusRingTypeDefault];
}
[self _willDisplayCell: cell [self _willDisplayCell: cell
forTableColumn: tb forTableColumn: tb
row: rowIndex]; row: rowIndex];
@ -1035,7 +1039,11 @@ static NSImage *unexpandable = nil;
[cell drawWithFrame: drawingRect inView: self]; [cell drawWithFrame: drawingRect inView: self];
if (i == _editedColumn && rowIndex == _editedRow) if (i == _editedColumn && rowIndex == _editedRow)
{
[cell _setInEditing: NO]; [cell _setInEditing: NO];
[cell setShowsFirstResponder:NO];
[cell setFocusRingType:NSFocusRingTypeDefault];
}
} }
} }
@ -1613,8 +1621,7 @@ Also returns the child index relative to this parent. */
} }
_textObject = [_editedCell setUpFieldEditorAttributes: t]; _textObject = [_editedCell setUpFieldEditorAttributes: t];
// FIXME: Which background color do we want here? [_textObject setBackgroundColor: [NSColor textBackgroundColor]];
[_textObject setBackgroundColor: [NSColor selectedControlColor]];
[_textObject setDrawsBackground: YES]; [_textObject setDrawsBackground: YES];
drawingRect = [self frameOfCellAtColumn: columnIndex row: rowIndex]; drawingRect = [self frameOfCellAtColumn: columnIndex row: rowIndex];

View file

@ -3369,8 +3369,7 @@ byExtendingSelection: (BOOL)flag
} }
_textObject = [_editedCell setUpFieldEditorAttributes: t]; _textObject = [_editedCell setUpFieldEditorAttributes: t];
// FIXME: Which background color do we want here? [_textObject setBackgroundColor: [NSColor textBackgroundColor]];
[_textObject setBackgroundColor: [NSColor selectedControlColor]];
[_textObject setDrawsBackground: YES]; [_textObject setDrawsBackground: YES];
drawingRect = [self frameOfCellAtColumn: columnIndex row: rowIndex]; drawingRect = [self frameOfCellAtColumn: columnIndex row: rowIndex];