Re: NSScrollView
Re: NSScrollView
- Subject: Re: NSScrollView
- From: Seth Willits <email@hidden>
- Date: Tue, 9 Feb 2010 17:40:03 -0800
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 (email@hidden)
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:
This email sent to email@hidden