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?
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?