Snapping Window Locations (partial solution)
Snapping Window Locations (partial solution)
- Subject: Snapping Window Locations (partial solution)
- From: Charles Jolley <email@hidden>
- Date: Wed, 19 Jun 2002 09:49:30 -0500
Hi everyone:
I've found a partial solution to making a window snap to some location.
The code below inserted into an NSWindow subclass will cause the window
to snap to the corner of the screen without "bouncing" like applications
such as Fire do. One important thing to note: the standard
event-handling methods (mouseDown:, mouseDragged:, etc.) do not work in
NSWindow like they do in NSView. For one thing, the actual moving of a
window when the user clicks on the titlebar is handled internally...NOT
though events sent to the NSWindow class. NSWindow never receives a
mouseDown: message or mouseUp, though it does get mouseDragged:. In any
case, overriding any of these methods, or event the sendEvent: method
will not override the window movement code. To further complicate
matters, the window origin reported during a window movement is not
accurate. You will have to track the motion and calculate the expected
position yourself. (This is what the code below will do.)
Anyway, I'm still looking for an Apple-official way of doing this, if
there is one. For now, this hack ought to make some progress for those
who are interested. Thanks to everyone who made a suggestion.
-Charles
// Place in NSWindow subclass. Requires NSPoint ivars _locInWindow and
_laslLoc ;
#define SNAP_DISTANCE (20.0)
- (void)sendEvent: (NSEvent*)event
{
unsigned eventType = [event type] ;
switch(eventType) {
case NSLeftMouseDown:
// record the location in the window for the down event and the
mouse location. These will be used later to calculate the offset.
_locInWindow = [event locationInWindow] ;
_lastLoc = [NSEvent mouseLocation] ;
break ;
default:
break ;
}
[super sendEvent: event] ;
}
- (void)mouseDragged: (NSEvent*)event
{
NSPoint delta ;
NSRect rect = [self frame] ; // NOTE: The origin here is probably
not correct!
NSRect sr = [[self screen] visibleFrame] ;
BOOL snap = NO ;
// everything here is calculated based on the mouse location since
the window location is not reliable!
rect.origin = [NSEvent mouseLocation] ;
// find the delta that will be applied to the window
delta.x = rect.origin.x - _lastLoc.x ;
delta.y = rect.origin.y - _lastLoc.y ;
_lastLoc = rect.origin ;
// find the new window position (note the _locInWindow was recorded
BEFORE the window ever moved. The mouse should always be at the same
location in the window relative to its current position since the window
itself is moving.)
rect.origin.x -= _locInWindow.x ;
rect.origin.y -= _locInWindow.y ;
// snap if needed
// perform snap
if (abs((NSMinX(rect) - NSMinX(sr)) < SNAP_DISTANCE)) {
rect.origin.x = sr.origin.x ;
snap = YES ;
}
// snap to bottom edge
if (abs((NSMinY(rect) - NSMinY(sr)) < SNAP_DISTANCE)) {
rect.origin.y = sr.origin.y ;
snap = YES ;
}
// snap to top edge
if (abs((NSMaxY(sr) - NSMaxY(rect)) < SNAP_DISTANCE)) {
rect.origin.y = NSMaxY(sr) - rect.size.height ;
snap = YES ;
}
// snap to right edge
if (abs(NSMaxX(sr) - NSMaxX(rect)) < SNAP_DISTANCE) {
rect.origin.x = NSMaxX(sr) - rect.size.width ;
snap = YES ;
}
if (snap) [self setFrameOrigin: rect.origin] ;
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.