From 568228dec319664b2c284a4566db0b14dcae2754 Mon Sep 17 00:00:00 2001 From: Richard Hult Date: Wed, 31 Oct 2007 11:01:56 +0000 Subject: [PATCH] Implement manual resize and move. 2007-10-31 Richard Hult * gdk/quartz/GdkQuartzWindow.c: * gdk/quartz/GdkQuartzWindow.h: * gdk/quartz/gdkwindow-quartz.c: (gdk_window_begin_resize_drag), (gdk_window_begin_move_drag): Implement manual resize and move. svn path=/trunk/; revision=18955 --- ChangeLog | 7 +++ gdk/quartz/GdkQuartzWindow.c | 99 +++++++++++++++++++++++++++++++++++ gdk/quartz/GdkQuartzWindow.h | 11 ++++ gdk/quartz/gdkwindow-quartz.c | 40 +++++++++++++- 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b1457700d..7138daa0c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-10-31 Richard Hult + + * gdk/quartz/GdkQuartzWindow.c: + * gdk/quartz/GdkQuartzWindow.h: + * gdk/quartz/gdkwindow-quartz.c: (gdk_window_begin_resize_drag), + (gdk_window_begin_move_drag): Implement manual resize and move. + 2007-10-31 Richard Hult * gdk/quartz/gdkwindow-quartz.c: diff --git a/gdk/quartz/GdkQuartzWindow.c b/gdk/quartz/GdkQuartzWindow.c index 4d0ccd12e0..ee32e3aa58 100644 --- a/gdk/quartz/GdkQuartzWindow.c +++ b/gdk/quartz/GdkQuartzWindow.c @@ -113,6 +113,13 @@ case NSLeftMouseUp: leftDown = NO; inMove = NO; + inManualMove = NO; + inManualResize = NO; + break; + + case NSLeftMouseDragged: + if ([self trackManualMove] || [self trackManualResize]) + return; break; default: @@ -256,6 +263,98 @@ return YES; } +- (BOOL)trackManualMove +{ + NSPoint currentLocation; + NSPoint newOrigin; + NSRect screenFrame = [[NSScreen mainScreen] visibleFrame]; + NSRect windowFrame = [self frame]; + + if (!inManualMove) + return NO; + + currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + newOrigin.x = currentLocation.x - initialMoveLocation.x; + newOrigin.y = currentLocation.y - initialMoveLocation.y; + + /* Clamp vertical position to below the menu bar. */ + if (newOrigin.y + windowFrame.size.height > screenFrame.origin.y + screenFrame.size.height) + newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height; + + [self setFrameOrigin:newOrigin]; + + return YES; +} + +-(void)beginManualMove +{ + NSRect frame = [self frame]; + + if (inMove || inManualMove || inManualResize) + return; + + inManualMove = YES; + + initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + initialMoveLocation.x -= frame.origin.x; + initialMoveLocation.y -= frame.origin.y; +} + +- (BOOL)trackManualResize +{ + NSPoint currentLocation; + NSRect newFrame; + float dx, dy; + NSSize min_size; + + if (!inManualResize) + return NO; + + currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + currentLocation.x -= initialResizeFrame.origin.x; + currentLocation.y -= initialResizeFrame.origin.y; + + dx = currentLocation.x - initialResizeLocation.x; + dy = -(currentLocation.y - initialResizeLocation.y); + + newFrame = initialResizeFrame; + newFrame.size.width = initialResizeFrame.size.width + dx; + newFrame.size.height = initialResizeFrame.size.height + dy; + + min_size = [self contentMinSize]; + if (newFrame.size.width < min_size.width) + newFrame.size.width = min_size.width; + if (newFrame.size.height < min_size.height) + newFrame.size.height = min_size.height; + + /* We could also apply aspect ratio: + newFrame.size.height = newFrame.size.width / [self aspectRatio].width * [self aspectRatio].height; + */ + + dy = newFrame.size.height - initialResizeFrame.size.height; + + newFrame.origin.x = initialResizeFrame.origin.x; + newFrame.origin.y = initialResizeFrame.origin.y - dy; + + [self setFrame:newFrame display:YES]; + + return YES; +} + +-(void)beginManualResize +{ + if (inMove || inManualMove || inManualResize) + return; + + inManualResize = YES; + + initialResizeFrame = [self frame]; + initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + initialResizeLocation.x -= initialResizeFrame.origin.x; + initialResizeLocation.y -= initialResizeFrame.origin.y; +} + + static GdkDragContext *current_context = NULL; static GdkDragAction diff --git a/gdk/quartz/GdkQuartzWindow.h b/gdk/quartz/GdkQuartzWindow.h index 4c2276d3c6..88dad48486 100644 --- a/gdk/quartz/GdkQuartzWindow.h +++ b/gdk/quartz/GdkQuartzWindow.h @@ -24,9 +24,20 @@ @interface GdkQuartzWindow : NSWindow { BOOL leftDown; BOOL inMove; + + /* Manually triggered move/resize (not by the window manager) */ + BOOL inManualMove; + BOOL inManualResize; + NSPoint initialMoveLocation; + NSPoint initialResizeLocation; + NSRect initialResizeFrame; } -(BOOL)isInMove; +-(void)beginManualMove; +-(BOOL)trackManualMove; +-(void)beginManualResize; +-(BOOL)trackManualResize; @end diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index 357b8a75ed..a60e4c8d22 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -2356,9 +2356,30 @@ gdk_window_begin_resize_drag (GdkWindow *window, gint root_y, guint32 timestamp) { + GdkWindowObject *private; + GdkWindowImplQuartz *impl; + g_return_if_fail (GDK_IS_WINDOW (window)); - /* FIXME: Implement */ + if (edge != GDK_WINDOW_EDGE_SOUTH_EAST) + { + g_warning ("Resizing is only implemented for GDK_WINDOW_EDGE_SOUTH_EAST on Mac OS"); + return; + } + + if (GDK_WINDOW_DESTROYED (window)) + return; + + private = GDK_WINDOW_OBJECT (window); + impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + if (!impl->toplevel) + { + g_warning ("Can't call gdk_window_begin_resize_drag on non-toplevel window"); + return; + } + + [(GdkQuartzWindow *)impl->toplevel beginManualResize]; } void @@ -2368,9 +2389,24 @@ gdk_window_begin_move_drag (GdkWindow *window, gint root_y, guint32 timestamp) { + GdkWindowObject *private; + GdkWindowImplQuartz *impl; + g_return_if_fail (GDK_IS_WINDOW (window)); - /* FIXME: Implement */ + if (GDK_WINDOW_DESTROYED (window)) + return; + + private = GDK_WINDOW_OBJECT (window); + impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + if (!impl->toplevel) + { + g_warning ("Can't call gdk_window_begin_move_drag on non-toplevel window"); + return; + } + + [(GdkQuartzWindow *)impl->toplevel beginManualMove]; } void