Get frame from NSTextAttachmentCell to NSTextView

I have an NSTextView with images in it. I want to add tracking areas for these images. I need a frame of cells with images to create tracking zones.

So my question is, how can I get the frame for the NSTextAttachments in the NSTextView coordinate system?

I am programmatically resizing an image in text view and this is when I need to create a new tracking area. I do the following to create an attributed string with text nesting and then programmatically inserting it into text anchored to text. But once I do all this, I don't know how to create my own tracking area for the new attachment.

-(NSAttributedString*)attributedStringAttachmentForImageObject:(id)object {
    NSFileWrapper* fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:[object TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0]];
    [fileWrapper setPreferredFilename:@"image.tiff"];
    NSTextAttachment* attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
    NSAttributedString* aString = [NSAttributedString attributedStringWithAttachment:attachment];
    [fileWrapper release];
    [attachment release];
    return aString;
}

      

+3


source to share


1 answer


Since attachments are made up of a single (invisible) glyph (0xFFFC), you can use message glyphs to get the bounding box. Here's the code I'm using to highlight the attachment in the NSTextView based on the mouse position (which requires getting the binding):

/**
 * Determines the index under the mouse. For highlighting we use the index only if the mouse is actually
 * within the tag bounds. For selection purposes we return the index as it was found even if the mouse pointer
 * is outside the tag bounds.
 */
- (NSUInteger)updateTargetDropIndexAtPoint: (NSPoint)point
{
    CGFloat fraction;
    NSUInteger index = [self.layoutManager glyphIndexForPoint: point
                                              inTextContainer: self.textContainer
                               fractionOfDistanceThroughGlyph: &fraction];
    NSUInteger caretIndex = index;
    if (fraction > 0.5) {
        caretIndex++;
    }

    // For highlighting a tag we need check if the mouse is actually within the tag.
    NSRect bounds = [self.layoutManager boundingRectForGlyphRange: NSMakeRange(index, 1)
                                                  inTextContainer: self.textContainer];
    NSUInteger newIndex;
    if (NSPointInRect(point, bounds)) {
        newIndex = index;
    } else {
        newIndex = NSNotFound;
    }
    if (hotTagIndex != newIndex) {
        NSRect oldBounds = [self.layoutManager boundingRectForGlyphRange: NSMakeRange(hotTagIndex, 1)
                                                         inTextContainer: self.textContainer];
        [self setNeedsDisplayInRect: oldBounds];
        hotTagIndex = newIndex;
        [self setNeedsDisplayInRect: bounds];
    }

    return caretIndex;
}

      



This code is used in the NSTextView descendant stream, hence accessing self.layoutManager.

+3


source







All Articles