]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/carbon/region.cpp
Document lack of wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK under OS X.
[wxWidgets.git] / src / osx / carbon / region.cpp
index ffd0f106d9f6bcfe9918ff9762fa8151cc2f1dc2..28e78cf999f2bfb251f0426426713d801f6e6405 100644 (file)
@@ -16,6 +16,7 @@
 
 #ifndef WX_PRECOMP
     #include "wx/gdicmn.h"
+    #include "wx/dcmemory.h"
 #endif
 
 #include "wx/osx/private.h"
@@ -67,14 +68,6 @@ public:
 // wxRegion
 //-----------------------------------------------------------------------------
 
-/*!
- * Create an empty region.
- */
-wxRegion::wxRegion()
-{
-    m_refData = new wxRegionRefData();
-}
-
 wxRegion::wxRegion(WXHRGN hRegion )
 {
     wxCFRef< HIShapeRef > shape( (HIShapeRef) hRegion );
@@ -89,8 +82,8 @@ wxRegion::wxRegion(long x, long y, long w, long h)
 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
 {
     m_refData = new wxRegionRefData(topLeft.x , topLeft.y ,
-                                    topLeft.x - bottomRight.x ,
-                                    topLeft.y - bottomRight.y);
+                                    bottomRight.x - topLeft.x,
+                                    bottomRight.y - topLeft.y);
 }
 
 wxRegion::wxRegion(const wxRect& rect)
@@ -98,63 +91,41 @@ wxRegion::wxRegion(const wxRect& rect)
     m_refData = new wxRegionRefData(rect.x , rect.y , rect.width , rect.height);
 }
 
