Michael Robinson
Michael Robinson

Reputation: 29498

Highlighting an Edited NSBrowserCell & Draw A Focus Ring on its NSText?

What I'm trying to do

I'm trying to add edit-in-place functionality to the Connection Kit's NSBrowser. I'd like this behaviour to be functionally and visually similar to Finder's implementation.

The visual effect I'm aiming for

Finder's implementation

What I've got so far

NSBrowserCell subclass

The arrows indicate focus ring & cell highlighting in Finder's implementation, and the lack of it in mine.

I have tried

The best I've managed was getting the area surrounding the cell's image coloured with the highlight colour.

Is there some fundamental that I'm missing here? Could someone please suggest a starting point for approaching this? Is drawInteriorWithFrame the place to be doing this?

I've got editing working fine - I'm just having trouble with the visual aspects.

Code to allow editing:

// In the main controller
int selectedColumn = [browser selectedColumn];
int selectedRow = [browser selectedRowInColumn:selectedColumn];
NSMatrix *theMatrix = [browser matrixInColumn:selectedColumn];
NSRect cellFrame = [theMatrix cellFrameAtRow:selectedRow column:0];

NSText *fieldEditor = [[browser window] fieldEditor:YES 
                                          forObject:editingCell];

[cell editWithFrame:cellFrame 
             inView:theMatrix
             editor:fieldEditor 
           delegate:self
              event:nil];

And in my subclass of NSBrowserCell:

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {  

    image = [[self representedObject] iconWithSize:[self imageSize]];

    [self setImage:image];

    NSRect imageFrame, highlightRect, textFrame;

    // Divide the cell into 2 parts, the image part (on the left) and the text part.
    NSDivideRect(cellFrame, &imageFrame, &textFrame, ICON_INSET_HORIZ + ICON_TEXT_SPACING + [self imageSize].width, NSMinXEdge);
    imageFrame.origin.x += ICON_INSET_HORIZ;
    imageFrame.size = [self imageSize];

    [super drawInteriorWithFrame:cellFrame inView:controlView];
}

- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
    NSRect imageRect, textRect;
    NSDivideRect(aRect , &imageRect, &textRect, 20, NSMinXEdge);
    self.editing = YES;
    [super editWithFrame: textRect inView: controlView editor:textObj delegate:anObject event:theEvent];
}

Upvotes: 4

Views: 944

Answers (2)

arun.s
arun.s

Reputation: 1528

Try subclassing field editor object and override drawRect function like this :

- (void)drawRect:(NSRect)rect {

    [super drawRect:rect];

    NSSetFocusRingStyle(NSFocusRingOnly);

    NSRectFill([self bounds]);

}

Hope this helps.

Upvotes: -1

mpergand
mpergand

Reputation: 96

You have to draw the focus ring yourself. Add the following in drawWithFrame in your NSBrowserCell subclass

[NSGraphicsContext saveGraphicsState];
[[controlView superview] lockFocus];

NSSetFocusRingStyle(NSFocusRingAbove);
[[NSBezierPath bezierPathWithRect:NSInsetRect(frame,-1,-1)] fill];

[[controlView superview] unlockFocus];
[NSGraphicsContext restoreGraphicsState];

Upvotes: 3

Related Questions