Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Simple NSBezier Drawing Question

Simple NSBezier Drawing Question
Thread Tools
Mac Elite
Join Date: Jan 2001
Location: New York
Status: Offline
Reply With Quote
Jan 30, 2001, 09:29 PM
 
I've been trying and trying and trying. But I can't draw even a simple little circle in Cocoa. I make the subclass. In IB I make a NSView that gets customized to extend the subclass I make. And then in Project Builder I call the display method of the NSView and then draw an NSBezierPath that I call a fill method on. It compiles fine, but when I click the button that calls the display method nothing happens. I'm thinking maybe the problem is that the NSView I drag and drop from the pallete and that then becomes a subclass of NSView.

If anyone could show me the most simple way to just draw a circle when a button it clicked using NSBezierPath I would greatly appreciate and would be in debt to you for quite a while.

Thank you ever so much,
Dave

------------------
Think Different.
     
Admin Emeritus
Join Date: Oct 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Jan 30, 2001, 09:52 PM
 
Have you tried looking at SonOfSillyBalls at Apple's source code repository? It's a Cocoa App which draws silly balls using (I think) NSBezierPath. You may want to check that out.
http://developer.apple.com/samplecod...SillyBalls.htm
"Against stupidity, the gods themselves contend in vain" (Schiller)
     
Dedicated MacNNer
Join Date: Jun 2000
Location: Dundas, Ontario, Canada
Status: Offline
Reply With Quote
Jan 31, 2001, 10:18 AM
 
Son of Silly Balls is helpful yet a little over-complicated for what most of us may want to do because of how it side-steps the "drawRect" method. If you create the subclass of NSView and then implement the drawRect method in it to make a few calls to NSBezierPath to draw the circle it should just draw it (I did something like that a few days ago and it worked great). As far as the button, I would just create a global boolean and get the button to set it when pressed and the drawRect to only draw the circle when the flag is set. I am not sure which is the best way to implement that button trigger but for straight drawing just use drawRect.

Hope that helps,
Jeff.

[This message has been edited by Apocalypse (edited 01-31-2001).]
Spectral Class
"Shedding Light on Innovation"
     
davecom  (op)
Mac Elite
Join Date: Jan 2001
Location: New York
Status: Offline
Reply With Quote
Jan 31, 2001, 03:17 PM
 
[self display] calls the drawRect method right?
     
ali
Forum Regular
Join Date: Sep 2000
Status: Offline
Reply With Quote
Jan 31, 2001, 05:37 PM
 
You basically override drawRect: and implement your drawing, everything else should be automatic... Below is a snippet of code from a view which draws a circle where the user clicks.
Ali


The interface:

@interface MyView : NSView {
NSPoint center;
float radius;
}


And part of the code:

@implementation MyView

- (id)initWithFrameNSRect)frame {
[super initWithFrame:frame];
center.x = 50.0;
center.y = 50.0;
radius = 10.0;
return self;
}


// Recommended way to handle events is to override NSResponder (superclass
// of NSView) methods in the NSView subclass. One such method is mouseUp:.
// These methods get the event as the argument. The event has the mouse
// location in window coordinates; use convertPoint:fromView: (with "nil"
// as the view argument) to convert this point to local view coordinates.
//
// Note that once we get the new center, we call setNeedsDisplay:YES to
// mark that the view needs to be redisplayed (which is done automatically
// by the AppKit).

- (void)mouseUpNSEvent *)event {
NSPoint eventLocation = [event locationInWindow];
center = [self convertPoint:eventLocation fromView:nil];
[self setNeedsDisplay:YES];
}


// setRadiusFromControl: is an action method which lets you change the radius of the dot.
// We assume the sender is a control capable of returning a floating point
// number; so we ask for it's value, and mark the view as needing to be
// redisplayed. A possible optimization is to check to see if the old and
// new value is the same, and not do anything if so.

- (void)setRadiusFromControlid)sender {
radius = [sender floatValue];
[self setNeedsDisplay:YES];
}


// drawRect: should be overridden in subclassers of NSView to do necessary
// drawing in order to recreate the the look of the view. It will be called
// to draw the whole view or parts of it (pay attention the rect argument);
// it will also be called during printing if your app is set up to print.
// Here we first clear the view to white, then draw a red dot at its
// current location.

- (void)drawRectNSRect)rect {
NSRect dotRect;

[[NSColor whiteColor] set];
NSRectFill([self bounds]); // Same as [[NSBezierPath bezierPathWithRect:[self bounds]] fill]

dotRect.origin.x = center.x - radius;
dotRect.origin.y = center.y - radius;
dotRect.size.width = 2 * radius;
dotRect.size.height = 2 * radius;

[[NSColor redColor] set];
[[NSBezierPath bezierPathWithOvalInRect:dotRect] fill];
}


// Views which totally redraw their whole bounds without needing any of the
// views behind it should override isOpaque to return YES. This is a performance
// optimization hint for the display subsystem.

- (BOOL)isOpaque {
return YES;
}

@end
     
ali
Forum Regular
Join Date: Sep 2000
Status: Offline
Reply With Quote
Jan 31, 2001, 05:38 PM
 
You basically override drawRect: and implement your drawing, everything else should be automatic... Below is a snippet of code from a view which draws a circle where the user clicks.
Ali


The interface:

@interface MyView : NSView {
NSPoint center;
float radius;
}


And part of the code:

@implementation MyView

- (id)initWithFrameNSRect)frame {
[super initWithFrame:frame];
center.x = 50.0;
center.y = 50.0;
radius = 10.0;
return self;
}


// Recommended way to handle events is to override NSResponder (superclass
// of NSView) methods in the NSView subclass. One such method is mouseUp:.
// These methods get the event as the argument. The event has the mouse
// location in window coordinates; use convertPoint:fromView: (with "nil"
// as the view argument) to convert this point to local view coordinates.
//
// Note that once we get the new center, we call setNeedsDisplay:YES to
// mark that the view needs to be redisplayed (which is done automatically
// by the AppKit).

- (void)mouseUpNSEvent *)event {
NSPoint eventLocation = [event locationInWindow];
center = [self convertPoint:eventLocation fromView:nil];
[self setNeedsDisplay:YES];
}


// setRadiusFromControl: is an action method which lets you change the radius of the dot.
// We assume the sender is a control capable of returning a floating point
// number; so we ask for it's value, and mark the view as needing to be
// redisplayed. A possible optimization is to check to see if the old and
// new value is the same, and not do anything if so.

- (void)setRadiusFromControlid)sender {
radius = [sender floatValue];
[self setNeedsDisplay:YES];
}


// drawRect: should be overridden in subclassers of NSView to do necessary
// drawing in order to recreate the the look of the view. It will be called
// to draw the whole view or parts of it (pay attention the rect argument);
// it will also be called during printing if your app is set up to print.
// Here we first clear the view to white, then draw a red dot at its
// current location.

- (void)drawRectNSRect)rect {
NSRect dotRect;

[[NSColor whiteColor] set];
NSRectFill([self bounds]); // Same as [[NSBezierPath bezierPathWithRect:[self bounds]] fill]

dotRect.origin.x = center.x - radius;
dotRect.origin.y = center.y - radius;
dotRect.size.width = 2 * radius;
dotRect.size.height = 2 * radius;

[[NSColor redColor] set];
[[NSBezierPath bezierPathWithOvalInRect:dotRect] fill];
}


// Views which totally redraw their whole bounds without needing any of the
// views behind it should override isOpaque to return YES. This is a performance
// optimization hint for the display subsystem.

- (BOOL)isOpaque {
return YES;
}

@end
     
davecom  (op)
Mac Elite
Join Date: Jan 2001
Location: New York
Status: Offline
Reply With Quote
Jan 31, 2001, 06:53 PM
 
Thank you Ali! This is exactly what I needed! I think this will be helpful to quite a few people.

------------------
Think Different.
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 12:15 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2