On Apr 30, 2013, at 7:01 AM, Jason Brennan wrote:
> Yeah what I'm trying to do mostly is a "block" element in the text, "inline"
> is just a side thing, not essential. What I'm trying to do is best described
> as an analogy with HTML.
>
> Let's say I've got the following HTML:
>
> <p>This is a paragraph</p>
> <img/>
> <p>Another paragraph</p>
So a quick fiddle offers a potential simpler solution. This is not quite
complete, but shows the idea. The only bit this doesn't handle is removing the
view when the attachment cell is removed from the text storage. To deal with
that you need to create a simple text storage subclass and in the replaceā¦:
method, scan for ViewAttachments and remove the view from the superview.
(Using a single view instance like this, you also won't be able to show the
same text storage in two different text views since the view can't be in two
places at once.)
@interface ViewAttachment : NSTextAttachment
@end
@interface ViewAttachmentCell : NSTextAttachmentCell {
NSView * _view;
}
@property (readwrite, assign) NSView * view;
@end
@implementation AppDelegate
{
IBOutlet NSTextView * textView;
IBOutlet NSView * attachmentView;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSTextStorage * ts = textView.textStorage;
NSUInteger location = <pick something in the middle of a line>
ViewAttachmentCell * attachmentCell = [[[ViewAttachmentCell alloc]
init] autorelease];
attachmentCell.view = attachmentView;
ViewAttachment * attachment = [[[ViewAttachment alloc] init]
autorelease];
attachment.attachmentCell = attachmentCell;
NSAttributedString * attachStr = [NSAttributedString
attributedStringWithAttachment:attachment];
[ts insertAttributedString:attachStr atIndex:location];
}
@end
@implementation ViewAttachment
@end
@implementation ViewAttachmentCell
@synthesize view = _view;
- (NSSize)cellSize
{
return self.view.frame.size;
}
- (NSRect)cellFrameForTextContainer:(NSTextContainer *)textContainer
proposedLineFragment:(NSRect)lineFrag glyphPosition:(NSPoint)position
characterIndex:(NSUInteger)charIndex
{
NSRect cellFrame = [super cellFrameForTextContainer:textContainer
proposedLineFragment:lineFrag glyphPosition:position characterIndex:charIndex];
// Make it on its own line.
cellFrame.size.width = textContainer.containerSize.width;
// Side note: AFAICT, the x/y of the frame when calling super is always
0,0
// which seems contradictory to what the documentation suggests it
should be.
// As a result, handling x/y seems unnecessary here, and works without
it.
// Otherwise I'd expect to have to set x to 0 and bump the y if needed,
etc.
return cellFrame;
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
characterIndex:(NSUInteger)charIndex layoutManager:(NSLayoutManager
*)layoutManager
{
if (self.view.superview != controlView) {
[self.view removeFromSuperview];
[controlView addSubview:self.view];
}
// I'm not really sure if moving the view when the cell should draw is
good
// enough, but it works in this quick example, anyway. You may need to
change
// the frame whenever the text storage changes (smartly).
self.view.frame = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y,
self.view.frame.size.width, self.view.frame.size.height);
}
@end
_______________________________________________
Cocoa-dev mailing list ([email protected])
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/archive%40mail-archive.com
This email sent to [email protected]