mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 12:00:52 +00:00
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:
parent
1aebe415da
commit
d965b511dc
2 changed files with 690 additions and 219 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue