Class (re)written

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@13204 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Nicola Pero 2002-03-22 13:23:07 +00:00
parent 1aebe415da
commit d965b511dc
2 changed files with 690 additions and 219 deletions

View file

@ -1,14 +1,16 @@
/*
/* -*-objc-*-
NSRulerView.h
The NSRulerView class.
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999-2002 Free Software Foundation, Inc.
Author: Michael Hanni <mhanni@sprintmail.com>
Date: Feb 1999
Author: Fred Kiefer <FredKiefer@gmx.de>
Date: Sept 2001
Author: Diego Kreutz (kreutz@inf.ufsm.br)
Date: January 2002
This file is part of the GNUstep GUI Library.
@ -32,107 +34,140 @@
#include <AppKit/NSView.h>
@class NSRulerMarker;
/* Declaring classes, rather than #including the full class header,
* results in much faster compilations. */
@class NSScrollView;
@class NSString;
@class NSArray;
@class NSRulerMarker;
@class NSCoder;
@class NSEvent;
typedef enum {
NSHorizontalRuler,
NSVerticalRuler
} NSRulerOrientation;
@class GSRulerUnit;
@interface NSRulerView : NSView
{
NSMutableArray *_markers;
NSString *_measurementUnits;
NSView *_clientView;
NSView *_accessoryView;
GSRulerUnit *_unit;
NSScrollView *_scrollView;
NSView *_clientView;
NSView *_accessoryView;
float _originOffset;
float _reservedThicknessForAccessoryView;
float _reservedThicknessForMarkers;
float _ruleThickness;
NSRulerOrientation _orientation;
NSMutableArray *_markers;
NSRulerOrientation _orientation;
float _ruleThickness;
float _reservedThicknessForAccessoryView;
float _reservedThicknessForMarkers;
/* Cached values. It's a little expensive to calculate them and they
* change only when the unit or the originOffset is changed or when
* clientView changes it's size or zooming factor. This cache is
* invalidated by -invalidateHashMarks method. */
BOOL _cacheIsValid;
float _markDistance;
float _labelDistance;
int _marksToBigMark;
int _marksToMidMark;
int _marksToLabel;
float _zeroLocation;
float _unitToRuler;
NSString *_labelFormat;
}
- (id)initWithScrollView:(NSScrollView *)aScrollView
orientation:(NSRulerOrientation)orientation;
- (id) initWithScrollView: (NSScrollView *)aScrollView
orientation: (NSRulerOrientation)o;
+ (void) registerUnitWithName: (NSString *)uName
abbreviation:(NSString *)abbreviation
unitToPointsConversionFactor:(float)conversionFactor
stepUpCycle:(NSArray *)stepUpCycle
stepDownCycle:(NSArray *)stepDownCycle;
+ (void)registerUnitWithName:(NSString *)unitName
abbreviation:(NSString *)abbreviation
unitToPointsConversionFactor:(float)conversionFactor
stepUpCycle:(NSArray *)stepUpCycle
stepDownCycle:(NSArray *)stepDownCycle;
- (void) setMeasurementUnits: (NSString *)uName;
- (NSString *) measurementUnits;
- (void)setMeasurementUnits:(NSString *)unitName;
- (NSString *)measurementUnits;
- (void) setClientView: (NSView *)aView;
- (NSView *) clientView;
- (void)setClientView:(NSView *)aView;
- (NSView *)clientView;
- (void) setAccessoryView: (NSView *)aView;
- (NSView *) accessoryView;
- (void)setAccessoryView:(NSView *)aView;
- (NSView *)accessoryView;
- (void) setOriginOffset: (float)offset;
- (float) originOffset;
- (void)setOriginOffset:(float)offset;
- (float)originOffset;
- (void) setMarkers: (NSArray *)markers;
- (NSArray *) markers;
- (void) addMarker: (NSRulerMarker *)aMarker;
- (void) removeMarker: (NSRulerMarker *)aMarker;
- (BOOL) trackMarker: (NSRulerMarker *)aMarker
withMouseEvent: (NSEvent *)theEvent;
- (void)setMarkers:(NSArray *)markers;
- (NSArray *)markers;
- (void)addMarker:(NSRulerMarker *)aMarker;
- (void)removeMarker:(NSRulerMarker *)aMarker;
- (BOOL)trackMarker:(NSRulerMarker *)aMarker
withMouseEvent:(NSEvent *)theEvent;
- (void) moveRulerlineFromLocation: (float)oldLoc toLocation: (float)newLoc;
- (void)moveRulerlineFromLocation:(float)oldLoc toLocation:(float)newLoc;
- (void) drawHashMarksAndLabelsInRect: (NSRect)aRect;
- (void) drawMarkersInRect: (NSRect)aRect;
- (void) invalidateHashMarks;
- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect;
- (void)drawMarkersInRect:(NSRect)aRect;
- (void)invalidateHashMarks;
- (void) setScrollView:(NSScrollView *) scrollView;
- (NSScrollView *) scrollView;
- (void)setScrollView:(NSScrollView *)scrollView;
- (NSScrollView *)scrollView;
- (void)setOrientation:(NSRulerOrientation)orientation;
- (NSRulerOrientation)orientation;
- (void)setReservedThicknessForAccessoryView:(float)thickness;
- (float)reservedThicknessForAccessoryView;
- (void)setReservedThicknessForMarkers:(float)thickness;
- (float)reservedThicknessForMarkers;
- (void)setRuleThickness:(float)thickness;
- (float)ruleThickness;
- (float)requiredThickness;
- (float)baselineLocation;
- (BOOL)isFlipped;
- (void) setOrientation: (NSRulerOrientation)o;
- (NSRulerOrientation) orientation;
- (void) setReservedThicknessForAccessoryView: (float)thickness;
- (float) reservedThicknessForAccessoryView;
- (void) setReservedThicknessForMarkers: (float)thickness;
- (float) reservedThicknessForMarkers;
- (void) setRuleThickness: (float)thickness;
- (float) ruleThickness;
- (float) requiredThickness;
- (float) baselineLocation;
- (BOOL) isFlipped;
@end
//
// Methods Implemented by the Delegate
//
@interface NSObject (NSRulerViewClient)
/*
* Methods Implemented by the client view ... FIXME/TODO: we currently
* do not send all these messages to the client view ... while we
* should!
*/
@interface NSObject (NSRulerViewClientView)
- (void)rulerView:(NSRulerView *)aRulerView
didAddMarker:(NSRulerMarker *)aMarker;
- (void)rulerView:(NSRulerView *)aRulerView
didMoveMarker:(NSRulerMarker *)aMarker;
- (void)rulerView:(NSRulerView *)aRulerView
didRemoveMarker:(NSRulerMarker *)aMarker;
- (void)rulerView:(NSRulerView *)aRulerView
handleMouseDown:(NSEvent *)theEvent;
- (BOOL)rulerView:(NSRulerView *)aRulerView
shouldAddMarker:(NSRulerMarker *)aMarker;
- (BOOL)rulerView:(NSRulerView *)aRulerView
shouldMoveMarker:(NSRulerMarker *)aMarker;
- (BOOL)rulerView:(NSRulerView *)aRulerView
- (void)rulerView: (NSRulerView *)aRulerView
didAddMarker: (NSRulerMarker *)aMarker;
- (void)rulerView: (NSRulerView *)aRulerView
didMoveMarker: (NSRulerMarker *)aMarker;
- (void)rulerView: (NSRulerView *)aRulerView
didRemoveMarker: (NSRulerMarker *)aMarker;
- (void)rulerView: (NSRulerView *)aRulerView
handleMouseDown: (NSEvent *)theEvent;
- (BOOL)rulerView: (NSRulerView *)aRulerView
shouldAddMarker: (NSRulerMarker *)aMarker;
- (BOOL)rulerView: (NSRulerView *)aRulerView
shouldMoveMarker: (NSRulerMarker *)aMarker;
- (BOOL)rulerView: (NSRulerView *)aRulerView
shouldRemoveMarker: (NSRulerMarker *)aMarker;
- (float)rulerView:(NSRulerView *)aRulerView
willAddMarker:(NSRulerMarker *)aMarker
atLocation:(float)location;
- (float)rulerView:(NSRulerView *)aRulerView
willMoveMarker:(NSRulerMarker *)aMarker
toLocation:(float)location;
- (void)rulerView:(NSRulerView *)aRulerView
willSetClientView:(NSView *)newClient;
- (float)rulerView: (NSRulerView *)aRulerView
willAddMarker: (NSRulerMarker *)aMarker
atLocation: (float)location;
- (float)rulerView: (NSRulerView *)aRulerView
willMoveMarker: (NSRulerMarker *)aMarker
toLocation: (float)location;
- (void)rulerView: (NSRulerView *)aRulerView
willSetClientView: (NSView *)newClient;
@end
#endif /* _GNUstep_H_NSRulerView */

