]> git.saurik.com Git - wxWidgets.git/blobdiff - src/cocoa/window.mm
don't use parent window of a TLW in HandleOnNavigationKey(), even if it's apparently...
[wxWidgets.git] / src / cocoa / window.mm
index 22228ee52c8b50e36170cda9c6026a1a5d1dc9e2..8449277a890243996102c5f838ac249da583c70f 100644 (file)
     #include "wx/log.h"
     #include "wx/window.h"
     #include "wx/dc.h"
+    #include "wx/dcclient.h"
     #include "wx/utils.h"
 #endif //WX_PRECOMP
 
 #include "wx/tooltip.h"
 
+#include "wx/cocoa/dc.h"
 #include "wx/cocoa/autorelease.h"
 #include "wx/cocoa/string.h"
 #include "wx/cocoa/trackingrectmanager.h"
 #include "wx/mac/corefoundation/cfref.h"
+#include "wx/cocoa/ObjcRef.h"
 
 #import <Foundation/NSArray.h>
 #import <Foundation/NSRunLoop.h>
@@ -985,7 +988,7 @@ void wxWindowCocoaScrollView::_wx_doScroller(NSScroller *sender)
     }
     wxScrollWinEvent event(commandType, scrollpos, orientation);
     event.SetEventObject(m_owner);
-    m_owner->GetEventHandler()->ProcessEvent(event);
+    m_owner->HandleWindowEvent(event);
 }
 
 void wxWindowCocoaScrollView::UpdateSizes()
@@ -1010,7 +1013,7 @@ void wxWindowCocoaScrollView::Cocoa_FrameChanged(void)
     wxLogTrace(wxTRACE_COCOA,wxT("wxWindowCocoaScrollView=%p::Cocoa_FrameChanged for wxWindow %p"), this, m_owner);
     wxSizeEvent event(m_owner->GetSize(), m_owner->GetId());
     event.SetEventObject(m_owner);
-    m_owner->GetEventHandler()->ProcessEvent(event);
+    m_owner->HandleWindowEvent(event);
     UpdateSizes();
 }
 
@@ -1107,8 +1110,8 @@ void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView)
     bool need_debug = cocoaNSView || m_cocoaNSView;
     if(need_debug) wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxWindowCocoa=%p::SetNSView [m_cocoaNSView=%p retainCount]=%d"),this,m_cocoaNSView,[m_cocoaNSView retainCount]);
     DisassociateNSView(m_cocoaNSView);
-    [cocoaNSView retain];
-    [m_cocoaNSView release];
+    wxGCSafeRetain(cocoaNSView);
+    wxGCSafeRelease(m_cocoaNSView);
     m_cocoaNSView = cocoaNSView;
     AssociateNSView(m_cocoaNSView);
     if(need_debug) wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxWindowCocoa=%p::SetNSView [cocoaNSView=%p retainCount]=%d"),this,cocoaNSView,[cocoaNSView retainCount]);
@@ -1157,7 +1160,7 @@ NSRect wxWindowCocoa::CocoaTransformWxToBounds(NSRect rectWx)
 WX_NSAffineTransform wxWindowCocoa::CocoaGetWxToBoundsTransform()
 {
     // TODO: Handle scrolling offset
-    NSAffineTransform *transform = wxDC::CocoaGetWxToBoundsTransform([GetNSView() isFlipped], [GetNSView() bounds].size.height);
+    NSAffineTransform *transform = wxCocoaDCImpl::CocoaGetWxToBoundsTransform([GetNSView() isFlipped], [GetNSView() bounds].size.height);
     return transform;
 }
 
@@ -1191,7 +1194,7 @@ bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect)
 
     wxPaintEvent event(m_windowId);
     event.SetEventObject(this);
-    bool ret = GetEventHandler()->ProcessEvent(event);
+    bool ret = HandleWindowEvent(event);
     m_isInPaint = false;
     return ret;
 }
@@ -1202,6 +1205,44 @@ void wxWindowCocoa::InitMouseEvent(wxMouseEvent& event, WX_NSEvent cocoaEvent)
     // Mouse events happen at the NSWindow level so we need to convert
     // into our bounds coordinates then convert to wx coordinates.
     NSPoint cocoaPoint = [m_cocoaNSView convertPoint:[(NSEvent*)cocoaEvent locationInWindow] fromView:nil];
+    if( m_wxCocoaScrollView != NULL)
+    {
+        // This gets the wx client area (i.e. the visible portion of the content) in
+        // the coordinate system of our (the doucment) view.
+       NSRect documentVisibleRect = [[m_wxCocoaScrollView->GetNSScrollView() contentView] documentVisibleRect];
+        // For horizontal, simply subtract the origin.
+        // e.g. if the origin is at 123 and the user clicks as far left as possible then
+        // the coordinate that wx wants is 0.
+       cocoaPoint.x -= documentVisibleRect.origin.x;
+        if([m_cocoaNSView isFlipped])
+        {
+            // In the flipped view case this works exactly like horizontal.
+            cocoaPoint.y -= documentVisibleRect.origin.y;
+        }
+        // For vertical we have to mind non-flipped (e.g. y=0 at bottom) views.
+        // We also need to mind the fact that we're still in Cocoa coordinates
+        // and not wx coordinates.  The wx coordinate translation will still occur
+        // and that is going to be wxY = boundsH - cocoaY for non-flipped views.
+
+        // When we consider scrolling we are truly interested in how far the top
+        // edge of the bounds rectangle is scrolled off the screen.
+        // Assuming the bounds origin is 0 (which is an assumption we make in
+        // wxCocoa since wxWidgets has no analog to it) then the top edge of
+        // the bounds rectangle is simply its height.  The top edge of the
+        // documentVisibleRect (e.g. the client area) is its height plus
+        // its origin.
+        // Thus, we simply need add the distance between the bounds top
+        // and the client (docuemntVisibleRect) top.
+        // Or putting it another way, we subtract the distance between the
+        // client top and the bounds top.
+        else
+        {
+            NSRect bounds = [m_cocoaNSView bounds];
+            CGFloat scrollYOrigin = (bounds.size.height - (documentVisibleRect.origin.y + documentVisibleRect.size.height));
+            cocoaPoint.y += scrollYOrigin;
+        }
+    }
+
     NSPoint pointWx = CocoaTransformBoundsToWx(cocoaPoint);
     // FIXME: Should we be adjusting for client area origin?
     const wxPoint &clientorigin = GetClientAreaOrigin();
@@ -1223,7 +1264,7 @@ bool wxWindowCocoa::Cocoa_mouseMoved(WX_NSEvent theEvent)
     wxMouseEvent event(wxEVT_MOTION);
     InitMouseEvent(event,theEvent);
     wxLogTrace(wxTRACE_COCOA,wxT("wxWindow=%p::Cocoa_mouseMoved @%d,%d"),this,event.m_x,event.m_y);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 void wxWindowCocoa::Cocoa_synthesizeMouseMoved()
@@ -1244,7 +1285,7 @@ void wxWindowCocoa::Cocoa_synthesizeMouseMoved()
     event.SetId(GetId());
 
     wxLogTrace(wxTRACE_COCOA,wxT("wxwin=%p Synthesized Mouse Moved @%d,%d"),this,event.m_x,event.m_y);
-    GetEventHandler()->ProcessEvent(event);
+    HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_mouseEntered(WX_NSEvent theEvent)
@@ -1262,7 +1303,7 @@ bool wxWindowCocoa::Cocoa_mouseEntered(WX_NSEvent theEvent)
         wxMouseEvent event(wxEVT_ENTER_WINDOW);
         InitMouseEvent(event,theEvent);
         wxLogTrace(wxTRACE_COCOA_TrackingRect,wxT("wxwin=%p Mouse Entered TR#%d @%d,%d"),this,[theEvent trackingNumber], event.m_x,event.m_y);
-        return GetEventHandler()->ProcessEvent(event);
+        return HandleWindowEvent(event);
     }
     else
         return false;
@@ -1277,7 +1318,7 @@ bool wxWindowCocoa::Cocoa_mouseExited(WX_NSEvent theEvent)
         wxMouseEvent event(wxEVT_LEAVE_WINDOW);
         InitMouseEvent(event,theEvent);
         wxLogTrace(wxTRACE_COCOA_TrackingRect,wxT("wxwin=%p Mouse Exited TR#%d @%d,%d"),this,[theEvent trackingNumber],event.m_x,event.m_y);
-        return GetEventHandler()->ProcessEvent(event);
+        return HandleWindowEvent(event);
     }
     else
         return false;
@@ -1288,7 +1329,7 @@ bool wxWindowCocoa::Cocoa_mouseDown(WX_NSEvent theEvent)
     wxMouseEvent event([theEvent clickCount]<2?wxEVT_LEFT_DOWN:wxEVT_LEFT_DCLICK);
     InitMouseEvent(event,theEvent);
     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Down @%d,%d num clicks=%d"),event.m_x,event.m_y,[theEvent clickCount]);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_mouseDragged(WX_NSEvent theEvent)
@@ -1297,7 +1338,7 @@ bool wxWindowCocoa::Cocoa_mouseDragged(WX_NSEvent theEvent)
     InitMouseEvent(event,theEvent);
     event.m_leftDown = true;
     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Drag @%d,%d"),event.m_x,event.m_y);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_mouseUp(WX_NSEvent theEvent)
@@ -1305,7 +1346,7 @@ bool wxWindowCocoa::Cocoa_mouseUp(WX_NSEvent theEvent)
     wxMouseEvent event(wxEVT_LEFT_UP);
     InitMouseEvent(event,theEvent);
     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Up @%d,%d"),event.m_x,event.m_y);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_rightMouseDown(WX_NSEvent theEvent)
@@ -1313,7 +1354,7 @@ bool wxWindowCocoa::Cocoa_rightMouseDown(WX_NSEvent theEvent)
     wxMouseEvent event([theEvent clickCount]<2?wxEVT_RIGHT_DOWN:wxEVT_RIGHT_DCLICK);
     InitMouseEvent(event,theEvent);
     wxLogDebug(wxT("Mouse Down @%d,%d num clicks=%d"),event.m_x,event.m_y,[theEvent clickCount]);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_rightMouseDragged(WX_NSEvent theEvent)
@@ -1322,7 +1363,7 @@ bool wxWindowCocoa::Cocoa_rightMouseDragged(WX_NSEvent theEvent)
     InitMouseEvent(event,theEvent);
     event.m_rightDown = true;
     wxLogDebug(wxT("Mouse Drag @%d,%d"),event.m_x,event.m_y);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_rightMouseUp(WX_NSEvent theEvent)
@@ -1330,7 +1371,7 @@ bool wxWindowCocoa::Cocoa_rightMouseUp(WX_NSEvent theEvent)
     wxMouseEvent event(wxEVT_RIGHT_UP);
     InitMouseEvent(event,theEvent);
     wxLogDebug(wxT("Mouse Up @%d,%d"),event.m_x,event.m_y);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowCocoa::Cocoa_otherMouseDown(WX_NSEvent theEvent)
@@ -1363,7 +1404,7 @@ void wxWindowCocoa::Cocoa_FrameChanged(void)
             m_visibleTrackingRectManager->RebuildTrackingRect();
         wxSizeEvent event(GetSize(), m_windowId);
         event.SetEventObject(this);
-        GetEventHandler()->ProcessEvent(event);
+        HandleWindowEvent(event);
     }
     else
     {
@@ -1744,7 +1785,7 @@ void wxWindow::GetTextExtent(const wxString& string, int *outX, int *outY,
     // transformations.  However, it's better than nothing.
     // We don't create a wxClientDC because we don't want to accidently be able to use
     // it for drawing.
-    wxDC tmpdc;
+    wxClientDC tmpdc(const_cast<wxWindow*>(this));
     return tmpdc.GetTextExtent(string, outX, outY, outDescent, outExternalLeading, inFont);
 }