-wxRegion::wxRegion(size_t n, const wxPoint *points, wxPolygonFillMode WXUNUSED(fillStyle))
-{
-    wxUnusedVar(n);
-    wxUnusedVar(points);
-
-#if 0
-    // no non-QD APIs available
-    // TODO : remove ?
-    // OS X somehow does not collect the region invisibly as before, so sometimes things
-    // get drawn on screen instead of just being combined into a region, therefore we allocate a temp gworld now
-
-    GWorldPtr gWorld = NULL;
-    GWorldPtr oldWorld;
-    GDHandle oldGDHandle;
-    OSStatus err;
-    Rect destRect = { 0, 0, 1, 1 };
-
-    ::GetGWorld( &oldWorld, &oldGDHandle );
-    err = ::NewGWorld( &gWorld, 32, &destRect, NULL, NULL, 0 );
-    if ( err == noErr )
-    {
-        ::SetGWorld( gWorld, GetGDevice() );
-
-        OpenRgn();
-
-        wxCoord x1, x2 , y1 , y2 ;
-        x2 = x1 = points[0].x ;
-        y2 = y1 = points[0].y ;
-
-        ::MoveTo( x1, y1 );
-        for (size_t i = 1; i < n; i++)
-        {
-            x2 = points[i].x ;
-            y2 = points[i].y ;
-            ::LineTo( x2, y2 );
-        }
-
-        // close the polyline if necessary
-        if ( x1 != x2 || y1 != y2 )
-            ::LineTo( x1, y1 ) ;
-
-        RgnHandle tempRgn = NewRgn();
-        CloseRgn( tempRgn ) ;
-
-        ::SetGWorld( oldWorld, oldGDHandle );
-        wxCFRef<HIShapeRef> tempShape( HIShapeCreateWithQDRgn(tempRgn ) );
-        m_refData = new wxRegionRefData(tempShape);
-        DisposeRgn( tempRgn );
-    }
-    else
-    {
-        m_refData = new wxRegionRefData;
-    }
-#else
-    wxFAIL_MSG( "not implemented" );
-    m_refData = NULL;
-#endif
+wxRegion::wxRegion(size_t n, const wxPoint *points, wxPolygonFillMode fillStyle)
+{
+    // Set the region to a polygon shape generically using a bitmap with the 
+    // polygon drawn on it. 
+    m_refData = new wxRegionRefData(); 
+     
+    wxCoord mx = 0; 
+    wxCoord my = 0; 
+    wxPoint p; 
+    size_t idx;     
+     
+    // Find the max size needed to draw the polygon 
+    for (idx=0; idx<n; idx++) 
+    { 
+        wxPoint pt = points[idx]; 
+        if (pt.x > mx) 
+            mx = pt.x; 
+        if (pt.y > my) 
+            my = pt.y; 
+    } 
+    // Make the bitmap 
+    wxBitmap bmp(mx, my); 
+    wxMemoryDC dc(bmp); 
+    dc.SetBackground(*wxBLACK_BRUSH); 
+    dc.Clear(); 
+    dc.SetPen(*wxWHITE_PEN); 
+    dc.SetBrush(*wxWHITE_BRUSH); 
+    dc.DrawPolygon(n, (wxPoint*)points, 0, 0, fillStyle); 
+    dc.SelectObject(wxNullBitmap); 
+    bmp.SetMask(new wxMask(bmp, *wxBLACK)); 
+    // Use it to set this region 
+    Union(bmp); 
 }
 
 wxRegion::~wxRegion()
@@ -185,7 +156,7 @@ void wxRegion::Clear()
 // Move the region
 bool wxRegion::DoOffset(wxCoord x, wxCoord y)
 {
-    wxCHECK_MSG( M_REGION, false, wxT("invalid wxRegion") );
+    wxCHECK_MSG( m_refData, false, wxT("invalid wxRegion") );
 
     if ( !x && !y )
         // nothing to do
@@ -198,12 +169,51 @@ bool wxRegion::DoOffset(wxCoord x, wxCoord y)
     return true ;
 }
 
+bool wxRegion::DoUnionWithRect(const wxRect& rect)
+{
+    if ( !m_refData )
+    {
+        m_refData = new wxRegionRefData(rect.x , rect.y , rect.width , rect.height);
+        return true;
+    }
+    
+    AllocExclusive();
+    
+    CGRect r = CGRectMake(rect.x , rect.y , rect.width , rect.height);
+    HIShapeUnionWithRect(M_REGION , &r);
+    
+    return true;
+}
 
 //! Union /e region with this.
 bool wxRegion::DoCombine(const wxRegion& region, wxRegionOp op)
 {
     wxCHECK_MSG( region.IsOk(), false, wxT("invalid wxRegion") );
 
+    // Handle the special case of not initialized (e.g. default constructed)
+    // region as we can't use HIShape functions if we don't have any shape.
+    if ( !m_refData )
+    {
+        switch ( op )
+        {
+            case wxRGN_COPY:
+            case wxRGN_OR:
+            case wxRGN_XOR:
+                // These operations make sense with a null region.
+                *this = region;
+                return true;
+
+            case wxRGN_AND:
+            case wxRGN_DIFF:
+                // Those ones don't really make sense so just leave this region
+                // empty/invalid.
+                return false;
+        }
+
+        wxFAIL_MSG( wxT("Unknown region operation") );
+        return false;
+    }
+
     AllocExclusive();
 
     switch (op)
@@ -242,11 +252,21 @@ bool wxRegion::DoCombine(const wxRegion& region, wxRegionOp op)
 //# Information on region
 //-----------------------------------------------------------------------------
 
-bool wxRegion::DoIsEqual(const wxRegion& WXUNUSED(region)) const
+bool wxRegion::DoIsEqual(const wxRegion& region) const
 {
-    wxFAIL_MSG( wxT("not implemented") );
+    // There doesn't seem to be any native function for checking the equality
+    // of HIShapes so we compute their differences to determine if they are
+    // equal.
+    wxRegion r(*this);
+    r.Subtract(region);
+
+    if ( !r.IsEmpty() )
+        return false;
+
+    wxRegion r2(region);
+    r2.Subtract(*this);
 
-    return false;
+    return r2.IsEmpty();
 }
 
 // Outer bounds of region
@@ -282,6 +302,9 @@ bool wxRegion::IsEmpty() const
 
 WXHRGN wxRegion::GetWXHRGN() const
 {
+    if ( !m_refData )
+        return NULL;
+
     return M_REGION ;
 }
 
@@ -295,7 +318,7 @@ wxRegionContain wxRegion::DoContainsPoint(wxCoord x, wxCoord y) const
     if (!m_refData)
         return wxOutRegion;
 
-    CGPoint p = { x, y } ;
+    CGPoint p = CGPointMake( x, y ) ;
     if (HIShapeContainsPoint( M_REGION , &p ) )
         return wxInRegion;
 
@@ -398,40 +421,6 @@ public :
     long m_current ;
 };
 
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
-
-OSStatus wxMacRegionToRectsCounterCallback(
-    UInt16 message, RgnHandle WXUNUSED(region), const Rect *WXUNUSED(rect), void *data )
-{
-    long *m_numRects = (long*) data ;
-    if ( message == kQDRegionToRectsMsgInit )
-    {
-        (*m_numRects) = 0 ;
-    }
-    else if (message == kQDRegionToRectsMsgParse)
-    {
-        (*m_numRects) += 1 ;
-    }
-
-    return noErr;
-}
-
-OSStatus wxMacRegionToRectsSetterCallback(
-    UInt16 message, RgnHandle WXUNUSED(region), const Rect *rect, void *data )
-{
-    if (message == kQDRegionToRectsMsgParse)
-    {
-        RegionToRectsCallbackData *cb = (RegionToRectsCallbackData*) data ;
-        cb->m_rects[cb->m_current++] = wxRect( rect->left , rect->top , rect->right - rect->left , rect->bottom - rect->top ) ;
-    }
-
-    return noErr;
-}
-
-#endif
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-
 OSStatus wxOSXRegionToRectsCounterCallback(
     int message, HIShapeRef WXUNUSED(region), const CGRect *WXUNUSED(rect), void *data )
 {
@@ -460,8 +449,6 @@ OSStatus wxOSXRegionToRectsSetterCallback(
     return noErr;
 }
 
-#endif
-
 void wxRegionIterator::Reset(const wxRegion& region)
 {
     m_current = 0;
@@ -482,51 +469,20 @@ void wxRegionIterator::Reset(const wxRegion& region)
         m_rects = new wxRect[m_numRects];
         m_rects[0] = m_region.GetBox();
 #endif
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-        if ( HIShapeEnumerate != NULL )
+        OSStatus err = HIShapeEnumerate (OTHER_M_REGION(region), kHIShapeParseFromTopLeft, wxOSXRegionToRectsCounterCallback,
+            (void*)&m_numRects);
+        if (err == noErr)
         {
-            OSStatus err = HIShapeEnumerate (OTHER_M_REGION(region), kHIShapeParseFromTopLeft, wxOSXRegionToRectsCounterCallback,
-                (void*)&m_numRects);
-            if (err == noErr)
-            {
-                m_rects = new wxRect[m_numRects];
-                RegionToRectsCallbackData data ;
-                data.m_rects = m_rects ;
-                data.m_current = 0 ;
-                HIShapeEnumerate( OTHER_M_REGION(region), kHIShapeParseFromTopLeft, wxOSXRegionToRectsSetterCallback,
-                    (void*)&data );
-            }
-            else
-            {
-                m_numRects = 0;
-            }
+            m_rects = new wxRect[m_numRects];
+            RegionToRectsCallbackData data ;
+            data.m_rects = m_rects ;
+            data.m_current = 0 ;
+            HIShapeEnumerate( OTHER_M_REGION(region), kHIShapeParseFromTopLeft, wxOSXRegionToRectsSetterCallback,
+                (void*)&data );
         }
         else
-#endif
         {
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
-            OSStatus err = noErr;
-            RgnHandle rgn = NewRgn();
-            HIShapeGetAsQDRgn(OTHER_M_REGION(region), rgn);
-
-            err = QDRegionToRects (rgn, kQDParseRegionFromTopLeft, wxMacRegionToRectsCounterCallback
-                , (void*)&m_numRects);
-            if (err == noErr)
-            {
-                m_rects = new wxRect[m_numRects];
-                RegionToRectsCallbackData data ;
-                data.m_rects = m_rects ;
-                data.m_current = 0 ;
-                QDRegionToRects( rgn , kQDParseRegionFromTopLeft, wxMacRegionToRectsSetterCallback,
-                    (void*)&data );
-            }
-            else
-            {
-                m_numRects = 0;
-            }
-            DisposeRgn( rgn );
-#endif
+            m_numRects = 0;
         }
     }
 }