#include "wx/cocoa/autorelease.h"
#include "wx/cocoa/string.h"
+#include "wx/cocoa/ObjcRef.h"
-#import <AppKit/NSView.h>
-#import <AppKit/NSWindow.h>
+#include "wx/cocoa/objc/NSView.h"
+#include "wx/cocoa/objc/NSWindow.h"
#import <AppKit/NSPanel.h>
+#import <AppKit/NSButtonCell.h>
+#import <AppKit/NSControl.h>
+
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
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,
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.
[m_cocoaNSWindow setExcludedFromWindowsMenu: YES];
if(style & wxSTAY_ON_TOP)
[m_cocoaNSWindow setLevel:NSFloatingWindowLevel];
- SetTitle(title);
+ [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
return true;
}
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
wxLogTrace(wxTRACE_COCOA,wxT("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey"),this);
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());
event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event);
+ HandleWindowEvent(event);
}
void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
// 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];
}
// wxTopLevelWindowCocoa misc
// ----------------------------------------------------------------------------
-void wxTopLevelWindowCocoa::SetTitle( const wxString& WXUNUSED(title))
+void wxTopLevelWindowCocoa::SetTitle(const wxString& title)
{
[m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
}
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;
{
// 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];
}
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);
}