diff --git a/Headers/AppKit/NSGraphics.h b/Headers/AppKit/NSGraphics.h index 4f53f2e38..ff8019d53 100644 --- a/Headers/AppKit/NSGraphics.h +++ b/Headers/AppKit/NSGraphics.h @@ -146,6 +146,8 @@ NSDrawBezel(const NSRect aRect, const NSRect clipRect) NSDrawGrayBezel(aRect, clipRect); } +APPKIT_EXPORT void NSFocusRingFrameRect(NSRect aRect); + /** Draws a rectangle along the inside of aRect. The rectangle will be black, dotted (using 1 point dashes), and will have a line width of 1 point. */ diff --git a/Source/Functions.m b/Source/Functions.m index d1fea7a6a..3cc78454e 100644 --- a/Source/Functions.m +++ b/Source/Functions.m @@ -44,6 +44,7 @@ #import "AppKit/NSView.h" #import "AppKit/NSWindow.h" #import "AppKit/DPSOperators.h" +#import "AppKit/NSBezierPath.h" char **NSArgv = NULL; @@ -642,6 +643,7 @@ NSRectFillListWithColorsUsingOperation(const NSRect *rects, /* Various functions for drawing bordered rectangles. */ +// TODO: Should we retire NSDottedFrameRect in favor of NSFocusRingFrameRect? void NSDottedFrameRect(const NSRect aRect) { float dot_dash[] = {1.0, 1.0}; @@ -656,6 +658,22 @@ void NSDottedFrameRect(const NSRect aRect) 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) { NSFrameRectWithWidth(aRect, 1.0); diff --git a/Source/GSThemeDrawing.m b/Source/GSThemeDrawing.m index 4d3e3e522..b413fb2d2 100644 --- a/Source/GSThemeDrawing.m +++ b/Source/GSThemeDrawing.m @@ -299,7 +299,7 @@ - (void) drawFocusFrame: (NSRect) frame view: (NSView*) view { - NSDottedFrameRect(frame); + NSFocusRingFrameRect(frame); } - (void) drawWindowBackground: (NSRect) frame view: (NSView*) view @@ -2647,7 +2647,12 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil}; tb = [tableColumns objectAtIndex: i]; cell = [tb dataCellForRow: rowIndex]; if (i == editedColumn && rowIndex == editedRow) - [cell _setInEditing: YES]; + { + [cell _setInEditing: YES]; + [cell setShowsFirstResponder:YES]; + [cell setFocusRingType:NSFocusRingTypeDefault]; + } + [tableView _willDisplayCell: cell forTableColumn: tb row: rowIndex]; @@ -2658,7 +2663,11 @@ static NSDictionary *titleTextAttributes[3] = {nil, nil, nil}; row: rowIndex]; [cell drawWithFrame: drawingRect inView: tableView]; if (i == editedColumn && rowIndex == editedRow) - [cell _setInEditing: NO]; + { + [cell _setInEditing: NO]; + [cell setShowsFirstResponder:NO]; + [cell setFocusRingType:NSFocusRingTypeNone]; + } } } @end diff --git a/Source/NSCell.m b/Source/NSCell.m index 5cb7afdc5..776d85b08 100644 --- a/Source/NSCell.m +++ b/Source/NSCell.m @@ -67,7 +67,8 @@ #import "GSBindingHelpers.h" #import "GNUstepGUI/GSTheme.h" #import "GSGuiPrivate.h" - +#import "AppKit/NSTextFieldCell.h" +#import "AppKit/NSSearchFieldCell.h" static Class colorClass; static Class cellClass; static Class fontClass; @@ -215,7 +216,6 @@ static NSColor *dtxtCol; _action_mask = NSLeftMouseUpMask; _menu = [object_getClass(self) defaultMenu]; [self setFocusRingType: [object_getClass(self) defaultFocusRingType]]; - return self; } @@ -2232,7 +2232,13 @@ static NSColor *dtxtCol; [textObject setDelegate: anObject]; [[controlView window] makeFirstResponder: textObject]; + _cell.shows_first_responder = 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); } /**
Ends any text editing. This method sets the text object's delegate @@ -2244,6 +2250,7 @@ static NSColor *dtxtCol; NSClipView *clipView; _cell.in_editing = NO; + _cell.shows_first_responder = NO; [textObject setString: @""]; [textObject setDelegate: nil]; @@ -2255,6 +2262,9 @@ static NSColor *dtxtCol; } else [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 - (void) _drawFocusRingWithFrame: (NSRect)cellFrame inView: (NSView*)controlView { - if (_cell.shows_first_responder - && [[controlView window] firstResponder] == controlView) + BOOL inFocus = NO; + 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) { 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: cellFrame] view: controlView]; break; - case NSFocusRingTypeExterior: - [[GSTheme theme] drawFocusFrame: cellFrame - view: controlView]; - break; - case NSFocusRingTypeNone: +// case NSFocusRingTypeExterior: +// [[GSTheme theme] drawFocusFrame: cellFrame +// view: controlView]; +// break; +// case NSFocusRingTypeNone: default: break; } diff --git a/Source/NSOutlineView.m b/Source/NSOutlineView.m index 351e026aa..1066fb686 100644 --- a/Source/NSOutlineView.m +++ b/Source/NSOutlineView.m @@ -968,7 +968,11 @@ static NSImage *unexpandable = nil; tb = [_tableColumns objectAtIndex: i]; cell = [self _dataCellForTableColumn: tb row: rowIndex]; if (i == _editedColumn && rowIndex == _editedRow) - [cell _setInEditing: YES]; + { + [cell _setInEditing: YES]; + [cell setShowsFirstResponder:YES]; + [cell setFocusRingType:NSFocusRingTypeDefault]; + } [self _willDisplayCell: cell forTableColumn: tb row: rowIndex]; @@ -1035,7 +1039,11 @@ static NSImage *unexpandable = nil; [cell drawWithFrame: drawingRect inView: self]; 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]; - // FIXME: Which background color do we want here? - [_textObject setBackgroundColor: [NSColor selectedControlColor]]; + [_textObject setBackgroundColor: [NSColor textBackgroundColor]]; [_textObject setDrawsBackground: YES]; drawingRect = [self frameOfCellAtColumn: columnIndex row: rowIndex]; diff --git a/Source/NSTableView.m b/Source/NSTableView.m index db85e5bd5..68d61fb0c 100644 --- a/Source/NSTableView.m +++ b/Source/NSTableView.m @@ -3369,8 +3369,7 @@ byExtendingSelection: (BOOL)flag } _textObject = [_editedCell setUpFieldEditorAttributes: t]; - // FIXME: Which background color do we want here? - [_textObject setBackgroundColor: [NSColor selectedControlColor]]; + [_textObject setBackgroundColor: [NSColor textBackgroundColor]]; [_textObject setDrawsBackground: YES]; drawingRect = [self frameOfCellAtColumn: columnIndex row: rowIndex];