View file

@ -1,221 +1,638 @@
/** <title>NSRulerView</title>
/*
NSRulerView.m
<abstract>The NSRulerView class.</abstract>
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2001 Free Software Foundation, Inc.
Author: Diego Kreutz (kreutz@inf.ufsm.br)
Date: January 2002
Author: Fred Kiefer <FredKiefer@gmx.de>
Date: Sept 2001
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* FIXME - HAVE_RINT */
#include <gnustep/gui/config.h>
#include <math.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSString.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include <Foundation/NSValue.h>
#include <AppKit/NSColor.h>
#include <AppKit/NSFont.h>
#include <AppKit/NSGraphics.h>
#include <AppKit/NSRulerMarker.h>
#include <AppKit/NSRulerView.h>
#include <AppKit/NSScrollView.h>
#include <AppKit/PSOperators.h>
#define MIN_LABEL_DISTANCE 40
#define MIN_MARK_DISTANCE 5
NSString *defaultUnits;
#define MARK_SIZE 2
#define MID_MARK_SIZE 4
#define BIG_MARK_SIZE 6
#define LABEL_MARK_SIZE 11
@implementation NSRulerView
#define BASE_LINE_LOCATION 0
#define RULER_THICKNESS 16
+ (void) initialize
#define ASSIGN_FIRST_VALUE(firstVal, tRect) (firstVal = (int)((tRect - _zeroLocation) / labelDistInRuler) * labelDistInRuler)
#define ASSIGN_FIRST_MARKER(firstMarker, tRect) (firstMarker = ceil(((tRect - _zeroLocation) - firstVal) / (_unitToRuler * markDistInUnits)))
#define ASSIGN_DIFERENCE(diference, tRect) (diference = (firstMarker * (markDistInUnits * _unitToRuler)) + firstVal + _zeroLocation - tRect)
#define SET_MARK_COUNT(markCount, tRect, dif) (markCount = floor(1 + (tRect - dif) / (_unitToRuler * markDistInUnits)))
#define DRAW_HASH_MARK(context, size) {if (_orientation == NSHorizontalRuler) DPSrlineto(context, 0, size); else DPSrlineto(context, size, 0);}
@interface GSRulerUnit : NSObject
{
if (self == [NSRulerView class])
NSString *_unitName;
NSString *_abbreviation;
float _conversionFactor;
NSArray *_stepUpCycle;
NSArray *_stepDownCycle;
}
+ (GSRulerUnit *) unitWithName: (NSString *)uName
abbreviation: (NSString *)abbrev
unitToPointsConversionFactor: (float)factor
stepUpCycle: (NSArray *)upCycle
stepDownCycle: (NSArray *)downCycle;
- (id) initWithUnitName: (NSString *)uName
abbreviation: (NSString *)abbrev
unitToPointsConversionFactor: (float)factor
stepUpCycle: (NSArray *)upCycle
stepDownCycle: (NSArray *)downCycle;
- (NSString *) unitName;
- (NSString *) abbreviation;
- (float) conversionFactor;
- (NSArray *) stepUpCycle;
- (NSArray *) stepDownCycle;
@end
@implementation GSRulerUnit
+ (GSRulerUnit *) unitWithName: (NSString *)uName
abbreviation: (NSString *)abbrev
unitToPointsConversionFactor: (float)factor
stepUpCycle: (NSArray *)upCycle
stepDownCycle: (NSArray *)downCycle
{
return [[[self alloc] initWithUnitName: uName
abbreviation: abbrev
unitToPointsConversionFactor: factor
stepUpCycle: upCycle
stepDownCycle: downCycle] autorelease];
}
- (id) initWithUnitName: (NSString *)uName
abbreviation: (NSString *)abbrev
unitToPointsConversionFactor: (float)factor
stepUpCycle: (NSArray *)upCycle
stepDownCycle: (NSArray *)downCycle
{
self = [super init];
if (self != nil)
{
NSArray *two = [NSArray arrayWithObject: [NSNumber numberWithFloat: 2.0]];
NSArray *half = [NSArray arrayWithObject: [NSNumber numberWithFloat: 0.5]];
NSArray *ten = [NSArray arrayWithObject: [NSNumber numberWithFloat: 10.0]];
NSArray *half_fifth = [NSArray arrayWithObjects:
[NSNumber numberWithFloat: 0.5],
[NSNumber numberWithFloat: 0.2],
nil];
// Register the predefined units
[self registerUnitWithName: @"Inches"
abbreviation: @"in"
unitToPointsConversionFactor: 72.0
stepUpCycle: two
stepDownCycle: half];
[self registerUnitWithName: @"Centimeters"
abbreviation: @"cm"
unitToPointsConversionFactor: 28.35
stepUpCycle: two
stepDownCycle: half_fifth];
[self registerUnitWithName: @"Points"
abbreviation: @"pt"
unitToPointsConversionFactor: 1.0
stepUpCycle: ten
stepDownCycle: half];
[self registerUnitWithName: @"Picas"
abbreviation: @"pc"
unitToPointsConversionFactor: 12.0
stepUpCycle: ten
stepDownCycle: half];
defaultUnits = [[NSUserDefaults standardUserDefaults]
objectForKey: @"NSMeasurementUnit"];
if (defaultUnits == nil)
defaultUnits = @"Centimeters";
ASSIGN(_unitName, uName);
ASSIGN(_abbreviation, abbrev);
_conversionFactor = factor;
ASSIGN(_stepUpCycle, upCycle);
ASSIGN(_stepDownCycle, downCycle);
}
}
+ (void)registerUnitWithName:(NSString *)unitName
abbreviation:(NSString *)abbreviation
unitToPointsConversionFactor:(float)conversionFactor
stepUpCycle:(NSArray *)stepUpCycle
stepDownCycle:(NSArray *)stepDownCycle
{
// FIXME
}
- (id)initWithScrollView:(NSScrollView *)aScrollView
orientation:(NSRulerOrientation)orientation
{
// FIXME
[super init];
_scrollView = aScrollView;
_orientation = orientation;
[self setMeasurementUnits: defaultUnits];
return self;
}
- (void)setMeasurementUnits:(NSString *)unitName
- (NSString *) unitName
{
// FIXME
ASSIGN(_measurementUnits, unitName);
return _unitName;
}
- (NSString *)measurementUnits
- (NSString *) abbreviation
{
return _measurementUnits;
return _abbreviation;
}
- (void)setClientView:(NSView *)aView
- (float) conversionFactor
{
if (_clientView == aView)
return;
return _conversionFactor;
}
if ([_clientView respondsToSelector: @selector(rulerView:willSetClientView:)])
[_clientView rulerView: self willSetClientView: aView];
- (NSArray *) stepUpCycle
{
return _stepUpCycle;
}
- (NSArray *) stepDownCycle
{
return _stepDownCycle;
}
- (void) dealloc
{
[_unitName release];
[_abbreviation release];
[_stepUpCycle release];
[_stepDownCycle release];
[super dealloc];
}
@end
@implementation NSRulerView
/*
* Class variables
*/
static NSMutableDictionary *units = nil;
/*
* Class methods
*/
+ (void) initialize
{
if (self == [NSRulerView class])
{
NSArray *array05;
NSArray *array052;
NSArray *array2;
NSArray *array10;
NSDebugLog(@"Initialize NSRulerView class\n");
[self setVersion: 0.01];
units = [[NSMutableDictionary alloc] init];
array05 = [NSArray arrayWithObject: [NSNumber numberWithFloat: 0.5]];
array052 = [NSArray arrayWithObjects: [NSNumber numberWithFloat: 0.5],
[NSNumber numberWithFloat: 0.2], nil];
array2 = [NSArray arrayWithObject: [NSNumber numberWithFloat: 2.0]];
array10 = [NSArray arrayWithObject: [NSNumber numberWithFloat: 10.0]];
[self registerUnitWithName: @"Inches"
abbreviation: @"in"
unitToPointsConversionFactor: 72.0
stepUpCycle: array2
stepDownCycle: array05];
[self registerUnitWithName: @"Centimeters"
abbreviation: @"cm"
unitToPointsConversionFactor: 28.35
stepUpCycle: array2
stepDownCycle: array052];
[self registerUnitWithName: @"Points"
abbreviation: @"pt"
unitToPointsConversionFactor: 1.0
stepUpCycle: array10
stepDownCycle: array05];
[self registerUnitWithName: @"Picas"
abbreviation: @"pc"
unitToPointsConversionFactor: 12.0
stepUpCycle: array2
stepDownCycle: array05];
}
}
- (id) initWithScrollView: (NSScrollView *)aScrollView
orientation: (NSRulerOrientation)o
{
self = [super initWithFrame: NSZeroRect];
if (self != nil)
{
[self setScrollView: aScrollView];
[self setOrientation: o];
[self setMeasurementUnits: @"Points"]; /* FIXME: should be user's pref */
[self setRuleThickness: RULER_THICKNESS];
[self setOriginOffset: 0.0];
[self setReservedThicknessForAccessoryView: 0.0];
[self setReservedThicknessForMarkers: 0.0];
[self invalidateHashMarks];
}
return self;
}
+ (void) registerUnitWithName: (NSString *)uName
abbreviation: (NSString *)abbreviation
unitToPointsConversionFactor: (float)conversionFactor
stepUpCycle: (NSArray *)stepUpCycle
stepDownCycle: (NSArray *)stepDownCycle
{
GSRulerUnit *u = [GSRulerUnit unitWithName: uName
abbreviation: abbreviation
unitToPointsConversionFactor: conversionFactor
stepUpCycle: stepUpCycle
stepDownCycle: stepDownCycle];
[units setObject: u forKey: uName];
}
- (void) setMeasurementUnits: (NSString *)uName
{
GSRulerUnit *newUnit;
newUnit = [units objectForKey: uName];
if (newUnit == nil)
{
[NSException raise: NSInvalidArgumentException
format: @"Unknown measurement unit %@", uName];
}
ASSIGN(_unit, newUnit);
[self setNeedsDisplay: YES];
}
- (NSString *) measurementUnits
{
return [_unit unitName];
}
- (void) setClientView: (NSView *)aView
{
if (_clientView != nil
&& [_clientView respondsToSelector:
@selector(rulerView:willSetClientView:)])
{
[_clientView rulerView: self willSetClientView: aView];
}
/* NB: We should not RETAIN the clientView. */
_clientView = aView;
// FIXME Remove all markers
[self setMarkers: nil];
[self setNeedsDisplay: YES];
}
- (NSView *)clientView
- (BOOL) isOpaque
{
return YES;
}
- (NSView *) clientView
{
return _clientView;
}
- (void)setAccessoryView:(NSView *)aView
{
// FIXME
ASSIGN(_accessoryView, aView);
}
- (NSView *)accessoryView
- (void) setAccessoryView: (NSView *)aView
{
/* FIXME/TODO: support for accessory views is not implemented */
ASSIGN(_accessoryView, aView);
[self setNeedsDisplay: YES];
}
- (NSView *) accessoryView
{
return _accessoryView;
}
- (void)setOriginOffset:(float)offset
- (void) setOriginOffset: (float)offset
{
_originOffset = offset;
[self setNeedsDisplay: YES];
}
- (float)originOffset
- (float) originOffset
{
return _originOffset;
}
- (void)setMarkers:(NSArray *)markers
- (void) setMarkers: (NSArray *)newMarkers
{
// FIXME
if (newMarkers != nil && _clientView == nil)
{
[NSException raise: NSInternalInconsistencyException
format: @"Cannot set markers without a client view"];
}
if (newMarkers != nil)
{
ASSIGN(_markers, [NSMutableArray arrayWithArray: newMarkers]);
}
else
{
ASSIGN(_markers, nil);
}
[self setNeedsDisplay: YES];
}
- (NSArray *)markers
- (NSArray *) markers
{
return _markers;
}
- (void)addMarker:(NSRulerMarker *)aMarker
- (void) addMarker: (NSRulerMarker *)aMarker
{
[_markers addObject: aMarker];
float markerThickness = [aMarker thicknessRequiredInRuler];
if (_clientView == nil)
{
[NSException raise: NSInternalInconsistencyException
format: @"Cannot add a marker without a client view"];
}
if (markerThickness > [self reservedThicknessForMarkers])
{
[self setReservedThicknessForMarkers: markerThickness];
}
if (_markers == nil)
{
_markers = [[NSMutableArray alloc] initWithObjects: aMarker, nil];
}
else
{
[_markers addObject: aMarker];
}
[self setNeedsDisplay: YES];
}
- (void)removeMarker:(NSRulerMarker *)aMarker
- (void) removeMarker: (NSRulerMarker *)aMarker
{
[_markers removeObject: aMarker];
[self setNeedsDisplay: YES];
}
- (BOOL)trackMarker:(NSRulerMarker *)aMarker
withMouseEvent:(NSEvent *)theEvent
- (BOOL) trackMarker: (NSRulerMarker *)aMarker
withMouseEvent: (NSEvent *)theEvent
{
return [aMarker trackMouse: theEvent adding: YES];
/* FIXME/TODO: not implemented */
return NO;
}
- (void)moveRulerlineFromLocation:(float)oldLoc toLocation:(float)newLoc
- (void) moveRulerlineFromLocation: (float)oldLoc
toLocation: (float)newLoc
{
// FIXME
/* FIXME/TODO: not implemented */
}
- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect
- (void)drawRect: (NSRect)aRect
{
// FIXME
[[NSColor controlColor] set];
NSRectFill(aRect);
[self drawHashMarksAndLabelsInRect: aRect];
[self drawMarkersInRect: aRect];
}
- (void)drawMarkersInRect:(NSRect)aRect
- (float) _stepForIndex: (int)index
{
// FIXME
int newindex;
NSArray *stepCycle;
if (index > 0)
{
stepCycle = [_unit stepUpCycle];
newindex = (index - 1) % [stepCycle count];
return [[stepCycle objectAtIndex: newindex] floatValue];
}
else
{
stepCycle = [_unit stepDownCycle];
newindex = (-index) % [stepCycle count];
return 1 / [[stepCycle objectAtIndex: newindex] floatValue];
}
}
- (void) drawRect: (NSRect)rect
- (void) _verifyCachedValues
{
[self drawHashMarksAndLabelsInRect: rect];
[self drawMarkersInRect: rect];
if (! _cacheIsValid)
{
NSRect rect;
NSRect unitRect;
float cf;
int convIndex;
/* calculate the position of the zero coordinate in the ruler
* and the size one unit in document view has in the ruler */
cf = [_unit conversionFactor];
rect = NSMakeRect(_originOffset, _originOffset, cf, cf);
unitRect = [self convertRect: rect
fromView: [_scrollView documentView]];
if (_orientation == NSHorizontalRuler)
{
_unitToRuler = NSWidth(unitRect);
}
else
{
_unitToRuler = NSHeight(unitRect);
}
/* Calculate distance between marks. */
/* It must not be less than MIN_MARK_DISTANCE in ruler units
* and must obey the current unit's step cycles. */
_markDistance = _unitToRuler;
convIndex = 0;
/* make sure it's smaller than MIN_MARK_DISTANCE */
while ((_markDistance) > MIN_MARK_DISTANCE)
{
_markDistance /= [self _stepForIndex: convIndex];
convIndex--;
}
/* find the first size that's not < MIN_MARK_DISTANCE */
while ((_markDistance) < MIN_MARK_DISTANCE)
{
convIndex++;
_markDistance *= [self _stepForIndex: convIndex];
}
/* calculate number of small marks in each bigger mark */
_marksToMidMark = rint([self _stepForIndex: convIndex + 1]);
_marksToBigMark = _marksToMidMark
* rint([self _stepForIndex: convIndex + 2]);
/* Calculate distance between labels.
It must not be less than MIN_LABEL_DISTANCE. */
_labelDistance = _markDistance;
while (_labelDistance < MIN_LABEL_DISTANCE)
{
convIndex++;
_labelDistance *= [self _stepForIndex: convIndex];
}
/* number of small marks between two labels */
_marksToLabel = rint(_labelDistance / _markDistance);
/* format of labels */
if (_labelDistance / _unitToRuler >= 1)
{
ASSIGN(_labelFormat, @"%1.f");
}
else
{
/* smallest integral value not less than log10(1/labelDistInUnits) */
int log = ceil(log10(1 / (_labelDistance / _unitToRuler)));
NSString *string = [NSString stringWithFormat: @"%%.%df", (int)log];
ASSIGN(_labelFormat, string);
}
_cacheIsValid = YES;
}
}
- (void)invalidateHashMarks
- (void) drawHashMarksAndLabelsInRect: (NSRect)drawRect
{
// FIXME
NSGraphicsContext *ctxt = GSCurrentContext();
NSFont *font;
NSView *docView;
float firstVisibleLocation;
float visibleLength;
int firstVisibleMark;
int lastVisibleMark;
int mark;
NSRect baseLineRect;
float baselineLocation = [self baselineLocation];
NSPoint zeroPoint;
docView = [_scrollView documentView];
zeroPoint = [self convertPoint: NSMakePoint(_originOffset, _originOffset)
fromView: docView];
if (_orientation == NSHorizontalRuler)
{
_zeroLocation = zeroPoint.x;
}
else
{
_zeroLocation = zeroPoint.y;
}
[self _verifyCachedValues];
/* TODO: should be a user default */
font = [NSFont systemFontOfSize: 8];
[font set];
[[NSColor blackColor] set];
baseLineRect = [self convertRect: [docView bounds] fromView: docView];
if (_orientation == NSHorizontalRuler)
{
baseLineRect.origin.y = baselineLocation;
baseLineRect.size.height = 1;
baseLineRect = NSIntersectionRect(baseLineRect, drawRect);
firstVisibleLocation = NSMinX(baseLineRect);
visibleLength = NSWidth(baseLineRect);
}
else
{
baseLineRect.origin.x = baselineLocation;
baseLineRect.size.width = 1;
baseLineRect = NSIntersectionRect(baseLineRect, drawRect);
firstVisibleLocation = NSMinY(baseLineRect);
visibleLength = NSHeight(baseLineRect);
}
/* draw the base line */
NSRectFill(baseLineRect);
/* draw hash marks */
firstVisibleMark = ceil((firstVisibleLocation - _zeroLocation)
/ _markDistance);
lastVisibleMark = floor((firstVisibleLocation + visibleLength - _zeroLocation)
/ _markDistance);
for (mark = firstVisibleMark; mark <= lastVisibleMark; mark++)
{
float markLocation;
markLocation = _zeroLocation + mark * _markDistance;
if (_orientation == NSHorizontalRuler)
{
DPSmoveto(ctxt, markLocation, baselineLocation);
}
else
{
DPSmoveto(ctxt, baselineLocation, markLocation);
}
if ((mark % _marksToLabel) == 0)
{
float labelValue;
NSString *label;
DRAW_HASH_MARK(ctxt, LABEL_MARK_SIZE);
/* draw label */
/* FIXME: shouldn't be using NSCell to draw labels? */
labelValue = (markLocation - _zeroLocation) / _unitToRuler;
if ([self isFlipped] == NO && labelValue != 0.0)
{
label = [NSString stringWithFormat: _labelFormat, -labelValue];
}
else
{
label = [NSString stringWithFormat: _labelFormat, labelValue];
}
if (_orientation == NSHorizontalRuler)
{
DPSrmoveto(ctxt, 2, 0);
}
else
{
float labelWidth;
labelWidth = [font widthOfString: label];
DPSrmoveto(ctxt, 3 - labelWidth, 9);
}
DPSshow(ctxt, [label cString]);
}
else if ((mark % _marksToBigMark) == 0)
{
DRAW_HASH_MARK(ctxt, BIG_MARK_SIZE);
}
else if ((mark % _marksToMidMark) == 0)
{
DRAW_HASH_MARK(ctxt, MID_MARK_SIZE);
}
else
{
DRAW_HASH_MARK(ctxt, MARK_SIZE);
}
}
DPSstroke(ctxt);
}
- (void)setScrollView:(NSScrollView *)scrollView
- (void) drawMarkersInRect: (NSRect)aRect
{
// FIXME
_scrollView = scrollView;
NSRulerMarker *marker;
NSEnumerator *en;
en = [_markers objectEnumerator];
while ((marker = [en nextObject]) != nil)
{
[marker drawRect: aRect];
}
}
- (NSScrollView *)scrollView
- (void) invalidateHashMarks
{
_cacheIsValid = NO;
}
- (void) setScrollView: (NSScrollView *)sView
{
/* We do NOT retain the scrollView; the scrollView is retaining us. */
_scrollView = sView;
}
- (NSScrollView *) scrollView
{
return _scrollView;
}
- (void)setOrientation:(NSRulerOrientation)orientation
- (void) setOrientation: (NSRulerOrientation)o
{
_orientation = orientation;
_orientation = o;
}
- (NSRulerOrientation)orientation
@ -223,66 +640,85 @@ unitToPointsConversionFactor:(float)conversionFactor
return _orientation;
}
- (void)setReservedThicknessForAccessoryView:(float)thickness
- (void) setReservedThicknessForAccessoryView: (float)thickness
{
_reservedThicknessForAccessoryView = thickness;
[_scrollView tile];
}
- (float)reservedThicknessForAccessoryView
- (float) reservedThicknessForAccessoryView
{
return _reservedThicknessForAccessoryView;
}
- (void)setReservedThicknessForMarkers:(float)thickness
- (void) setReservedThicknessForMarkers: (float)thickness
{
_reservedThicknessForMarkers = thickness;
/* NSLog(@"requiredThicknessForMarkers: %f", thickness); */
_reservedThicknessForMarkers = thickness;
[_scrollView tile];
}
- (float)reservedThicknessForMarkers
- (float) reservedThicknessForMarkers
{
return _reservedThicknessForMarkers;
}
- (void)setRuleThickness:(float)thickness
- (void) setRuleThickness: (float)thickness
{
_ruleThickness = thickness;
_ruleThickness = thickness;
[_scrollView tile];
}
- (float)ruleThickness
- (float) ruleThickness
{
return _ruleThickness;
}
- (float)requiredThickness
- (float) requiredThickness
{
// FIXME
return 0.0;
return [self ruleThickness]
+ [self reservedThicknessForAccessoryView]
+ [self reservedThicknessForMarkers];
}
- (float)baselineLocation
- (float) baselineLocation
{
// FIXME
return 0.0;
return [self reservedThicknessForAccessoryView]
+ [self reservedThicknessForMarkers];
}
- (BOOL)isFlipped
/* FIXME ... we cache isFlipped in NSView. */
- (BOOL) isFlipped
{
return [_scrollView isFlipped];
if (_orientation == NSVerticalRuler)
{
return [[_scrollView documentView] isFlipped];
}
return YES;
}
// NSCoding protocol
- (void) encodeWithCoder: (NSCoder*)aCoder
- (void)encodeWithCoder:(NSCoder *)encoder
{
// FIXME
[super encodeWithCoder: aCoder];
/* FIXME/TODO: not implemented */
return;
}
- (id) initWithCoder: (NSCoder*)aDecoder
- (id)initWithCoder:(NSCoder *)decoder
{
// FIXME
return [super initWithCoder: aDecoder];
/* FIXME/TODO: not implemented */
return nil;
}
// NSObject protocol
- (void) dealloc
{
RELEASE(_unit);
RELEASE(_scrollView);
RELEASE(_clientView);
RELEASE(_accessoryView);
RELEASE(_markers);
RELEASE(_labelFormat);
[super dealloc];
}
@end