Aligning a subview element with text in an NSTextView (was: Finding vertical pos...)
Aligning a subview element with text in an NSTextView (was: Finding vertical pos...)
- Subject: Aligning a subview element with text in an NSTextView (was: Finding vertical pos...)
- From: Keith Blount <email@hidden>
- Date: Wed, 15 Dec 2004 10:19:15 -0800 (PST)
- Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys
Hi, sorry to reply to my own post, but I have spent
another day trying to get this right with no luck.
Does anybody know how to constantly get the vertical
position of a character in an NSTextView, even if the
view's size is changed or after the text is edited? I
need to align little notes that are added by the user
with the character nearest where the note was added...
So I have to keep track of a particular character (or
rather, a number of characters) and tell the notes
views whenever the vertical positions of these
characters changes for any reason.
If anybody has any suggestions, I would be really
grateful.
Many thanks,
Keith
Original Post:
Hello,
For a writing/note-taking program that I am working
on, I have a view with an NSTextView on the right, and
a custom "margin notes" view on the left. If the user
clicks in the margin notes view, it creates a little
card like one in Stickies. The user can type into this
card and freely drag it around in the margin. The idea
is that this view can be used to make marginal notes
on the main text in the NSTextView.
So far, so good, but I would like to improve this by
having it so that when a margin note card is created,
it is "attached" to the nearest character in the text
view, so that if the text is edited, or if the text
view is resized, the margin card automatically moves
to stay in line with the text it was created next to.
I am not sure of the best approach to this.
I have had some very helpful suggestions from users on
this site regarding this earlier in the year, but I
have not yet found a really good way of implementing
them. I have some code that finds the nearest
character index of a card when it is created (though
it is not perfect yet), and the card stores this as an
instance variable entitled charIndex, which has setter
and getter methods. In an attempt to update the
position of the card, I put the following code in
textView:shouldChangeTextInRange:replacementString: :
NSLayoutManager *lm = [textView layoutManager];
int i;
for (i=0; i<[[self subviews] count]; i++)
{
id card = [[self subviews] objectAtIndex:i];
if ([card charIndex] >= affectedCharRange.location)
{
[card setCharIndex:([card charIndex] +
([replacementString length] -
affectedCharRange.length))]; // But what if it is IN
rep. str?
NSRange glyphRange = [lm
glyphRangeForCharacterRange:NSMakeRange([card
charIndex],0) actualCharacterRange:nil];
int glyphIndex = glyphRange.location +
glyphRange.length;
NSPoint pt = [lm
lineFragmentRectForGlyphAtIndex:glyphIndex
effectiveRange:nil].origin;
pt = [self convertPoint:pt fromView:textView];
// Now move card
NSRect newFrame = [card frame];
newFrame.origin.y = pt.y;
[card setFrame:newFrame];
[self setNeedsDisplay:YES];
}
}
This, however, has some bizarre effects and the card
often only moves with a delay, and cards seem to get
deleted or stop moving if other cards are added - very
strange. And of course, this does not account for
changes in the size of the view (should I listen for
"frame did change" notifications?).
Does anybody have any suggestions for a good way of
implementing it so that my margin cards will stay in
line with the text they were created next to at all
times? The only program I have ever seen do something
similar is Jer's Novel Writer
(http://www.jerssoftwarehut.com/AboutJNW.shtml).
Many thanks in advance for any help, suggestions or
advice,
Keith
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden