X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/080c7d56e0ab91ba778c1687eee353ea7cef4485..35c63208f04930176aa34ec1fcabc4f3c19804b9:/src/cocoa/toplevel.mm diff --git a/src/cocoa/toplevel.mm b/src/cocoa/toplevel.mm index c51f22719a..f2e44d4b44 100644 --- a/src/cocoa/toplevel.mm +++ b/src/cocoa/toplevel.mm @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: cocoa/toplevel.mm +// Name: src/cocoa/toplevel.mm // Purpose: implements wxTopLevelWindow for Cocoa -// Author: David Elliott +// 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 /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -19,9 +19,11 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" + +#include "wx/toplevel.h" + #ifndef WX_PRECOMP #include "wx/window.h" - #include "wx/toplevel.h" #include "wx/menuitem.h" #include "wx/frame.h" #include "wx/log.h" @@ -30,11 +32,13 @@ #include "wx/cocoa/autorelease.h" #include "wx/cocoa/string.h" -#include "wx/cocoa/mbarman.h" -#import -#import +#include "wx/cocoa/objc/NSView.h" +#include "wx/cocoa/objc/NSWindow.h" #import +#import +#import + // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- @@ -46,6 +50,8 @@ wxWindowList wxModelessWindows; // wxTopLevelWindowCocoa implementation // ============================================================================ +wxTopLevelWindowCocoa *wxTopLevelWindowCocoa::sm_cocoaDeactivateWindow = NULL; + // ---------------------------------------------------------------------------- // wxTopLevelWindowCocoa creation // ---------------------------------------------------------------------------- @@ -92,7 +98,7 @@ bool wxTopLevelWindowCocoa::Create(wxWindow *parent, wxTopLevelWindows.Append(this); if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name)) - return FALSE; + return false; if ( parent ) parent->AddChild(this); @@ -101,15 +107,45 @@ bool wxTopLevelWindowCocoa::Create(wxWindow *parent, 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); + // NOTE: y-origin needs to be flipped. - NSRect cocoaRect = [NSWindow contentRectForFrameRect:NSMakeRect(pos.x,pos.y,size.x,size.y) styleMask:cocoaStyle]; + NSRect cocoaRect = [NSWindow + contentRectForFrameRect:NSMakeRect(realx,realy,realw,realh) + styleMask:cocoaStyle]; m_cocoaNSWindow = NULL; m_cocoaNSView = NULL; + // NOTE: We may need to deal with the contentView becoming a wx NSView as well. + NSWindow *newWindow; + // Create a WXNSPanel or a WXNSWindow depending on what type of window is desired. if(style & wxFRAME_TOOL_WINDOW) - SetNSWindow([[NSPanel alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]); + newWindow = [[WXNSPanel alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]; else - SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]); + newWindow = [[WXNSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]; + // Make sure the default content view is a WXNSView + [newWindow setContentView: [[WX_GET_OBJC_CLASS(WXNSView) alloc] initWithFrame: [[newWindow contentView] frame]]]; + // Associate the window and view + SetNSWindow(newWindow); + // 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. @@ -120,34 +156,57 @@ bool wxTopLevelWindowCocoa::Create(wxWindow *parent, if(style & wxSTAY_ON_TOP) [m_cocoaNSWindow setLevel:NSFloatingWindowLevel]; [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)]; - return TRUE; + 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(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; + // NOTE: We are no longer using posing so we won't get events on the + // window's view unless it was explicitly created as the wx view class. if(m_cocoaNSWindow) SetNSView([m_cocoaNSWindow contentView]); else SetNSView(NULL); AssociateNSWindow(m_cocoaNSWindow); - if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]); + 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) @@ -156,44 +215,44 @@ void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newVie [m_cocoaNSWindow setContentView:newView]; } +/*static*/ void wxTopLevelWindowCocoa::DeactivatePendingWindow() +{ + if(sm_cocoaDeactivateWindow) + sm_cocoaDeactivateWindow->wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(); + sm_cocoaDeactivateWindow = NULL; +} + void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void) { - wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey",this); - wxMenuBarManager::GetInstance()->WindowDidBecomeKey(this); - wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId()); + 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) { - wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey",this); - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId()); + wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey"),this); + wxActivateEvent event(wxEVT_ACTIVATE, false, GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); - wxMenuBarManager::GetInstance()->WindowDidResignKey(this); } void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void) { - wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this); - wxMenuBarManager::GetInstance()->WindowDidBecomeMain(this); + wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain"),this); } void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void) { - wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this); - wxMenuBarManager::GetInstance()->WindowDidResignMain(this); + 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::CocoaDelegate_windowShouldClose() @@ -201,6 +260,15 @@ 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 // ---------------------------------------------------------------------------- @@ -211,7 +279,7 @@ void wxTopLevelWindowCocoa::Maximize(bool maximize) bool wxTopLevelWindowCocoa::IsMaximized() const { - return false ; + return false ; } void wxTopLevelWindowCocoa::Iconize(bool iconize) @@ -220,7 +288,7 @@ void wxTopLevelWindowCocoa::Iconize(bool iconize) bool wxTopLevelWindowCocoa::IsIconized() const { - return FALSE; + return false; } void wxTopLevelWindowCocoa::Restore() @@ -234,7 +302,7 @@ bool wxTopLevelWindowCocoa::Show(bool show) wxAutoNSAutoreleasePool pool; if(show) { - // Send the window a size event because wxWindows apps expect it + // 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()); @@ -257,8 +325,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; } @@ -277,14 +345,46 @@ void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event) // wxTopLevelWindowCocoa misc // ---------------------------------------------------------------------------- +void wxTopLevelWindowCocoa::SetTitle(const wxString& title) +{ + [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)]; +} + +wxString wxTopLevelWindowCocoa::GetTitle() const +{ + return wxStringWithNSString([m_cocoaNSWindow title]); +} + +wxWindow* wxTopLevelWindowCocoa::SetDefaultItem(wxWindow *win) +{ + wxWindow *old = wxTopLevelWindowBase::SetDefaultItem(win); + NSView *newView = win->GetNSView(); + + NSCell *newCell; + // newView does not have to be an NSControl, we only cast to NSControl* + // to silence the warning about cell not being implemented. + if(newView != nil && [newView respondsToSelector:@selector(cell)]) + newCell = [(NSControl*)newView cell]; + else + newCell = nil; + + if(newCell != nil && ![newCell isKindOfClass:[NSButtonCell class]]) + { // It's not an NSButtonCell, set the default to nil. + newCell = nil; + } + + [GetNSWindow() setDefaultButtonCell:(NSButtonCell*)newCell]; + return old; +} + bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style) { - return FALSE; + return false; } bool wxTopLevelWindowCocoa::IsFullScreen() const { - return FALSE; + return false; } void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height) @@ -305,7 +405,7 @@ void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height) 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]; @@ -318,7 +418,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 @@ -328,6 +428,5 @@ 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); } -