Re: Rects and points...
Re: Rects and points...
- Subject: Re: Rects and points...
- From: Tom Waters <email@hidden>
- Date: Tue, 20 Nov 2001 14:06:40 -0800
I hadn't played with BezierPath's before answering your question, so i
spent a few more minutes adding some interaction to the answer... You
can now click on the control points and drag them around.
#import <Cocoa/Cocoa.h>
#define NUMPOINTS 4
#define HITDIST 8
@interface MyView : NSView
{
NSPoint points[NUMPOINTS];
}
@end
@implementation MyView
- (id)initWithFrame:(NSRect)r
{
if (self = [super initWithFrame:r]) {
points[0] = NSMakePoint(0.0, 0.0);
points[1] = NSMakePoint(50.0, 100.0);
points[2] = NSMakePoint(150.0,50.0);
points[3] = NSMakePoint(200.0,150.0);
}
return self;
}
- (void)drawRect:(NSRect)rect
{
NSBezierPath *curve = [NSBezierPath bezierPath];
[[NSColor blackColor] set];
[curve moveToPoint:points[0]];
[curve lineToPoint:points[1]];
[curve lineToPoint:points[2]];
[curve lineToPoint:points[3]];
[curve stroke];
[curve removeAllPoints];
[[NSColor redColor] set];
[curve moveToPoint:points[0]];
[curve curveToPoint:points[3] controlPoint1:points[1]
controlPoint2:points[2]];
[curve stroke];
}
- (int)pointAtPoint:(NSPoint)p
{
int n = NUMPOINTS;
int i;
for (i = 0; i < n; i++) {
float dx = p.x - points[i].x;
float dy = p.y - points[i].y;
float dist = sqrt(dx*dx + dy*dy);
if (dist < HITDIST)
return i;
}
return -1;
}
- (void)mouseDown:(NSEvent *)theEvent
{
NSPoint p = [self convertPoint: [theEvent locationInWindow]
fromView: nil];
int point = [self pointAtPoint:p];
if (point > -1) {
do {
theEvent = [[self window]
nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask];
p = [self convertPoint:[theEvent locationInWindow] fromView:nil];
points[point] = p;
[self setNeedsDisplayInRect:[self bounds]];
} while ([theEvent type] == NSLeftMouseDragged);
}
}
@end
On Tuesday, November 20, 2001, at 01:30 PM, Tom Waters wrote:
There are a lot of problems with your example. Several are fundamental
to how cocoa applications are supposed to render pixels on the screen.
It seems you are trying to do things in an "immediate mode", as in,
"draw these curves now!" Cocoa applications do things differently.
You want to create a subclass of NSView which overrides drawRect to do
the drawing you want, and then just "let things happen". drawRect will
be called automatically whenever the display needs to change. If you
want to cause an update, say when the user moves a slider, you just put
a [myView setNeedsDisplay:YES] in the IB action callback for the slider.
As far as the specifics of your attempt go:
is this a method on an NSView subclass?
if so, you don't want to have an IBAction method for drawing, you want
to override drawRect:
also, calling initWithFrame in the middle of your draw function is
wrong. initWithFrame will be called once by the runtime when your NIB
is loaded.
setNeedsDisplay is a method for telling the system to call drawRect...
it has no effect in your example.
Also, note that even if your example was able to get things to appear
on the screen, you're not creating a proper Bezier curve. They are
cubic curves and require four points to get the classic curve you
expect. From the postcript world: currentpoint, the curveto point and
two control points.
Here's my guess on an example that will work better for you. Just put
a custom view into a window in IB and edit its custom class attribute
to be a class called MyView, and have this in the implementation:
[ code snipped]
On Tuesday, November 20, 2001, at 07:16 AM, Riccardo Santato wrote:
Hi there.
I'd reaally like someone of you help me in making this code work.
I'm just having fun with Bezier curves, but nothing is displayed... Can
you tell me please where are the errors ?
Many thanx to everyone 4 your kindness
[code snipped]
--
Riccardo Santato
www.riccardosantato.com
_______________________________________________
cocoa-dev mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/cocoa-dev