• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSTextView and Line Numbering
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSTextView and Line Numbering


  • Subject: Re: NSTextView and Line Numbering
  • From: Koen van der Drift <email@hidden>
  • Date: Thu, 20 Feb 2003 19:38:42 -0500

Hi Jim,

>Or am I going about this the wrong way? Should I override NSTextView and
>force in some self-created NSView to draw upon to the left of the TextView?
>I'd still have the same problem whereby I have no idea where to correlate
>the position of one to the other.
>
>Ideas or general pointers? Thanks all!
>



I recently came across the same problem. This is how I solved it. I
subclassed NSTextView and also its NSTextContainer. The latter to tell the
text view to leave a 'gap' on the left side:


#define left_margin_width 40;

@implementation MyViewContainer

- (NSRect)lineFragmentRectForProposedRect:(NSRect)proposedRect
sweepDirection:(NSLineSweepDirection)sweepDirection
movementDirection:(NSLineMovementDirection)movementDirection
remainingRect:(NSRect *)remainingRect
{
proposedRect.origin.x = left_margin_width;

return [super lineFragmentRectForProposedRect:proposedRect
sweepDirection:sweepDirection
movementDirection:movementDirection
remainingRect:remainingRect];
}

@end


Then in myTextView I added a method drawLineNumbers. Actually, I draw
character numbers, but this should help you.

-(void)drawLineNumbers
{
NSMutableDictionary *attr;
int i, j;
NSRect r;
NSRange aRange;
NSString *s;
NSLayoutManager *lm;

// erase rect first

r = [self bounds];
r.size.width = left_margin_width;
NSEraseRect( r );

attr = [[NSMutableDictionary alloc] init];
[attr setObject:[NSFont fontWithName: @"Courier" size: 12]
forKey: NSFontAttributeName];

[attr setObject:[NSColor blueColor]
forKey: NSForegroundColorAttributeName];

i = 0;
j = 1;

lm = [self layoutManager];

while ( i < [lm numberOfGlyphs] )
{
r = [lm lineFragmentRectForGlyphAtIndex:i effectiveRange:&aRange];

s = [NSString stringWithFormat:@"M", j, nil];
[s drawAtPoint:NSMakePoint(5, r.origin.y+2) withAttributes:attr];

s = [[[self string] substringWithRange:aRange] strip];
i += aRange.length;
j += [s length];
}

[attr release];
}



My only problem was *when* to call drawLineNumbers. It should be called
only if the text changes, so I added a BOOL that is set to YES whenever the
text changes and call setNeedsDisplayInRect to force an update of the
margin region:

- (void)updateLayout
{
NSRect r;

// do some other layout things


doDrawLineNumbers = YES;
r = [self bounds];
r.size.width = left_margin_width;

[self setNeedsDisplayInRect:r avoidAdditionalLayout:NO];
}


and then in drawRect:

- (void)drawRect:(NSRect)aRect
{
[super drawRect:aRect];

if ( doDrawLineNumbers )
{
[self drawLineNumbers];
doDrawLineNumbers = NO;
}
}



I am not sure if the code in updateLayout and drawRect is the 'best' way to
do it, but in my case it works.


good luck,

- Koen.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: [Code] search field à la Mail.app
  • Next by Date: Re: Programmatically collapsing split view
  • Previous by thread: Re: NSTextView and Line Numbering
  • Next by thread: Re: NSTextView and Line Numbering
  • Index(es):
    • Date
    • Thread