[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23633] trunk/blender: Cocoa port :

Damien Plisson damien.plisson at yahoo.fr
Mon Oct 5 14:55:59 CEST 2009


Revision: 23633
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23633
Author:   damien78
Date:     2009-10-05 14:55:16 +0200 (Mon, 05 Oct 2009)

Log Message:
-----------
Cocoa port :
- Window creation at preferred size
  Implement in Ghost the use of Cocoa functions to get the maximum visible rect (size and position) for the window contents (all screen excluding dock, top menu, and window title bar)
  Thus Apple specific code in window creation (wm_window.c & wm_apple.c) is no more needed => removed in case of Cocoa build

- Alert on exiting despite unsaved changes
  Add to GHOST method to maintain an all platforms (not apple specific anymore) status on unsaved changes
  Update GHOST_SystemCocoa to use this for asking or not user to confirm exit without saving changes

Modified Paths:
--------------
    trunk/blender/intern/ghost/GHOST_C-api.h
    trunk/blender/intern/ghost/GHOST_IWindow.h
    trunk/blender/intern/ghost/GHOST_Types.h
    trunk/blender/intern/ghost/intern/GHOST_C-api.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.h
    trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
    trunk/blender/intern/ghost/intern/GHOST_Window.cpp
    trunk/blender/intern/ghost/intern/GHOST_Window.h
    trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h
    trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm
    trunk/blender/intern/ghost/intern/GHOST_WindowManager.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowManager.h
    trunk/blender/source/blender/windowmanager/CMakeLists.txt
    trunk/blender/source/blender/windowmanager/intern/wm_window.c

Modified: trunk/blender/intern/ghost/GHOST_C-api.h
===================================================================
--- trunk/blender/intern/ghost/GHOST_C-api.h	2009-10-05 11:13:15 UTC (rev 23632)
+++ trunk/blender/intern/ghost/GHOST_C-api.h	2009-10-05 12:55:16 UTC (rev 23633)
@@ -598,7 +598,17 @@
 extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
 										   GHOST_TWindowState state);
 
+	
 /**
+ * Sets the window "modified" status, indicating unsaved changes
+ * @param windowhandle The handle to the window
+ * @param isUnsavedChanges Unsaved changes or not
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle,
+												   GHOST_TUns8 isUnsavedChanges);
+	
+/**
  * Sets the order of the window (bottom, top).
  * @param windowhandle The handle to the window
  * @param order The order of the window.

Modified: trunk/blender/intern/ghost/GHOST_IWindow.h
===================================================================
--- trunk/blender/intern/ghost/GHOST_IWindow.h	2009-10-05 11:13:15 UTC (rev 23632)
+++ trunk/blender/intern/ghost/GHOST_IWindow.h	2009-10-05 12:55:16 UTC (rev 23633)
@@ -162,6 +162,19 @@
 	virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0;
 
 	/**
+	 * Sets the window "modified" status, indicating unsaved changes
+	 * @param isUnsavedChanges Unsaved changes or not
+	 * @return Indication of success.
+	 */
+	virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0;
+	
+	/**
+	 * Gets the window "modified" status, indicating unsaved changes
+	 * @return True if there are unsaved changes
+	 */
+	virtual bool getModifiedState() = 0;
+	
+	/**
 	 * Sets the order of the window (bottom, top).
 	 * @param order The order of the window.
 	 * @return Indication of success.

Modified: trunk/blender/intern/ghost/GHOST_Types.h
===================================================================
--- trunk/blender/intern/ghost/GHOST_Types.h	2009-10-05 11:13:15 UTC (rev 23632)
+++ trunk/blender/intern/ghost/GHOST_Types.h	2009-10-05 12:55:16 UTC (rev 23633)
@@ -116,7 +116,13 @@
 } GHOST_TWindowState;
 
 
+/** Constants for the answer to the blender exit request */
 typedef enum {
+	GHOST_kExitCancel = 0,
+	GHOST_kExitNow
+} GHOST_TExitRequestResponse;
+
+typedef enum {
 	GHOST_kWindowOrderTop = 0,
 	GHOST_kWindowOrderBottom
 } GHOST_TWindowOrder;

Modified: trunk/blender/intern/ghost/intern/GHOST_C-api.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_C-api.cpp	2009-10-05 11:13:15 UTC (rev 23632)
+++ trunk/blender/intern/ghost/intern/GHOST_C-api.cpp	2009-10-05 12:55:16 UTC (rev 23633)
@@ -629,7 +629,14 @@
 }
 
 
+GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, GHOST_TUns8 isUnsavedChanges)
+{
+	GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+	
+	return window->setModifiedState(isUnsavedChanges);
+}	
 
+
 GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,
 									GHOST_TWindowOrder order)
 {

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.h	2009-10-05 11:13:15 UTC (rev 23632)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.h	2009-10-05 12:55:16 UTC (rev 23633)
@@ -133,6 +133,12 @@
 	 */
 	virtual bool processEvents(bool waitForEvent);
 	
+	/**
+	 * Handle User request to quit, from Menu bar Quit, and Cmd+Q
+	 * Display alert panel if changes performed since last save
+	 */
+	GHOST_TUns8 handleQuitRequest();
+	
 	/***************************************************************************************
 	 ** Cursor management functionality
 	 ***************************************************************************************/
@@ -193,39 +199,33 @@
 	 */
 	virtual GHOST_TSuccess init();
 
-	/**
-	 * Closes the system down.
-	 * @return A success value.
-	 */
-	virtual GHOST_TSuccess exit();
-
-	
     /**
      * Handles a tablet event.
      * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
      * @return Indication whether the event was handled. 
      */
-    int handleTabletEvent(void *eventPtr);
-    /**
+    GHOST_TSuccess handleTabletEvent(void *eventPtr);
+    
+	/**
      * Handles a mouse event.
      * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
      * @return Indication whether the event was handled. 
      */
-    int handleMouseEvent(void *eventPtr);
+    GHOST_TSuccess handleMouseEvent(void *eventPtr);
 
     /**
      * Handles a key event.
      * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
      * @return Indication whether the event was handled. 
      */
-    int handleKeyEvent(void *eventPtr);
+    GHOST_TSuccess handleKeyEvent(void *eventPtr);
 
    /**
      * Handles a window event.
      * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
      * @return Indication whether the event was handled. 
      */
-    int handleWindowEvent(void *eventPtr);
+    GHOST_TSuccess handleWindowEvent(void *eventPtr);
 
     /**
      * Handles all basic Mac application stuff for a mouse down event.

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2009-10-05 11:13:15 UTC (rev 23632)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2009-10-05 12:55:16 UTC (rev 23633)
@@ -414,6 +414,7 @@
 }
 -(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+- (void)applicationWillTerminate:(NSNotification *)aNotification;
 @end
 
 @implementation CocoaAppDelegate : NSObject
@@ -424,23 +425,28 @@
 
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
 {
+	//TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled
 	//Note that Cmd+Q is already handled by keyhandler
-    //FIXME: Need an event "QuitRequest"
-	int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes may not have been saved. Do you really want to quit ?",
-									 @"No", @"Yes", nil);
-	
-	if (shouldQuit == NSAlertAlternateReturn)
-		systemCocoa->pushEvent( new GHOST_Event(systemCocoa->getMilliSeconds(), GHOST_kEventQuit, NULL) );
-    
-	return NSTerminateCancel;
+    if (systemCocoa->handleQuitRequest() == GHOST_kExitNow)
+		return NSTerminateCancel;//NSTerminateNow;
+	else
+		return NSTerminateCancel;
 }
+
+// To avoid cancelling a log off process, we must use Cocoa termination process
+// And this function is the only chance to perform clean up
+// So WM_exit needs to be called directly, as the event loop will never run before termination
+- (void)applicationWillTerminate:(NSNotification *)aNotification
+{
+	/*G.afbreek = 0; //Let Cocoa perform the termination at the end
+	WM_exit(C);*/
+}
 @end
 
 
 
 #pragma mark initialization/finalization
 
-/***/
 
 GHOST_SystemCocoa::GHOST_SystemCocoa()
 {
@@ -468,6 +474,8 @@
 
 GHOST_SystemCocoa::~GHOST_SystemCocoa()
 {
+	NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool;
+	[pool drain];
 }
 
 
@@ -478,7 +486,7 @@
     if (success) {
 		//ProcessSerialNumber psn;
 		
-		//FIXME: Carbon stuff to move window & menu to foreground
+		//Carbon stuff to move window & menu to foreground
 		/*if (!GetCurrentProcess(&psn)) {
 			TransformProcessType(&psn, kProcessTransformToForegroundApplication);
 			SetFrontProcess(&psn);
@@ -566,13 +574,6 @@
 }
 
 
-GHOST_TSuccess GHOST_SystemCocoa::exit()
-{
-	NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool;
-	[pool drain];
-    return GHOST_System::exit();
-}
-
 #pragma mark window management
 
 GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
@@ -602,11 +603,15 @@
 
 void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
 {
-	//TODO: Provide visible frame or total frame, check for consistency with rest of code
+	//Get visible frame, that is frame excluding dock and top menu bar
 	NSRect frame = [[NSScreen mainScreen] visibleFrame];
 	
-	width = frame.size.width;
-	height = frame.size.height;
+	//Returns max window contents (excluding title bar...)
+	NSRect contentRect = [NSWindow contentRectForFrameRect:frame
+												 styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
+	
+	width = contentRect.size.width;
+	height = contentRect.size.height;
 }
 
 
@@ -623,7 +628,16 @@
 )
 {
     GHOST_IWindow* window = 0;
-
+	
+	//Get the available rect for including window contents
+	NSRect frame = [[NSScreen mainScreen] visibleFrame];
+	NSRect contentRect = [NSWindow contentRectForFrameRect:frame
+												 styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
+	
+	//Ensures window top left is inside this available rect
+	left = left > contentRect.origin.x ? left : contentRect.origin.x;
+	top = top > contentRect.origin.y ? top : contentRect.origin.y;
+	
 	window = new GHOST_WindowCocoa (title, left, top, width, height, state, type);
 
     if (window) {
@@ -847,7 +861,7 @@
 }
 
 //TODO: To be called from NSWindow delegate
-int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
+GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
 {
 	/*WindowRef windowRef;
 	GHOST_WindowCocoa *window;
@@ -900,8 +914,30 @@
 	return GHOST_kSuccess;
 }
 
-int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
+GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
 {
+	//Check open windows if some changes are not saved
+	if (m_windowManager->getAnyModifiedState())
+	{
+		int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?",
+										 @"Cancel", @"Quit anyway", nil);
+		if (shouldQuit == NSAlertAlternateReturn)
+		{
+			pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
+			return GHOST_kExitNow;
+		}
+	}
+	else {
+		pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
+		return GHOST_kExitNow;
+	}
+	
+	return GHOST_kExitCancel;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
+{
 	NSEvent *event = (NSEvent *)eventPtr;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list