The R Project SVN R-packages

Rev

Rev 1421 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1021 urbaneks 1
/*
2
 *  R.app : a Cocoa front end to: "R A Computer Language for Statistical Data Analysis"
3
 *  
4
 *  R.app Copyright notes:
1254 iacus 5
 *                     Copyright (C) 2004-5  The R Foundation
1021 urbaneks 6
 *                     written by Stefano M. Iacus and Simon Urbanek
7
 *
8
 *                  
9
 *  R Copyright notes:
10
 *                     Copyright (C) 1995-1996   Robert Gentleman and Ross Ihaka
11
 *                     Copyright (C) 1998-2001   The R Development Core Team
12
 *                     Copyright (C) 2002-2004   The R Foundation
13
 *
14
 *  This program is free software; you can redistribute it and/or modify
15
 *  it under the terms of the GNU General Public License as published by
16
 *  the Free Software Foundation; either version 2 of the License, or
17
 *  (at your option) any later version.
18
 *
19
 *  This program is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  A copy of the GNU General Public License is available via WWW at
25
 *  http://www.gnu.org/copyleft/gpl.html.  You can also obtain it by
26
 *  writing to the Free Software Foundation, Inc., 59 Temple Place,
27
 *  Suite 330, Boston, MA  02111-1307  USA.
28
 *
29
 *  Added by Rob Goedman on 2/3/05 based on an example by
30
 *  Carl Sziebert on Thu May 13 2004
31
 *  inspired by LineNumbering example authored by Koen van der Drift.
32
 */
33
 
34
#import "RRulerView.h"
1421 urbaneks 35
#import "RGUI.h"
1021 urbaneks 36
 
37
@interface RRulerView (PrivateMethods)
38
 
39
- (void)drawEmptyMargin:(NSRect)aRect;
40
- (void)drawNumbersInMargin:(NSRect)aRect;
41
- (void)drawOneNumberInMargin:(unsigned) aNumber inRect:(NSRect)r;
42
 
43
@end
44
 
45
@implementation RRulerView
46
 
47
- (id)initWithScrollView:(NSScrollView *)aScrollView orientation:(NSRulerOrientation)orientation showLineNumbers:(BOOL) use textView:(NSTextView *) tv {
1421 urbaneks 48
	SLog(@"RRulerView.initWithScrollView setting up line No ruler");
1021 urbaneks 49
	showLineNos = use;
50
    if (self = [super initWithScrollView: aScrollView orientation: orientation]) 
51
    {
52
        unsigned textViewFontSize = [[tv font] pointSize];
53
        if (textViewFontSize <= 10.0) {
54
            fontSize = 8.0;
55
        } else {
56
            fontSize = 9.0;
57
        }
1421 urbaneks 58
 
1459 urbaneks 59
		[self updatePreferences];
1421 urbaneks 60
		[[Preferences sharedPreferences] addDependent:self];
61
 
1021 urbaneks 62
        marginAttributes = [[NSMutableDictionary alloc] init];
63
        [marginAttributes setObject:[NSFont boldSystemFontOfSize: fontSize] forKey: NSFontAttributeName];
64
        [marginAttributes setObject:[NSColor disabledControlTextColor] forKey: NSForegroundColorAttributeName];
65
 
66
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
67
        [paragraphStyle setAlignment: NSRightTextAlignment];
68
 
69
        [marginAttributes setObject:[[paragraphStyle copy] autorelease] forKey: NSParagraphStyleAttributeName];
70
 
71
        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
72
        [nc addObserver:self selector:@selector(windowDidUpdate:) name: NSWindowDidUpdateNotification object: myTextView];
73
    }
74
	myTextView = tv;
1421 urbaneks 75
	SLog(@" - line No ruler is done");
1021 urbaneks 76
    return self;
77
}
78
 
79
- (void)dealloc
80
{
1421 urbaneks 81
	[[Preferences sharedPreferences] removeDependent:self];
1021 urbaneks 82
    [[NSNotificationCenter defaultCenter] removeObserver: self];
83
    [marginAttributes release];
84
    [super dealloc];
85
}
86
 
87
 - (void)windowDidUpdate:(NSNotification *)notification
88
{
89
    if (showLineNos && (myTextView == [[[NSDocumentController sharedDocumentController] currentDocument] textView]))
90
		[self updateView];		
91
}
92
 
93
- (void)updateView
94
{
95
	[self setNeedsDisplay: YES];
96
}
97
 
1421 urbaneks 98
// Ruler callback to actually draw
1021 urbaneks 99
- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect
100
{
101
	[self drawEmptyMargin: aRect];        
102
	[self drawNumbersInMargin: aRect];
103
}
104
 
105
-(void)drawEmptyMargin:(NSRect)aRect
106
{
107
    [self setRuleThickness: gutterThickness];
108
 
109
    [[NSColor controlHighlightColor] set];
110
    [NSBezierPath fillRect: aRect]; 
111
 
112
    NSPoint top = NSMakePoint(aRect.size.width, [self bounds].size.height);
113
    NSPoint bottom = NSMakePoint(aRect.size.width, 0);
114
 
115
    [[NSColor controlShadowColor] set];
116
    [NSBezierPath setDefaultLineWidth: 1.0];
117
    [NSBezierPath strokeLineFromPoint:top toPoint:bottom];
118
}
119
 
120
-(void)drawNumbersInMargin:(NSRect)aRect
121
{
1084 urbaneks 122
    unsigned		index, numberOfLines, numberOfGlyphs, rLineNumber;
1021 urbaneks 123
    NSRange		lineRange;
124
    NSLayoutManager	*lm;
125
    NSRect              docRect, lineRect, numRect;
1084 urbaneks 126
	BOOL displayNextLineNumber;
1421 urbaneks 127
 
1459 urbaneks 128
    //SLog(@"RRulerView.drawNumbersInMargin: %f:%f %f:%f", aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
1021 urbaneks 129
    docRect = [[self scrollView] documentVisibleRect];
130
    id textView = [[[NSDocumentController sharedDocumentController] currentDocument] textView];
131
 
132
    lm = [textView layoutManager];    
133
    numberOfGlyphs = [lm numberOfGlyphs];
134
 
1084 urbaneks 135
	NSTextStorage *ts = [textView textStorage];
136
	NSString *s = [ts string];
137
	unichar c;
138
	displayNextLineNumber = YES;
139
    for ( rLineNumber = 1, numberOfLines = 1, index = 0; index < numberOfGlyphs; numberOfLines++ )
1021 urbaneks 140
    {
141
        lineRect = [lm lineFragmentRectForGlyphAtIndex:index effectiveRange:&lineRange];
1084 urbaneks 142
		// This offsets the margin of our rulerView so that it scrolls with the textView properly.
143
		lineRect = NSOffsetRect(lineRect, -docRect.origin.x, -docRect.origin.y);
144
		numRect = NSMakeRect(aRect.origin.x, lineRect.origin.y, aRect.size.width, lineRect.size.height);
1421 urbaneks 145
		index = NSMaxRange( lineRange );
146
		//SLog(@" - draw rect %f:%f %f:%f", numRect.origin.x, numRect.origin.y, numRect.size.width, numRect.size.height);
1084 urbaneks 147
		c = [s characterAtIndex:lineRange.location + lineRange.length - 1];
1421 urbaneks 148
		{
149
			BOOL drawIt = lineRect.origin.y+lineRect.size.height>=aRect.origin.y && lineRect.origin.y<=aRect.origin.y+aRect.size.height;
150
			if (displayNextLineNumber) {
151
				if (drawIt) [self drawOneNumberInMargin: rLineNumber inRect: numRect];
152
				rLineNumber++;
153
				if (!(c=='\n')) {
154
					displayNextLineNumber = NO;	
155
				} 
1084 urbaneks 156
			} else {
1421 urbaneks 157
				if (drawIt) [self drawOneNumberInMargin: 0 inRect: numRect];
158
				if (c=='\n') {
159
					displayNextLineNumber = YES;			
160
				} else {
161
					displayNextLineNumber = NO;
162
				}			
163
			}
1084 urbaneks 164
		}
1021 urbaneks 165
    }
166
    lineRect = [lm extraLineFragmentRect];
1084 urbaneks 167
	// This offsets the margin of our rulerView so that it scrolls with the textView properly.
1021 urbaneks 168
    lineRect = NSOffsetRect(lineRect, -docRect.origin.x, -docRect.origin.y);
169
    numRect = NSMakeRect(aRect.origin.x, lineRect.origin.y, aRect.size.width, lineRect.size.height);
1421 urbaneks 170
	if (lineRect.origin.y+lineRect.size.height>=aRect.origin.y && lineRect.origin.y<=aRect.origin.y+aRect.size.height)
171
		[self drawOneNumberInMargin: rLineNumber inRect: numRect];
1459 urbaneks 172
	//SLog(@" - done drawing numbers");
1021 urbaneks 173
}
174
 
175
-(void)drawOneNumberInMargin:(unsigned) aNumber inRect:(NSRect)r
176
{
177
    NSString    *s;
178
    NSSize      stringSize;
1084 urbaneks 179
 
180
    if (aNumber == 0)
181
		s = [NSString stringWithFormat:@"."];
182
	else
183
		s = [NSString stringWithFormat:@"%d", aNumber, nil];
1021 urbaneks 184
    stringSize = [s sizeWithAttributes:marginAttributes];
185
 
186
    [s drawInRect: NSMakeRect(r.origin.x, r.origin.y + ((r.size.height / 2) - (stringSize.height / 2)), [self ruleThickness] - 2, r.size.height) withAttributes: marginAttributes];
187
}
188
 
1421 urbaneks 189
- (void) updatePreferences {
190
	gutterThickness = [[Preferences stringForKey:lineNumberGutterWidthKey withDefault: @"16.0"] floatValue];
1084 urbaneks 191
}
192
 
193
 
1021 urbaneks 194
@end