drawing lines in and NSTextView

41 views
Skip to first unread message

Koen van der Drift

unread,
Mar 31, 2012, 8:08:56 AM3/31/12
to Cocoa Dev
I have an NSTextView to which I want to add some lines that connect
certain words. When the text changes, either by editing, or scrolling,
that lines should follow the words. I thought about using
CoreAnimation, but text in a CATextLayer does not appear to be
editable like the text in an NSTextView (is that correct?). So, an
alternative could be to override drawViewBackgroundInRect and use
NSBezierPaths to draw my lines and I will work on that this weekend.

Any thoughts or suggestions I may have overlooked?

- Koen.
_______________________________________________

Cocoa-dev mailing list (Coco...@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/cocoa-dev-garchive-98506%40googlegroups.com

This email sent to cocoa-dev-ga...@googlegroups.com

Graham Cox

unread,
Mar 31, 2012, 9:09:52 PM3/31/12
to Koen van der Drift, Cocoa Dev

On 31/03/2012, at 11:08 PM, Koen van der Drift wrote:

> I have an NSTextView to which I want to add some lines that connect
> certain words. When the text changes, either by editing, or scrolling,
> that lines should follow the words. I thought about using
> CoreAnimation, but text in a CATextLayer does not appear to be
> editable like the text in an NSTextView (is that correct?). So, an
> alternative could be to override drawViewBackgroundInRect and use
> NSBezierPaths to draw my lines and I will work on that this weekend.
>
> Any thoughts or suggestions I may have overlooked?


Seems to me you're focusing on the wrong aspect of the problem. The key to this is to track given words' positions as the text is scrolled/reflowed. If you lay out the text yourself (using NSLayoutManager, for example) this is not hard, but if you leave it to something else, such as NSTextView, it may be a lot harder (though NSTextView has a NSLayoutManager of which you can ask questions).

Drawing the lines once you have those positions is relatively easy - NSBezierPaths will work, and are probably the simplest.


--Graham

Douglas Davidson

unread,
Mar 31, 2012, 9:41:08 PM3/31/12
to Graham Cox, Cocoa Dev, Koen van der Drift

On Mar 31, 2012, at 6:09 PM, Graham Cox <graha...@bigpond.com> wrote:

>
> On 31/03/2012, at 11:08 PM, Koen van der Drift wrote:
>
>> I have an NSTextView to which I want to add some lines that connect
>> certain words. When the text changes, either by editing, or scrolling,
>> that lines should follow the words. I thought about using
>> CoreAnimation, but text in a CATextLayer does not appear to be
>> editable like the text in an NSTextView (is that correct?). So, an
>> alternative could be to override drawViewBackgroundInRect and use
>> NSBezierPaths to draw my lines and I will work on that this weekend.
>>
>> Any thoughts or suggestions I may have overlooked?
>
>
> Seems to me you're focusing on the wrong aspect of the problem. The key to this is to track given words' positions as the text is scrolled/reflowed. If you lay out the text yourself (using NSLayoutManager, for example) this is not hard, but if you leave it to something else, such as NSTextView, it may be a lot harder (though NSTextView has a NSLayoutManager of which you can ask questions).
>
> Drawing the lines once you have those positions is relatively easy - NSBezierPaths will work, and are probably the simplest.

Actually it's pretty easy to just use the text view's layout manager to find out where the words are, and do some additional drawing in your NSTextView subclass. We have some developer examples of this, though I don't have them ready to hand at the moment, and I've discussed this at more than one WWDC text session.

-Doug

Salman Khilji

unread,
Mar 31, 2012, 12:32:25 PM3/31/12
to Cocoa Dev
You may want to look at the freely downloadable Session 114 - Advance Cocoa Text Tip and Tricks from iTunesU in WWDC 2010 videos. It may help.

Salman


On Mar 31, 2012, at 5:08 AM, Koen van der Drift wrote:

> I have an NSTextView to which I want to add some lines that connect
> certain words. When the text changes, either by editing, or scrolling,
> that lines should follow the words. I thought about using
> CoreAnimation, but text in a CATextLayer does not appear to be
> editable like the text in an NSTextView (is that correct?). So, an
> alternative could be to override drawViewBackgroundInRect and use
> NSBezierPaths to draw my lines and I will work on that this weekend.
>
> Any thoughts or suggestions I may have overlooked?
>
> - Koen.
> _______________________________________________
>
> Cocoa-dev mailing list (Coco...@lists.apple.com)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:

> https://lists.apple.com/mailman/options/cocoa-dev/salmankhilji%40yahoo.com
>
> This email sent to salman...@yahoo.com

jona...@mugginsoft.com

unread,
Apr 1, 2012, 6:16:31 AM4/1/12
to coco...@lists.apple.com


On 31 Mar 2012, at 13:08, Koen van der Drift wrote:

> I have an NSTextView to which I want to add some lines that connect
> certain words. When the text changes, either by editing, or scrolling,
> that lines should follow the words. I thought about using
> CoreAnimation, but text in a CATextLayer does not appear to be
> editable like the text in an NSTextView (is that correct?). So, an
> alternative could be to override drawViewBackgroundInRect and use
> NSBezierPaths to draw my lines and I will work on that this weekend.
>
> Any thoughts or suggestions I may have overlooked?
>

You probably get get what you need form the WWDC references already given but the following might still be useful.
http://www.cocoabuilder.com/archive/cocoa/113955-graphics-in-nstextview-ichat-like-bubbles.html?q=nstextview+draw+bubble#114075

Of course, overriding drawViewBackgroundInRect, will draw your lines behind the text, which may be acceptable.
Another approach is to add a subview to the NSTextView instance and do all your drawing there.
I use this approach to draw a simple Quartz 2D animation over an NSTextView.

Obviously you need to make your drawing sub view non opaque.
You also will need to resize your subview as the NSTextView size changes by requesting that the appropriate NSView notifications be sent.

In my case I make my child view modify its behaviour if it is embedded in an NSTextView.

// in NSTextView subview
if ([[self superview] isKindOfClass:[NSTextView class]]) {

// get the text view
_textView = (id)[self superview];
[_textView setAutoresizesSubviews:YES];

// set scrollview background drawing behaviour
[[self enclosingScrollView] setDrawsBackground:NO];

// observe changes to the scrollview content bounds.
// see "How Scroll Views Work" in the docs
[[[self enclosingScrollView] contentView] setPostsBoundsChangedNotifications:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollContentBoundsChanged:) name:NSViewBoundsDidChangeNotification object:[[self enclosingScrollView] contentView]];

[_textView setPostsFrameChangedNotifications:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollContentBoundsChanged:) name:NSViewFrameDidChangeNotification object:_textView];

// turn on layer backed views for this view
// and all subviews.
//
// this works fine but the cpu usage can be very high

// add a filter
if (_useLayers) {

// create layer for textview and all subviews
[_textView setWantsLayer:YES];

// this works but the overhead is high - cpu usage increases from 4 -> 40%
CIFilter *filter = [CIFilter filterWithName:@"CIColorBurnBlendMode"];
[self setCompositingFilter:filter];
}

}

Regards

Jonathan Mitchell
Mugginsoft LLP

Koen van der Drift

unread,
Apr 1, 2012, 7:47:41 AM4/1/12
to Cocoa Dev
Thanks for the response, very helpful. Also the link to the iTunes U session. There is a wealth of info I was not aware of that it is available for non-WWDC attendees.

- Koen.

Reply all
Reply to author
Forward
0 new messages