X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d2518be484155be41dae1babc60bae4978168a3c..a766986f6d443ba1d50e3af25f3306fa56e4518e:/src/cocoa/toplevel.mm diff --git a/src/cocoa/toplevel.mm b/src/cocoa/toplevel.mm index 4778cc3668..b4b55f1b53 100644 --- a/src/cocoa/toplevel.mm +++ b/src/cocoa/toplevel.mm @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////// -// 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$ @@ -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,10 +32,14 @@ #include "wx/cocoa/autorelease.h" #include "wx/cocoa/string.h" +#include "wx/cocoa/ObjcRef.h" -#import -#import +#include "wx/cocoa/objc/NSView.h" +#include "wx/cocoa/objc/NSWindow.h" #import +#import +#import + // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- @@ -81,6 +87,23 @@ unsigned int wxTopLevelWindowCocoa::NSWindowStyleForWxStyle(long style) return styleMask; } +NSRect wxTopLevelWindowCocoa::MakeInitialNSWindowContentRect(const wxPoint& pos, const wxSize& size, unsigned int cocoaStyleMask) +{ + // Arbitrarily use (100,100) as the origin when default coords are given. + wxCoord x = pos.x!=wxDefaultCoord ? pos.x : 100; + wxCoord y = pos.y!=wxDefaultCoord ? pos.y : 100; + + wxCoord w = WidthDefault(size.x); + wxCoord h = HeightDefault(size.y); + + NSPoint cocoaOrigin = OriginInCocoaScreenCoordinatesForRectInWxDisplayCoordinates(x,y,w,h,true); + + return [NSWindow + contentRectForFrameRect:NSMakeRect(cocoaOrigin.x,cocoaOrigin.y,w,h) + styleMask:cocoaStyleMask]; + +} + bool wxTopLevelWindowCocoa::Create(wxWindow *parent, wxWindowID winid, const wxString& title, @@ -93,7 +116,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); @@ -102,37 +125,22 @@ 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(realx,realy,realw,realh) - styleMask:cocoaStyle]; + NSRect cocoaRect = MakeInitialNSWindowContentRect(pos,size,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 = [[WX_GET_OBJC_CLASS(WXNSPanel) alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]; else - SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]); + newWindow = [[WX_GET_OBJC_CLASS(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. @@ -143,7 +151,7 @@ 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() @@ -183,9 +191,11 @@ void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow) bool need_debug = cocoaNSWindow || 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]; + wxGCSafeRetain(cocoaNSWindow); + wxGCSafeRelease(m_cocoaNSWindow); 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 @@ -211,17 +221,17 @@ void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void) { DeactivatePendingWindow(); wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey"),this); - wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId()); + wxActivateEvent event(wxEVT_ACTIVATE, true, GetId()); event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); + HandleWindowEvent(event); } void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void) { wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey"),this); - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId()); + wxActivateEvent event(wxEVT_ACTIVATE, false, GetId()); event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); + HandleWindowEvent(event); } void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void) @@ -264,7 +274,7 @@ void wxTopLevelWindowCocoa::Maximize(bool maximize) bool wxTopLevelWindowCocoa::IsMaximized() const { - return false ; + return false ; } void wxTopLevelWindowCocoa::Iconize(bool iconize) @@ -273,7 +283,7 @@ void wxTopLevelWindowCocoa::Iconize(bool iconize) bool wxTopLevelWindowCocoa::IsIconized() const { - return FALSE; + return false; } void wxTopLevelWindowCocoa::Restore() @@ -292,7 +302,7 @@ bool wxTopLevelWindowCocoa::Show(bool show) // is shown. I doubt this will cause any problems though. wxSizeEvent event(GetSize(), GetId()); event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); + HandleWindowEvent(event); [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow]; } @@ -330,37 +340,82 @@ 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); + + NSCell *newCell; + if(win != NULL) + { + NSView *newView = win->GetNSView(); + // 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; + } + } + else + 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) { // Set the NSView size by setting the frame size to enclose it unsigned int styleMask = [m_cocoaNSWindow styleMask]; - NSRect frameRect = [m_cocoaNSWindow frame]; + NSRect oldFrameRect = [m_cocoaNSWindow frame]; NSRect contentRect = [NSWindow - contentRectForFrameRect: frameRect + contentRectForFrameRect: oldFrameRect styleMask: styleMask]; contentRect.size.width = width; contentRect.size.height = height; - frameRect = [NSWindow + NSRect newFrameRect = [NSWindow frameRectForContentRect: contentRect styleMask: styleMask]; - [m_cocoaNSWindow setFrame: frameRect display: NO]; + + // Cocoa uses +y is up but wxWidgets uses +y is down. We want an increase/decrease in height + // to not effect where the top of the window is placed so we set the new y origin relative the + // old one taking the height change into account. + newFrameRect.origin.y = oldFrameRect.origin.y + oldFrameRect.size.height - newFrameRect.size.height; + + [m_cocoaNSWindow setFrame: newFrameRect display: NO]; } void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int 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); + NSPoint cocoaOrigin = OriginInCocoaScreenCoordinatesForRectInWxDisplayCoordinates(x,y,width,height,false); + + NSRect cocoaRect = NSMakeRect(cocoaOrigin.x,cocoaOrigin.y,width,height); [m_cocoaNSWindow setFrame: cocoaRect display:NO]; } @@ -376,11 +431,14 @@ void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const { - NSRect cocoaRect = [m_cocoaNSWindow frame]; - if(x) - *x=(int)cocoaRect.origin.x; - if(y) - *y=(int)cocoaRect.origin.y; - wxLogTrace(wxTRACE_COCOA_TopLevelWindow_Size,wxT("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)"),this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y); -} + NSRect windowFrame = [m_cocoaNSWindow frame]; + + wxPoint theWxOrigin = OriginInWxDisplayCoordinatesForRectInCocoaScreenCoordinates(windowFrame); + if(*x) + *x = theWxOrigin.x; + if(*y) + *y = theWxOrigin.y; + + wxLogTrace(wxTRACE_COCOA_TopLevelWindow_Size,wxT("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)"),this,(int)theWxOrigin.x,(int)theWxOrigin.y); +}