Re: NSBezierPath and draw NSString in NSView.
Re: NSBezierPath and draw NSString in NSView.
- Subject: Re: NSBezierPath and draw NSString in NSView.
- From: Candide Kemmler <email@hidden>
- Date: Wed, 11 Jul 2001 12:57:05 +0200
Didn't read all your code to be honest, but this is how I draw a String
from another object that's specialized for this:
-(void) paintLabel: (NSString *) aLabel sizeAdjustment:(int)anAdjustment
angle:(float)anAngle x:(int) anX y:(int)anY scale:(float)aScale
{
NSPoint o;
NSAffineTransform *t = [ NSAffineTransform transform ];
NSFont *font = [ NSFont fontWithName;fontName
size:fontSize+anAdjustment];
[atts setObject:font forKey:NSFontAttributeName ];
[ t translateXBy:anX yBy:anY ];
[ t rotateByRadians:-anAngle];
[ t scaleBy: aScale ];
[ t invert ];
o.x = 0;
o.y = 0;
[ aLabel drawAtPoint:o withAttributes:atts ];
[ t invert ];
[ t concat ];
}
The object which has this method is defined like so:
@interface LabelStyle : NSObject
{
NSString *name;
NSMutableString * fontName;
int fontSize;
NSFont * styleDefaultFont;
NSMutableDictionary *atts;
}
Works very nicely !
At first sight, you might have forgotten the
[ t invert ];
[ t concat ];
part. It's necessary because when you apply a transformation with [ t
concat ], it gets multiplied by your view's current transformation. If
you do it again with yet another transformation, you get a totally
useless transformation. So you need to invert your last transformation
and apply it again to reset your view's transformation to what it was at
the beginning. I personally thing this is an unnecessary bore left to
the programmer.
Let me know if that helped you.
candide
Le mardi 10 juillet 2001, ` 06:34, Michel Haver a icrit :
I am porting a old pascal application to cocoa but ran into some
problems
with the NSBezierPath and draw NSString in NSView.
I start with the example code from Learning cocoa, Appendix A: Drawing
in
Cocoa Draw NSString, Draw with NSBezierPath examples
From the example code I try to implement my pascal code with looks
something
like this:
procedure drawScoreArray (var Nr: integer; angle: real);
var
radian_angle, x, y: real;
drawAngle, n, score: integer;
top, bottom, left, right, i: integer;
score: array[1..12] of string[3];
myrect: rect;
begin
Textmode(0);
left := 170;
bottom := 235;
top := 55;
right := 350;
SetRect(myrect, left, top, right, bottom);
i := 0;
TextSize(14);
n := 1;
score[1] := '0';
score[2] := '10';
score[3] := '20';
score[4] := '30';
score[5] := '40';
score[6] := '50';
score[7] := '60';
score[8] := '70';
score[9] := '80';
score[10] := '90';
score[11] := '100';
TextSize(14);
for drawAngle := 0 to 360 do
begin
radian_angle := pi * (drawAngle - 90) / 180;
x := 250 + 105 * cos(radian_angle);
y := 145 + 105 * sin(radian_angle);
MoveTo(trunc(x), trunc(y));
DrawString(score[n]);
drawAngle := drawAngle + 29;
n := n + 1;
end;
Now I adjust the Draw with NSBezierPath example code and get something
like
this:
#import <Cocoa/Cocoa.h>
@interface MyView : NSView
{
NSString *string;
// NSColor *circleStrokeColor;
NSFont *font;
NSBezierPath *circlePath;
// Declarations for the scorearay
NSMutableArray * scoreArray;
}
// Standard view create/free methods
- (id)initWithFrame:(NSRect)frame;
- (void)dealloc;
- (NSBezierPath *)circlePath;
- (void)setCirclePath: (NSBezierPath *)newPath;
- (NSBezierPath *)scoreArrayPath;
- (void)set`ScoreArrayPath: (NSBezierPath *)newPath;
- (void)setString:(NSString *)value;
- (void)setFont:(NSFont *)value;
- (void)awakeFromNib;
- (BOOL)isOpaque;
- (NSBezierPath *)createCirclePath;
- (NSBezierPath *)createScoreArrayPath;
- (void)drawCircle;
- (void)drawCircle1;
- (void)drawScoreArray
// Custom methods for actions this view implements
//- (IBAction)setRadius:(id)sender;
//- (IBAction)setColor:(id)sender;
@end
-----------------------------------
#import "MyView.h"
#import <ApplicationServices/ApplicationServices.h>
@implementation MyView
- (id)init
{
[super init];
// Initialize the Score Array
scoreArray = [[ NSMutableArray alloc ] initWithCapacity: 10 ];
// Initialize the scoreArray with 12 elements
// Element 0 on index 0
[ scoreArray insertObject: @"0" atIndex: 0 ];
// Element 10 on index 1
[ scoreArray insertObject: @"10" atIndex: 1 ];
// Element 20 on index 2
[ scoreArray insertObject: @"20" atIndex: 2 ];
// Element 30 on index 3
[ scoreArray insertObject: @"30" atIndex: 3 ];
// Element 40 on index 4
[ scoreArray insertObject: @"40" atIndex: 4 ];
// Element 50 on index 5
[ scoreArray insertObject: @"50" atIndex: 5 ];
// Element 60 on index 6
[ scoreArray insertObject: @"60" atIndex: 6 ];
// Element 70 on index 7
[ scoreArray insertObject: @"70" atIndex: 7 ];
// Element 80 on index 8
[ scoreArray insertObject: @"80" atIndex: 8 ];
// Element 90 on index 9
[ scoreArray insertObject: @"90" atIndex: 9 ];
// Element 100 on index 10
[ scoreArray insertObject: @"100" atIndex: 10 ];
return self;
}
-(BOOL)isFlipped {
return YES;
}
- (BOOL)isOpaque
{
return YES;
}
- (void)awakeFromNib
{
[self setCirclePath: [self createCirclePath]];
[self setScoreArrayPath: [self createScoreArrayPath]];
}
- (id)initWithFrame:(NSRect)frame {
[super initWithFrame:frame];
// [self setString: @"Hello World 0456789"];
[self setFont: [NSFont systemFontOfSize: 18]];
// circleStrokeColor = [[NSColor redColor] retain];
return self;
}
// dealloc is the method called when objects are being freed.
- (void)dealloc {
// [circleStrokecolor release];
// [color release];
[super dealloc];
}
- (void)setString:(NSString *)value {
[string autorelease];
string = [value copy];
[self setNeedsDisplay: YES];
}
- (void)setFont:(NSFont *)value {
[value retain];
[font autorelease];
font = value;
[self setNeedsDisplay: YES];
}
- (void)drawRect:(NSRect)rect {
// Leave the Directory and myBounds on
NSRect myBounds = [self bounds];
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
// Paint a white background
[[NSColor whiteColor] set];
[NSBezierPath fillRect:myBounds];
// Draw some crosshairs on the view
[[NSColor lightGrayColor] set];
[NSBezierPath
strokeLineFromPoint:NSMakePoint(0,(myBounds.size.height/2.0))
toPoint:NSMakePoint(myBounds.size.width, (myBounds.size.height/2.0))];
[NSBezierPath
strokeLineFromPoint:NSMakePoint((myBounds.size.width/2.0),
0) toPoint:NSMakePoint((myBounds.size.width/2.0),
myBounds.size.height)];
// Draw a black border around the view.
[[NSColor blackColor] set];
[NSBezierPath strokeRect:myBounds];
// Render a string.
// [attrs setObject: font forKey: NSFontAttributeName];
// [string drawAtPoint: NSMakePoint((myBounds.size.width/4.0), 5)
withAttributes: attrs];
// Draw the inner and outer circle of the circleRouletteRound1
[self drawCircle];
[self drawCircle1];
// Draw the content of the scoreArray
// [self drawScoreArray];
}
- (NSBezierPath *)circlePath
{
return circlePath;
}
- (void)setCirclePath:(NSBezierPath *)newPath
{
[newPath retain];
[circlePath release];
circlePath = newPath;
}
// initialize the path for ScoreArray
- (NSBezierPath *)scoreArrayPath
{
return scoreArrayPath;
}
- (void)setScoreArrayPath:(NSBezierPath *)newPath
{
[newPath retain];
[scoreArrayPath release];
scoreArrayPath = newPath;
}
- (NSBezierPath *)createCirclePath
{
// An NSPoint that is re-used to create the arrow model.
NSPoint point;
NSBezierPath *model = [NSBezierPath bezierPath];
// Create simple circle with it's center at (0,0).
point.x = 1;
point.y = 0;
[model moveToPoint:point];
point.x = 0;
[model appendBezierPathWithArcWithCenter:point
radius:1.0 startAngle:0 endAngle:360];
// Draw a plus sign.
// Start with a horizontal line.
point.x = .05;
point.y = 0;
[model moveToPoint:point];
point.x = -.05;
[model lineToPoint:point];
// Draw the vertical line
point.x = 0;
point.y = .05;
[model moveToPoint:point];
point.y = -.05;
[model lineToPoint:point];
// Finish drawing.
[model closePath];
return model;
}
- (NSBezierPath *)createScoreArrayPath
{
// An NSPoint that is re-used to create the arrow model.
NSPoint point;
NSBezierPath *model = [NSBezierPath bezierPath];
// Create simple circle with it's center at (0,0).
point.x = 0;
point.y = 0;
[model moveToPoint:point];
point.x = 0;
[model appendBezierPathWithArcWithCenter:point
radius:1.0 startAngle:0 endAngle:360];
// And now I am run into the deep space of
BezierPathWithArcWithCenter
// ?? How to proceed?
[model closePath];
return model;
}
- (void)drawCircle
{
NSBezierPath *circleToDraw;
NSAffineTransform *translationMatrix;
NSAffineTransform *scaleMatrix;
//Make the Circle grow with resizing MyView
NSRect myBounds = [self bounds];
//Make screenLocation grow with the NSView
//NSPoint screenLocation = NSMakePoint(50, 50);
NSPoint screenLocation = NSMakePoint(myBounds.size.width/2.0,
myBounds.size.height/2.0);
NSColor *circleStrokeColor = [NSColor blackColor];
// NSColor *circleStrokeColor = [NSColor blueColor];
// NSColor *circleFillColor = [NSColor blueColor];
float circleRadius = 150.0;
translationMatrix = [NSAffineTransform transform];
[translationMatrix translateXBy: screenLocation.x yBy:
screenLocation.y];
scaleMatrix = [NSAffineTransform transform];
[scaleMatrix scaleBy: circleRadius];
[scaleMatrix appendTransform:translationMatrix];
circleToDraw = [scaleMatrix transformBezierPath:[self circlePath]];
// [circleFillColor set];
// [circleToDraw fill];
[circleStrokeColor set];
[circleToDraw setLineWidth:2.0];
[circleToDraw stroke];
}
- (void)drawCircle1
{
NSBezierPath *circleToDraw;
NSAffineTransform *translationMatrix;
NSAffineTransform *scaleMatrix;
//Make the Circle grow with resizing MyView
NSRect myBounds = [self bounds];
//Make screenLocation grow with the NSView
//NSPoint screenLocation = NSMakePoint(175, 150);
NSPoint screenLocation = NSMakePoint(myBounds.size.width/2.0,
myBounds.size.height/2.0);
NSColor *circleStrokeColor = [NSColor blackColor];
// NSColor *circleFillColor = [NSColor blueColor];
float circleRadius = 110.0;
translationMatrix = [NSAffineTransform transform];
[translationMatrix translateXBy: screenLocation.x yBy:
screenLocation.y];
scaleMatrix = [NSAffineTransform transform];
[scaleMatrix scaleBy: circleRadius];
[scaleMatrix appendTransform:translationMatrix];
circleToDraw = [scaleMatrix transformBezierPath:[self circlePath]];
// [circleFillColor set];
// [circleToDraw fill];
[circleStrokeColor set];
[circleToDraw setLineWidth:2.0];
[circleToDraw stroke];
}
- (void)drawScoreArrayCircle
{
NSBezierPath *circleToDraw;
NSAffineTransform *translationMatrix;
NSAffineTransform *scaleMatrix;
//Make the Circle grow with resizing MyView
NSRect myBounds = [self bounds];
//Make screenLocation grow with the NSView
//NSPoint screenLocation = NSMakePoint(50, 50);
NSPoint screenLocation = NSMakePoint(myBounds.size.width/2.0,
myBounds.size.height/2.0);
// Read somehow the scoreArray from 0 to 11 and draw the string
at
Point on the circle with 30 degrees for each element. How??
NSColor *circleStrokeColor = [NSColor blackColor];
// NSColor *circleStrokeColor = [NSColor blueColor];
// NSColor *circleFillColor = [NSColor blueColor];
float circleRadius = 130.0;
translationMatrix = [NSAffineTransform transform];
[translationMatrix translateXBy: screenLocation.x yBy:
screenLocation.y];
scaleMatrix = [NSAffineTransform transform];
[scaleMatrix scaleBy: circleRadius];
[scaleMatrix appendTransform:translationMatrix];
circleToDraw = [scaleMatrix transformBezierPath:[self circlePath]];
// [circleFillColor set];
// [circleToDraw fill];
[circleStrokeColor set];
[circleToDraw setLineWidth:2.0];
[circleToDraw stroke];
}
@end
Question:
How can I draw my ScoreArray from 0 to 11 with drawAtPoint and
NSBezierPath
and draw the scoreArray on the circle with 30 degrees difference for
each
element?
The example code don't feels like keep it simple stupid, but I want to
implement the whole application in cocoa and nothing but cocoa, not
carbon.
_______________________________________________
cocoa-dev mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/cocoa-dev