]> git.saurik.com Git - wxWidgets.git/blobdiff - src/cocoa/window.mm
No significant change
[wxWidgets.git] / src / cocoa / window.mm
index dfe05d763d1da2b6016876ed4a80cbbe840fd1c5..3155c35f687f9f0c0470f58a2b5f5f53bb9ed590 100644 (file)
 #include "wx/window.h"
 #include "wx/log.h"
 
+#include "wx/cocoa/autorelease.h"
+
 #import <Appkit/NSView.h>
+#import <AppKit/NSEvent.h>
 
 // normally the base classes aren't included, but wxWindow is special
 #ifdef __WXUNIVERSAL__
@@ -32,6 +35,7 @@ void wxWindowCocoa::Init()
     m_cocoaNSView = NULL;
     m_dummyNSView = NULL;
     m_isBeingDeleted = FALSE;
+    m_isInPaint = FALSE;
 }
 
 // Constructor
@@ -62,6 +66,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID winid,
 // Destructor
 wxWindow::~wxWindow()
 {
+    wxAutoNSAutoreleasePool pool;
     DestroyChildren();
 
     if(m_parent)
@@ -106,16 +111,127 @@ void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView)
 {
     bool need_debug = cocoaNSView || m_cocoaNSView;
     if(need_debug) wxLogDebug("wxWindowCocoa=%p::SetNSView [m_cocoaNSView=%p retainCount]=%d",this,m_cocoaNSView,[m_cocoaNSView retainCount]);
-    if(m_cocoaNSView)
-        DisassociateNSView(m_cocoaNSView);
+    DisassociateNSView(m_cocoaNSView);
     [cocoaNSView retain];
     [m_cocoaNSView release];
     m_cocoaNSView = cocoaNSView;
-    if(m_cocoaNSView)
-        AssociateNSView(m_cocoaNSView);
+    AssociateNSView(m_cocoaNSView);
     if(need_debug) wxLogDebug("wxWindowCocoa=%p::SetNSView [cocoaNSView=%p retainCount]=%d",this,cocoaNSView,[cocoaNSView retainCount]);
 }
 
+bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect)
+{
+    wxLogDebug("Cocoa_drawRect");
+    // Recursion can happen if the event loop runs from within the paint
+    // handler.  For instance, if an assertion dialog is shown.
+    // FIXME: This seems less than ideal.
+    if(m_isInPaint)
+    {
+        wxLogDebug("Paint event recursion!");
+        return false;
+    }
+    //FIXME: should probably turn that rect into the update region
+    m_isInPaint = TRUE;
+    wxPaintEvent event(m_windowId);
+    event.SetEventObject(this);
+    bool ret = GetEventHandler()->ProcessEvent(event);
+    m_isInPaint = FALSE;
+    return ret;
+}
+
+void wxWindowCocoa::InitMouseEvent(wxMouseEvent& event, WX_NSEvent cocoaEvent)
+{
+    NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView;
+    wxASSERT_MSG([nsview window]==[cocoaEvent window],"Mouse event for different NSWindow");
+    NSPoint cocoaPoint = [nsview convertPoint:[(NSEvent*)cocoaEvent locationInWindow] fromView:nil];
+    NSRect cocoaRect = [nsview frame];
+    const wxPoint &clientorigin = GetClientAreaOrigin();
+    event.m_x = (wxCoord)cocoaPoint.x - clientorigin.x;
+    event.m_y = (wxCoord)(cocoaRect.size.height - cocoaPoint.y) - clientorigin.y;
+
+    event.m_shiftDown = [cocoaEvent modifierFlags] & NSShiftKeyMask;
+    event.m_controlDown = [cocoaEvent modifierFlags] & NSControlKeyMask;
+    event.m_altDown = [cocoaEvent modifierFlags] & NSAlternateKeyMask;
+    event.m_metaDown = [cocoaEvent modifierFlags] & NSCommandKeyMask;
+
+    // TODO: set timestamp?
+    event.SetEventObject(this);
+    event.SetId(GetId());
+}
+
+bool wxWindowCocoa::Cocoa_mouseMoved(WX_NSEvent theEvent)
+{
+    wxMouseEvent event(wxEVT_MOTION);
+    InitMouseEvent(event,theEvent);
+    wxLogDebug("Mouse Drag @%d,%d",event.m_x,event.m_y);
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindowCocoa::Cocoa_mouseEntered(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_mouseExited(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_mouseDown(WX_NSEvent theEvent)
+{
+    wxMouseEvent event([theEvent clickCount]<2?wxEVT_LEFT_DOWN:wxEVT_LEFT_DCLICK);
+    InitMouseEvent(event,theEvent);
+    wxLogDebug("Mouse Down @%d,%d num clicks=%d",event.m_x,event.m_y,[theEvent clickCount]);
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindowCocoa::Cocoa_mouseDragged(WX_NSEvent theEvent)
+{
+    wxMouseEvent event(wxEVT_MOTION);
+    InitMouseEvent(event,theEvent);
+    event.m_leftDown = true;
+    wxLogDebug("Mouse Drag @%d,%d",event.m_x,event.m_y);
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindowCocoa::Cocoa_mouseUp(WX_NSEvent theEvent)
+{
+    wxMouseEvent event(wxEVT_LEFT_UP);
+    InitMouseEvent(event,theEvent);
+    wxLogDebug("Mouse Up @%d,%d",event.m_x,event.m_y);
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindowCocoa::Cocoa_rightMouseDown(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_rightMouseDragged(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_rightMouseUp(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_otherMouseDown(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_otherMouseDragged(WX_NSEvent theEvent)
+{
+    return false;
+}
+
+bool wxWindowCocoa::Cocoa_otherMouseUp(WX_NSEvent theEvent)
+{
+    return false;
+}
+
 void wxWindowCocoa::Cocoa_FrameChanged(void)
 {
     wxLogDebug("Cocoa_FrameChanged");
@@ -131,39 +247,48 @@ bool wxWindow::Close(bool force)
 
 bool wxWindow::Show(bool show)
 {
+    wxAutoNSAutoreleasePool pool;
     // If the window is marked as visible, then it shouldn't have a dummy view
     // If the window is marked hidden, then it should have a dummy view
-    wxASSERT_MSG( (m_isShown && !m_dummyNSView) || (!m_isShown && m_dummyNSView),"wxWindow: m_isShown does not agree with m_dummyNSView");
+    // wxSpinCtrl (generic) abuses m_isShown, don't use it for any logic
+//    wxASSERT_MSG( (m_isShown && !m_dummyNSView) || (!m_isShown && m_dummyNSView),"wxWindow: m_isShown does not agree with m_dummyNSView");
     // Return false if there isn't a window to show or hide
     if(!m_cocoaNSView)
         return false;
-    // Return false if the state isn't changing
-    if( show == m_isShown )
-        return false;
     if(show)
     {
+        // If state isn't changing, return false
+        if(!m_dummyNSView)
+            return false;
         // replaceSubView releases m_dummyNSView, balancing the alloc
         [m_cocoaNSView retain];
         [[m_dummyNSView superview] replaceSubview:m_dummyNSView with:m_cocoaNSView];
         // But since we also retained it ourselves
+        wxASSERT(![m_dummyNSView superview]);
         [m_dummyNSView release];
         m_dummyNSView = nil;
-        return true;
+        wxASSERT([m_cocoaNSView superview]);
     }
     else
     {
+        // If state isn't changing, return false
+        if(m_dummyNSView)
+            return false;
         m_dummyNSView = [[NSView alloc] initWithFrame: [m_cocoaNSView frame]];
         [m_dummyNSView retain];
         // NOTE: replaceSubView will cause m_cocaNSView to be released
         [[m_cocoaNSView superview] replaceSubview:m_cocoaNSView with:m_dummyNSView];
         // m_coocaNSView is now only retained by us
-        return true;
+        wxASSERT([m_dummyNSView superview]);
+        wxASSERT(![m_cocoaNSView superview]);
     }
+    m_isShown = show;
+    return true;
 }
 
 void wxWindowCocoa::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
-    wxLogDebug("wxWindow=%p::DoSetSizeWindow(%d,%d,%d,%d,Auto: %s%s)",this,x,y,width,height,(sizeFlags&wxSIZE_AUTO_WIDTH)?"W":".",sizeFlags&wxSIZE_AUTO_HEIGHT?"H":".");
+//    wxLogDebug("wxWindow=%p::DoSetSizeWindow(%d,%d,%d,%d,Auto: %s%s)",this,x,y,width,height,(sizeFlags&wxSIZE_AUTO_WIDTH)?"W":".",sizeFlags&wxSIZE_AUTO_HEIGHT?"H":".");
     int currentX, currentY;
     int currentW, currentH;
     DoGetPosition(&currentX, &currentY);
@@ -203,9 +328,10 @@ void wxWindowCocoa::DoSetSize(int x, int y, int width, int height, int sizeFlags
 
 void wxWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
 {
-    wxLogDebug("wxWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
+//    wxLogDebug("wxWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
 
-    NSView *superview = [m_cocoaNSView superview];
+    NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView;
+    NSView *superview = [nsview superview];
     wxCHECK_RET(superview,"NSView does not have a superview");
     NSRect parentRect = [superview frame];
 
@@ -224,7 +350,7 @@ void wxWindow::DoGetSize(int *w, int *h) const
         *w=(int)cocoaRect.size.width;
     if(h)
         *h=(int)cocoaRect.size.height;
-    wxLogDebug("wxWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
+//    wxLogDebug("wxWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
 }
 
 void wxWindow::DoGetPosition(int *x, int *y) const
@@ -239,7 +365,7 @@ void wxWindow::DoGetPosition(int *x, int *y) const
         *x=(int)cocoaRect.origin.x;
     if(y)
         *y=(int)(parentRect.size.height-(cocoaRect.origin.y+cocoaRect.size.height));
-    wxLogDebug("wxWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
+//    wxLogDebug("wxWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
 }
 
 WXWidget wxWindow::GetHandle() const
@@ -247,6 +373,11 @@ WXWidget wxWindow::GetHandle() const
     return m_cocoaNSView;
 }
 
+void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
+{
+    [m_cocoaNSView setNeedsDisplay:YES];
+}
+
 void wxWindow::SetFocus()
 {
     // TODO
@@ -304,11 +435,6 @@ void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
     // TODO
 }
 
-void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
-{
-    // TODO
-}
-
 // Coordinates relative to the window
 void wxWindow::WarpPointer (int x_pos, int y_pos)
 {
@@ -367,7 +493,12 @@ void wxWindow::Clear()
 // Raise the window to the top of the Z order
 void wxWindow::Raise()
 {
-    // TODO
+    wxAutoNSAutoreleasePool pool;
+    NSView *nsview = m_dummyNSView?m_dummyNSView:m_cocoaNSView;
+    NSView *superview = [nsview superview];
+    [nsview retain];
+    [nsview removeFromSuperview];
+    [superview addSubview:nsview];
 }
 
 // Lower the window to the bottom of the Z order
@@ -400,3 +531,15 @@ wxWindow *wxGetActiveWindow()
     return NULL;
 }
 
+wxPoint wxGetMousePosition()
+{
+    // TODO
+    return wxDefaultPosition;
+}
+
+wxWindow* wxFindWindowAtPointer(wxPoint& pt)
+{
+    pt = wxGetMousePosition();
+    return NULL;
+}
+