Re: text highlighting with CALayer and NSTextVew
Re: text highlighting with CALayer and NSTextVew
- Subject: Re: text highlighting with CALayer and NSTextVew
- From: Koen van der Drift <email@hidden>
- Date: Thu, 23 Aug 2012 21:45:40 -0400
I think I figured it out. I had to add a call to convertRectToBase to make the CALayers show up in the right place in the NSView. Here's my current code, which is called whenever a particular area in my text needs to be highlighted through a notification.
NSUInteger rectCount;
NSRange selectedRange = NSMakeRange(NSNotFound, 0);
aRange = myGetRangeFromNotification;
NSRectArray rectArray = [[self layoutManager] rectArrayForCharacterRange: aRange
withinSelectedCharacterRange: selectedRange
inTextContainer: [self textContainer]
rectCount: &rectCount];
for (NSUInteger i = 0; i < rectCount; i++)
{
NSRect layerRect = rectArray[i];
CALayer *aLayer = [CALayer layer];
aLayer.backgroundColor = CGColorCreateGenericRGB (0.2, 0.2, 0.2, 0.2);
aLayer.frame = [self convertRectToBase:layerRect]; <<<<<-------------------
aLayer.cornerRadius = 5.0f;
[self.layer addSublayer: aLayer];
}
Resizing the window doesn't move the layers, so I need to work on that next.
- Koen.
On Aug 23, 2012, at 8:09 AM, Graham Cox <email@hidden> wrote:
>
> On 23/08/2012, at 9:16 PM, Koen van der Drift <email@hidden> wrote:
>
>> Another update, I guess I love to talk to myself.
>>
>> I got the drawing part done as follows:
>>
>>
>> CALayer *aLayer = [CALayer layer];
>> NSRect r = [self.layoutManager boundingRectForGlyphRange: aRange inTextContainer: self.textContainer];
>>
>> aLayer.backgroundColor = CGColorCreateGenericRGB (0.2, 0.2, 0.2, 0.2); // obviously this will be changed to something nicer
>> aLayer.frame = r;
>> aLayer.cornerRadius = 6.0f;
>>
>> [self.layer addSublayer: aLayer];
>>
>>
>> There are two problems:
>>
>> 1. the y-location of the layer that is drawn is wrong, I think it has to do with the coordinates being flipped
>
> Text views generally use flipped coordinates (since most text systems render top-down). You may need to set the -geometryFlipped property of the CALayer to match.
>
>
>> 2. when the range contains a line break, I get the rect for two whole lines, not just the glyphs.
>
>
> You probably want to use [NSLayoutManager rectArrayForCharacterRange:....] instead, which gives you all of the rectangles necessary to perform a highlight, which can consist of numerous parts, considering a text highlight can extend over many lines, be disjoint, etc. Of course you can't just set a CALayer frame with this - it might be better to create a custom layer that can draw the necessary rectangles behind the text.
>
> --Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden