Question

I have an NSTextView with images in it. I want to add tracking areas for those images. I need the frame of the cells holding the images in order to create tracking areas.

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

I am programmatically changing the size of an image in the text view and this is when I need to create this new tracking area. I am doing the following to create an attributed string with the text attachment, and then programmatically inserting this into my text view's attributed string. But once I do all this I do not know how to create my 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;
}

No correct solution

OTHER TIPS

Since attachments consist of a single (non visible) glyph (0xFFFC) you can use the glyph messages to get the bounding box. Here's code I use to highlight an attachment in an NSTextView based on the mouse position (which requires to get attachment bounds):

/**
 * 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 an NSTextView descendant, hence the self.layoutManager access.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top