Finding the vertical position of a character in an NSTextView
Finding the vertical position of a character in an NSTextView
- Subject: Finding the vertical position of a character in an NSTextView
- From: Keith Blount <email@hidden>
- Date: Tue, 14 Dec 2004 11:16:00 -0800 (PST)
- Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys
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!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail
_______________________________________________
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