X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fb896a322a2ed53d393ee738765ddd3f72cee004..9c112555198f51fcec71106530cddba95a17f3dc:/src/cocoa/toplevel.mm diff --git a/src/cocoa/toplevel.mm b/src/cocoa/toplevel.mm index 93fb983c77..4778cc3668 100644 --- a/src/cocoa/toplevel.mm +++ b/src/cocoa/toplevel.mm @@ -4,9 +4,9 @@ // Author: David Elliott // Modified by: // Created: 2002/11/27 -// RCS-ID: $Id: +// RCS-ID: $Id$ // Copyright: (c) 2002 David Elliott -// License: wxWindows license +// Licence: wxWidgets licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -28,7 +28,12 @@ #include "wx/app.h" #endif //WX_PRECOMP +#include "wx/cocoa/autorelease.h" +#include "wx/cocoa/string.h" + +#import #import +#import // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- @@ -40,10 +45,11 @@ wxWindowList wxModelessWindows; // wxTopLevelWindowCocoa implementation // ============================================================================ +wxTopLevelWindowCocoa *wxTopLevelWindowCocoa::sm_cocoaDeactivateWindow = NULL; + // ---------------------------------------------------------------------------- // wxTopLevelWindowCocoa creation // ---------------------------------------------------------------------------- -IMPLEMENT_CLASS(wxTopLevelWindowCocoa,wxWindowCocoa) BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase) EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow) END_EVENT_TABLE() @@ -55,6 +61,26 @@ void wxTopLevelWindowCocoa::Init() m_closed = false; } +unsigned int wxTopLevelWindowCocoa::NSWindowStyleForWxStyle(long style) +{ + unsigned int styleMask = 0; + if(style & wxCAPTION) + styleMask |= NSTitledWindowMask; + if(style & wxMINIMIZE_BOX) + styleMask |= NSMiniaturizableWindowMask; + #if 0 + if(style & wxMAXIMIZE_BOX) + styleMask |= NSWindowMask; + #endif + if(style & wxCLOSE_BOX) + styleMask |= NSClosableWindowMask; + if(style & wxRESIZE_BORDER) + styleMask |= NSResizableWindowMask; + if(style & wxSIMPLE_BORDER) + styleMask |= NSBorderlessWindowMask; + return styleMask; +} + bool wxTopLevelWindowCocoa::Create(wxWindow *parent, wxWindowID winid, const wxString& title, @@ -63,6 +89,7 @@ bool wxTopLevelWindowCocoa::Create(wxWindow *parent, long style, const wxString& name) { + wxAutoNSAutoreleasePool pool; wxTopLevelWindows.Append(this); if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name)) @@ -71,42 +98,91 @@ bool wxTopLevelWindowCocoa::Create(wxWindow *parent, if ( parent ) parent->AddChild(this); - // TODO: get rect from given position/size - NSRect cocoaRect = NSMakeRect(100,100,200,200); + unsigned int cocoaStyle = NSWindowStyleForWxStyle(style); + if(style & wxFRAME_TOOL_WINDOW) + cocoaStyle |= NSUtilityWindowMask; + + // Create frame and check and handle default position and size + int realx, + realy; + + // WX has no set default position - the carbon port caps the low + // end at 20, 50. Here we do the same, except instead of setting + // it to 20 and 50, we set it to 100 and 100 if the values are too low + if (pos.x < 20) + realx = 100; + else + realx = pos.x; + + if (pos.y < 50) + realy = 100; + else + realy = pos.y; + + int realw = WidthDefault(size.x); + int realh = HeightDefault(size.y); - // TODO: Set flags given wxWindows style - unsigned int cocoaStyle = 0; - cocoaStyle |= NSTitledWindowMask; - cocoaStyle |= NSClosableWindowMask; - cocoaStyle |= NSMiniaturizableWindowMask; - cocoaStyle |= NSResizableWindowMask; + // NOTE: y-origin needs to be flipped. + NSRect cocoaRect = [NSWindow + contentRectForFrameRect:NSMakeRect(realx,realy,realw,realh) + styleMask:cocoaStyle]; m_cocoaNSWindow = NULL; m_cocoaNSView = NULL; - SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]); + if(style & wxFRAME_TOOL_WINDOW) + SetNSWindow([[NSPanel alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]); + else + SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]); // NOTE: SetNSWindow has retained the Cocoa object for this object. // Because we do not release on close, the following release matches the // above alloc and thus the retain count will be 1. [m_cocoaNSWindow release]; + if(style & wxFRAME_NO_TASKBAR) + [m_cocoaNSWindow setExcludedFromWindowsMenu: YES]; + if(style & wxSTAY_ON_TOP) + [m_cocoaNSWindow setLevel:NSFloatingWindowLevel]; + [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)]; return TRUE; } wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa() { + wxASSERT(sm_cocoaDeactivateWindow!=this); + wxAutoNSAutoreleasePool pool; + DestroyChildren(); + if(m_cocoaNSView) + SendDestroyEvent(); SetNSWindow(NULL); } +bool wxTopLevelWindowCocoa::Destroy() +{ + if(sm_cocoaDeactivateWindow==this) + { + sm_cocoaDeactivateWindow = NULL; + wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(); + } + return wxTopLevelWindowBase::Destroy(); +} + // ---------------------------------------------------------------------------- // wxTopLevelWindowCocoa Cocoa Specifics // ---------------------------------------------------------------------------- +wxMenuBar* wxTopLevelWindowCocoa::GetAppMenuBar(wxCocoaNSWindow *win) +{ + wxTopLevelWindowCocoa *parent = wxDynamicCast(GetParent(),wxTopLevelWindow); + if(parent) + return parent->GetAppMenuBar(win); + return NULL; +} + void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow) { bool need_debug = cocoaNSWindow || m_cocoaNSWindow; - if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d",this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]); - if(m_cocoaNSWindow) - DisassociateNSWindow(m_cocoaNSWindow); + if(need_debug) wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d"),this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]); + DisassociateNSWindow(m_cocoaNSWindow); [cocoaNSWindow retain]; [m_cocoaNSWindow release]; m_cocoaNSWindow = cocoaNSWindow; @@ -114,30 +190,70 @@ void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow) SetNSView([m_cocoaNSWindow contentView]); else SetNSView(NULL); - if(m_cocoaNSWindow) - AssociateNSWindow(m_cocoaNSWindow); - if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]); + AssociateNSWindow(m_cocoaNSWindow); + if(need_debug) wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d"),this,cocoaNSWindow,[cocoaNSWindow retainCount]); +} + +void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView) +{ + if([m_cocoaNSWindow contentView] == (id)oldView) + [m_cocoaNSWindow setContentView:newView]; +} + +/*static*/ void wxTopLevelWindowCocoa::DeactivatePendingWindow() +{ + if(sm_cocoaDeactivateWindow) + sm_cocoaDeactivateWindow->wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(); + sm_cocoaDeactivateWindow = NULL; +} + +void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void) +{ + DeactivatePendingWindow(); + wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey"),this); + wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); +} + +void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void) +{ + wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey"),this); + wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); +} + +void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void) +{ + wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain"),this); } -void wxTopLevelWindowCocoa::Cocoa_wxMenuItemAction(wxMenuItem& item) +void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void) { + wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain"),this); } -void wxTopLevelWindowCocoa::Cocoa_close(void) +void wxTopLevelWindowCocoa::CocoaDelegate_windowWillClose(void) { m_closed = true; Destroy(); - /* Be SURE that idle events get ran. If the window was not active when - it was closed, then there will be no more events to trigger this and - therefore it must be done here */ - wxTheApp->CocoaInstallRequestedIdleHandler(); } -bool wxTopLevelWindowCocoa::Cocoa_windowShouldClose() +bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose() { return wxWindowBase::Close(false); } +void wxTopLevelWindowCocoa::CocoaDelegate_wxMenuItemAction(WX_NSMenuItem menuItem) +{ +} + +bool wxTopLevelWindowCocoa::CocoaDelegate_validateMenuItem(WX_NSMenuItem menuItem) +{ + return false; +} + // ---------------------------------------------------------------------------- // wxTopLevelWindowCocoa maximize/minimize // ---------------------------------------------------------------------------- @@ -166,10 +282,23 @@ void wxTopLevelWindowCocoa::Restore() bool wxTopLevelWindowCocoa::Show(bool show) { + if(m_isShown == show) + return false; + wxAutoNSAutoreleasePool pool; if(show) + { + // Send the window a size event because wxWidgets apps expect it + // NOTE: This should really only be done the first time a window + // is shown. I doubt this will cause any problems though. + wxSizeEvent event(GetSize(), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); + [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow]; + } else [m_cocoaNSWindow orderOut:m_cocoaNSWindow]; + m_isShown = show; return true; } @@ -181,8 +310,8 @@ bool wxTopLevelWindowCocoa::Close(bool force) // will invoke windowShouldClose which will call the base class version // of Close() which will NOT Destroy() the window (see below) but // if closing is not stopped, then performClose will go ahead and - // close the window which will invoke Cocoa_close() setting m_closed - // to true and Destroy()ing the window. + // close the window which will send the close notifications setting + // m_closed to true and Destroy()ing the window. [m_cocoaNSWindow performClose:m_cocoaNSWindow]; return m_closed; } @@ -211,9 +340,25 @@ bool wxTopLevelWindowCocoa::IsFullScreen() const return FALSE; } +void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height) +{ + // Set the NSView size by setting the frame size to enclose it + unsigned int styleMask = [m_cocoaNSWindow styleMask]; + NSRect frameRect = [m_cocoaNSWindow frame]; + NSRect contentRect = [NSWindow + contentRectForFrameRect: frameRect + styleMask: styleMask]; + contentRect.size.width = width; + contentRect.size.height = height; + frameRect = [NSWindow + frameRectForContentRect: contentRect + styleMask: styleMask]; + [m_cocoaNSWindow setFrame: frameRect display: NO]; +} + void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height) { - wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height); + wxLogTrace(wxTRACE_COCOA_TopLevelWindow_Size,wxT("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)"),this,x,y,width,height); NSRect cocoaRect = NSMakeRect(x,y,width,height); [m_cocoaNSWindow setFrame: cocoaRect display:NO]; @@ -226,7 +371,7 @@ void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const *w=(int)cocoaRect.size.width; if(h) *h=(int)cocoaRect.size.height; - wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height); + wxLogTrace(wxTRACE_COCOA_TopLevelWindow_Size,wxT("wxTopLevelWindow=%p::DoGetSize = (%d,%d)"),this,(int)cocoaRect.size.width,(int)cocoaRect.size.height); } void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const @@ -236,6 +381,6 @@ void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const *x=(int)cocoaRect.origin.x; if(y) *y=(int)cocoaRect.origin.y; - wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y); + wxLogTrace(wxTRACE_COCOA_TopLevelWindow_Size,wxT("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)"),this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y); }