PDA

View Full Version : Interactive mouse dragging


Feanor
2002.07.02, 08:32 AM
I've got interactive mouse dragging working in a simple way in StormCloud, but I want to improve it. Right now, the code looks like this:


NSPoint mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
NSSize frameSize = [self frame].size;
BOOL dragging;

// the modal event loop
dragging = YES;
while( dragging ) {

// hog all successive mouse drags and following mouse up
theEvent = [[self window] nextEventMatchingMask: NSLeftMouseUpMask|NSLeftMouseDraggedMask];
mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];

if( [theEvent type] == NSLeftMouseDragged ) {

// we have to scroll along with the drag
[self autoscroll:theEvent];
// force a redraw so that we see the rectangle while dragging
[self display];
}

// we got the mouse up
else {

// we aren't doing anything special yet...
;
dragging = NO;
}

// redraw one last time
[self setNeedsDisplay:YES];
}


[self autoscroll] works passably, but it requires the user to wiggle the mouse (to generate mouseDragged events) to get it to scroll. I've thought of a complicated solution using timers, but I'd have to create and invalidate a timer for every mouseDragged event -- not efficient!

I may be able to set up a tracking rectangle in the modal event loop. (just thought of this) Argh, the problem as I see it is that I must be able to receive new events, but I must also be able to execute scrolling code when there are no events. Instead of a new timer for every mouseDragged, could I have a single timer at the start of mouseDown to call code to check a flag and mouse position, and scroll as required?

kainsin
2002.07.02, 09:15 AM
Your second option seems reasonable. Set up a timer at mouseDown and keep it going until mouseUp. With every fire of the timer, check the difference in the mouse position and scroll as necessary.

Feanor
2002.07.02, 10:59 AM
In fact, there is a specific mechanism for generating events for use in this kind of situation: NSPeriodicEvents. They can be set to happen at a certain interval, and are then grabbed manually.