• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bezier folies
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bezier folies


  • Subject: Re: Bezier folies
  • From: Tom Waters <email@hidden>
  • Date: Thu, 29 Nov 2001 09:37:46 -0800

I think an even better design would be to create an informal dataSource protocol for your view, a la NSTableView...

Here's the example I did for Riccardo last time, extended to have a controller class acting as the view's datasource.

I'll leave the IB connecting as an exercise to the reader. (there's a button which is connected to the Controller's randomizePoints: action)

// MyView.h
#import <Cocoa/Cocoa.h>

@interface NSObject (MyViewDataSource)
- (NSPoint)pointAtIndex:(int)i;
- (void)setPoint:(NSPoint)p atIndex:(int)i;
- (int)pointAtPoint:(NSPoint)p;
@end


@interface MyView : NSView
{
id dataSource;
}
@end

// MyView.m
#import "MyView.h"

@implementation MyView

- (void)drawRect:(NSRect)rect
{
NSPoint p0 = [dataSource pointAtIndex:0];
NSPoint p1 = [dataSource pointAtIndex:1];
NSPoint p2 = [dataSource pointAtIndex:2];
NSPoint p3 = [dataSource pointAtIndex:3];
NSBezierPath *curve = [NSBezierPath bezierPath];
[[NSColor blackColor] set];
[curve moveToPoint:p0];
[curve lineToPoint:p1];
[curve lineToPoint:p2];
[curve lineToPoint:p3];
[curve stroke];
[curve removeAllPoints];
[[NSColor redColor] set];
[curve moveToPoint:p0];
[curve curveToPoint:p3 controlPoint1:p1 controlPoint2:p2];
[curve stroke];
}

- (void)mouseDown:(NSEvent *)theEvent
{
NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
int point = [dataSource pointAtPoint:p];
if (point > -1) {
do {
theEvent = [[self window] nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask];
p = [self convertPoint:[theEvent locationInWindow] fromView:nil];
[dataSource setPoint:p atIndex:point];
[self setNeedsDisplayInRect:[self bounds]];
} while ([theEvent type] == NSLeftMouseDragged);
}
}

@end


// Controller.h
#import <Cocoa/Cocoa.h>

#define NUMPOINTS 4
#define HITDIST 8
@interface Controller : NSObject
{
IBOutlet id view;
IBOutlet id window;
NSPoint points[NUMPOINTS];
}

- (NSPoint)pointAtIndex:(int)i;
- (void)setPoint:(NSPoint)p atIndex:(int)i;
- (int)pointAtPoint:(NSPoint)p;
- (IBAction)randomizePoints:(id)sender;
@end

// Controller.m
#import "Controller.h"

@implementation Controller

- (void)awakeFromNib
{
[self randomizePoints:self];
}

- (NSPoint)pointAtIndex:(int)i
{
return points[i];
}

- (void)setPoint:(NSPoint)p atIndex:(int)i
{
points[i] = p;
}

- (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;
}

- (IBAction)randomizePoints:(id)sender
{
NSRect bounds = [view bounds];
int i;
for (i = 0; i < NUMPOINTS; i++) {
points[i].x = bounds.size.width * random() / 0x7fffffff;
points[i].y = bounds.size.height * random() / 0x7fffffff;
}
[view setNeedsDisplay:YES];
}

@end

On Thursday, November 29, 2001, at 08:54 AM, email@hidden wrote:

Hi everybody,

Do you remember I was toying around the NSBezierPath class ? Well, I've
decided to go a little step further and I'm now trying to implement a
little GUI. The main goal is : "I press a button and then a random curve
is generated".
Here are the step I've done so far:

1) I've created 2 interfaces: a NSView subclass and another "controller"
istantiated class for the gui...

2) ... I've #imported the NSView class inside the other...

3) ... I've made my NSPoints in the NSView class as @public ...

4) I try to access the points from the main class but it tells me it's
"undeclared" ?!?

How can it be possible ? How can I make a class gain variables and values
from a "brother" one ?!?

Better design would require that you define the variables as @private and then create accessor methods to access them/change them. That way you can use the standard [object_name method_name] syntax to access them.

If you want to learn more about accessor methods you may want to take a look at Recipe 1 of "Vermont Recipes" which is located at http://www.stepwise.com/Articles/VermontRecipes/


References: 
 >Re: Bezier folies (From: email@hidden)

  • Prev by Date: NSScreen isn't notified of resolution switch
  • Next by Date: Re: Displaying Unicode
  • Previous by thread: Re: Bezier folies
  • Next by thread: Responder chain design
  • Index(es):
    • Date
    • Thread