Re: NSView Examples (minus the examples)
Re: NSView Examples (minus the examples)
- Subject: Re: NSView Examples (minus the examples)
- From: Simon Stapleton <email@hidden>
- Date: Tue, 04 Sep 2001 10:09:36 +0100 (BST)
>
From: Sam Goldman <email@hidden>
>
To: email@hidden
>
Subject: Re: NSView Examples (minus the examples)
>
>
Come on, I know if someone says something, then another person will
>
disagree, then another person will chime in, and sooner rather than
>
later I'd know everything there was to know! I know this list.
I disagree...
<snippage>
Well, I've managed to get dragging to work, and it wasn't _that_ hard.
My approach is probably suboptimal, naive or just plain wrong, but it
works. Sort of.
Bear in mind that my classes are for the display of curves, so in a
generic sense they have to deal with the dragging of 'control points'.
The underlying model classes provide the following:
- (NSArray *) points; // Accessor to the points controlling the curve
and the view classes have
- (NSPoint) dragStart;
- (void) setDragStart: (NSPoint) point; // Also calls
setCurrentDragPosition:
- (NSPoint) currentDragPosition;
- (void) setCurrentDragPosition: (NSPoint) point;
- (NSMutableArray *) selectedPoints;
- (BOOL) isDragging;
- (void) setIsDragging: (BOOL) yesNo;
and override the following:
- (void) mouseDown: (NSEvent *) event;
- (void) mouseDragged: (NSEvent *) event;
- (void) mouseUp: (NSEvent *) event;
So. In mouseDown, we see if we're dragging. If we are, something
went wrong with the previous drag (mouseUp happened outside our
view), so we work out the difference between [self
currentDragPosition] and [self dragStart], and make any points in
[self selectedPoints] move themselves by that amount. We then
extract the co-ordinates of the click (in view co-ordinates), and
work out what points are affected. If any, we add that point to the
list of selected points (clearing the list if we don't have the multi-
select modifier key pressed) and then [self setIsDragging:YES] and
[self setDragStart:] with the current co-ordinate. This doesn't
allow for 'rubberband selecting', doubleclicking etc, but that's
relatively easy to add later. Of course, if you can't handle the
click, pass it on to super.
In mouseDragged, we first check if we're dragging, and if not, pass
directly to super. If we are, we again extract the mouse co-
ordinates, again in view co-ordinates, and work out a delta amount
between [self currentDragPosition] and that co-ordinate, and tell
each point in [self selectedPoints] to move itself by that amount.
The model objects notify their owning curves to modify themselves,
those curves send notifications which get picked up by the view, and
the view redraws the curves as required. We then store the extracted
co-ordinate in currentDragPosition.
In mouseUp, we again check if we're dragging and, if not, pass on to
super. Otherwise, do a final update to the positions of the selected
points, and then [self setIsDragging:NO]
Note that my points are real model classes, not NSPoints, but the
same logic applies if they are just NSPoints contained within some
other model class.
Note also I'm using NSNotificationQueue to batch up the notifications
and stop the system getting flooded (I could have >200 points being
moved at once)
Like I said, it's probably inefficient, naive or just plain wrong,
but it seems to work reasonably well.
Simon
--
If the answer isn't obvious, the question is a distraction. Go find
an easier question.