Caret drawing artifacts in NSTextView (subclass)
Caret drawing artifacts in NSTextView (subclass)
- Subject: Caret drawing artifacts in NSTextView (subclass)
- From: Antonio Nunes <email@hidden>
- Date: Sat, 2 Sep 2006 13:56:20 +0100
Hi,
I'm running into a problem I would have expected to find documented
somewhere, but no such luck. Here's the deal:
My app allows adding text boxes to pages. When I start editing that
text box, if the text box's scale is smaller than a little over 100%
then, as soon as the caret blinks, black lines are drawn either
around the frame of the text box, or inside the box. If I scale the
view up to say 120% and than back down to where it was then these
lines are no longer drawn. Which is how it should be. But I can't
figure out why the black lines are drawn when the view is at, say 75%
when the editing starts. I've tried a bunch of workarounds but
nothing seems to work.
Here's the relevant code, with comments, mostly derived from the
Sketch demo:
This is the code that my object uses to create the text view.
ANBorderedTextView is a simple subclass of NSTextView, all it does is
drawing a border around itself, and keeping track of when it loses
first responder status.
static ANBorderedTextView *newEditor(NSRect theBounds) {
NSLayoutManager *lm = [[NSLayoutManager allocWithZone:NULL] init];
NSTextContainer *tc = [[NSTextContainer allocWithZone:NULL]
initWithContainerSize:NSMakeSize(1.0e6, 1.0e6)];
ANBorderedTextView *tv = [[ANBorderedTextView
allocWithZone:NULL] initWithFrame:theBounds textContainer:nil];
[lm addTextContainer:tc];
[tc release];
[tv setTextContainerInset:NSMakeSize(0.0, 0.0)];
[tv setDrawsBackground:NO];
[tv setAllowsUndo:YES];
[tc setTextView:tv];
[tv release];
return tv;
}
When the user double-clicks the text box we start editing it:
- (void)startEditingWithEvent:(NSEvent *)event inView:(ANLayoutView *)
view {
ANBorderedTextView *editor;
NSTextStorage *contents = [self source];
NSSize maxSize = [self maxSize];
NSSize minSize = [self minSize];
NSRect bounds = [self bounds];
bounds.origin.x = (bounds.origin.x * [[owner sheetPage]
scale].width) + [[[owner sheetPage] sheetSide] bounds].origin.x +
[[owner sheetPage] bounds].origin.x;
bounds.origin.y = (bounds.origin.y * [[owner sheetPage]
scale].height) + [[[owner sheetPage] sheetSide] bounds].origin.y +
[[owner sheetPage] bounds].origin.y;
originalSize = [self size]; // remember our size for when we end
editing
if (!sharedEditorInUse) {
if (!sharedEditor) {
sharedEditor = newEditor(NSMakeRect(0.0, 0.0, 1.0e6,
1.0e6));
}
sharedEditorInUse = YES;
editor = sharedEditor;
} else {
editor = newEditor(NSMakeRect(0.0, 0.0, 1.0e6, 1.0e6));
}
[sharedEditor setOwner:self];
if (fixedWidth) {
[[editor textContainer] setContainerSize:NSMakeSize(NSWidth
(bounds), maxSize.height)];
[editor setHorizontallyResizable:NO];
} else {
[[editor textContainer] setContainerSize:maxSize];
[editor setHorizontallyResizable:YES];
}
[editor setVerticallyResizable:YES];
[editor setMinSize:minSize];
[editor setMaxSize:maxSize];
[[editor textContainer] setHeightTracksTextView:NO];
[editor setFrame:bounds];
[contents addLayoutManager:[editor layoutManager]];
[editor setScale:[[[self owner] sheetPage] scale]];
[view addSubview:editor];
[view setObjectBeingEdited:self editorView:editor];
[editor setSelectedRange:NSMakeRange(0, [contents length])];
[editor setDelegate:self];
[[view window] makeFirstResponder:editor];
if (event) {
[editor mouseDown:event];
}
}
What happens when the text changes:
- (void)textDidChange:(NSNotification *)notification {
#pragma unused (notification)
NSSize textSize;
NSRect myBounds = [self bounds];
textSize = [self requiredSize:(fixedWidth ? NSWidth(myBounds) :
1.0e6)];
[self setSize:NSMakeSize([self size].width, [self size].height +
(textSize.height - myBounds.size.height))];
[self setSize:NSMakeSize(textSize.width, textSize.height)];
[[[[self owner] document] layoutView] setNeedsDisplayInRect:[[self
owner] bounds]];
}
The drawRect method for my ANBorderedTextView:
- (void)drawRect:(NSRect)rect {
[[NSColor selectedTextBackgroundColor] set];
NSFrameRect([self bounds]);
[super drawRect:rect];
}
The drawing of the artifacts happens in the call to [super drawRect].
By the way these artifacts also show up when I use a straight
NSTextView rather than this subclass for the editor.
My questions then are:
1 What may be causing these artifacts?
2 How do I stop the artifacts being drawn?
Kind regards,
António
-----------------------------------------
Forgiveness is not an occasional act;
it is a permanent attitude.
--Martin Luther King, Jr
-----------------------------------------
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden