On Feb 9, 2010, at 5:03 PM, Graham Cox wrote:

>> Xcode does this when you an error on a certain line. Has anyone implemented 
>> this in their application, and if so, how did you go about doing it.
> 
> I would expect that it's done using a private custom subclass of NSScroller - 
> the standard control doesn't support this.

It's not too hard though. I did it. Here's some code I wrote a few years ago. I 
might do it a little differently now, but it works fine and at quick glance it 
generally looks ok.



//
//  AGTickScroller.h
//  AGTickScroller
//
//  Created by Seth Willits on 6/22/07.
//  Copyright 2007 Araelium Group. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface AGTickScroller : NSScroller {
        NSMutableArray * _ticks;
        BOOL _ticksMoveWithDocument;
        BOOL _hideTicksWhenNoScrollTrack;
}

- (void)setTicks:(NSArray *)ticks;
- (NSArray *)ticks;

- (void)addTick:(NSDictionary *)tick;

@end


@protocol AGTickScrollerDelegate <NSObject>

@end


@interface NSScroller (PrivateMethods)
- (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight;
@end






//
//  AGTickScroller.m
//  AGTickScroller
//
//  Created by Seth Willits on 6/22/07.
//  Copyright 2007 Araelium Group. All rights reserved.
//

#import "AGTickScroller.h"


@implementation AGTickScroller

- (void)dealloc;
{
        [_ticks release];
        [super dealloc];
}




#pragma mark -
#pragma mark Tick Management

- (void)setTicks:(NSArray *)ticks;
{
        if (!_ticks) _ticks = [[NSMutableArray alloc] init];
        
        [_ticks removeAllObjects];
        [_ticks addObjectsFromArray:ticks];
        
        [self setNeedsDisplay:YES];
}

- (void)addTick:(NSDictionary *)tick;
{
        if (!_ticks) _ticks = [[NSMutableArray alloc] init];
        [_ticks addObject:tick];
        [self setNeedsDisplay:YES];
}

- (NSArray *)ticks;
{
        return _ticks;
}




#pragma mark -
#pragma mark Drawing

- (void)setNeedsDisplayInRect:(NSRect)rect;
{
        if (_ticksMoveWithDocument) {
                // We need to always redraw the entire scrollbar so that ticks 
get updated appropriately
                [super setNeedsDisplayInRect:[self bounds]];
        } else {
                [super setNeedsDisplayInRect:rect];
        }
}


- (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight;
{
        [super drawKnobSlotInRect:rect highlight:highlight];
        
        // Hack - end caps draw ontop of slot rect. They're drawn by - 
(void)drawArrow:(int)fp8 highlightPart:(int)fp12;
        NSRect trackRect = [self rectForPart:NSScrollerKnobSlot];
        trackRect.origin.y += 14;
        trackRect.size.height -= 28;
        
        NSScrollView * scrollView = (NSScrollView * )[self superview];
        float trackHeight = trackRect.size.height;
        float totalHeight = [[scrollView documentView] frame].size.height;
        float offset = [[scrollView documentView] visibleRect].origin.y - 
[[scrollView documentView] frame].origin.y;
        
        // Draw tick marks
        if (!_hideTicksWhenNoScrollTrack || [self usableParts] != 
NSNoScrollerParts) {
                NSEnumerator * ticksEnum = [_ticks objectEnumerator];
                NSDictionary * tick = nil;
                                
                while (tick = [ticksEnum nextObject]) {
                        float tickPosition = [[tick objectForKey:@"position"] 
floatValue];
                        NSRect tickRect;
                        
                        // Move tick rect with document
                        if (_ticksMoveWithDocument) {
                                tickRect = NSMakeRect(4, trackRect.origin.y + 
tickPosition * totalHeight, rect.size.width - 8, 2);
                                tickRect.origin.y -= offset;
                                
                        // Ticks are fixed in scroll track
                        } else {
                                tickRect = NSMakeRect(4, trackRect.origin.y + 
tickPosition * trackHeight, rect.size.width - 8, 2);
                        }
                        
                        // Draw Tick
                        if (NSIntersectsRect(rect, tickRect)) {
                                [[tick objectForKey:@"color"] set];
                                NSRectFill(tickRect);
                        }
                }
        }
}

@end



--
Seth Willits



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to