X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4bb6408c2631988fab9925014c6619358bf867de..84c5b38d579e140df28cfbb649587e8862148c89:/src/motif/region.cpp?ds=sidebyside diff --git a/src/motif/region.cpp b/src/motif/region.cpp index fcc58d3175..fb3b1e3db2 100644 --- a/src/motif/region.cpp +++ b/src/motif/region.cpp @@ -1,10 +1,10 @@ ///////////////////////////////////////////////////////////////////////////// // File: region.cpp // Purpose: Region class -// Author: Markus Holzem/Julian Smart/Julian Smart +// Author: Markus Holzem/Julian Smart // Created: Fri Oct 24 10:46:34 MET 1997 -// RCS-ID: $Id$ -// Copyright: (c) 1997 Markus Holzem/Julian Smart/Julian Smart +// RCS-ID: $Id$ +// Copyright: (c) 1997 Markus Holzem/Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -15,10 +15,25 @@ #include "wx/region.h" #include "wx/gdicmn.h" -#if !USE_SHARED_LIBRARY - IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) - IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) +#ifdef __VMS__ +#pragma message disable nosimpint #endif +#include +#ifdef __VMS__ +#pragma message enable nosimpint +#endif +// #include "wx/motif/private.h" + + IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) + IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) + +// ---------------------------------------------------------------------------- +// list types +// ---------------------------------------------------------------------------- + +#include "wx/listimpl.cpp" + +WX_DEFINE_LIST(wxRectList); //----------------------------------------------------------------------------- // wxRegionRefData implementation @@ -26,21 +41,90 @@ class WXDLLEXPORT wxRegionRefData : public wxGDIRefData { public: - wxRegionRefData() - { - } - - wxRegionRefData(const wxRegionRefData& data) - { - // TODO - } - - ~wxRegionRefData() - { - // TODO - } + wxRegionRefData() + { + m_region = XCreateRegion(); + m_usingRects = FALSE; + m_rects = (wxRect*) NULL; + m_rectCount = 0; + } + + wxRegionRefData(const wxRegionRefData& data) + { + m_region = XCreateRegion(); + m_rects = (wxRect*) NULL; + m_rectCount = 0; + XUnionRegion(m_region, data.m_region, m_region); + + SetRects(data.m_rectCount, data.m_rects); + } + + ~wxRegionRefData() + { + XDestroyRegion(m_region); + DeleteRects(); + } + + wxRect* GetRects() { return m_rects; }; + void SetRects(const wxRectList& rectList); + void SetRects(int count, const wxRect* rects); + bool UsingRects() const { return m_usingRects; } + int GetRectCount() const { return m_rectCount; } + + void DeleteRects(); + + Region m_region; + wxRect* m_rects; + int m_rectCount; + bool m_usingRects; // TRUE if we're using the above. }; +void wxRegionRefData::SetRects(const wxRectList& rectList) +{ + DeleteRects(); + m_usingRects = (rectList.Number() > 0); + if (m_usingRects) + { + m_rectCount = rectList.Number(); + m_rects = new wxRect[m_rectCount]; + } + + wxRectList::Node* node = rectList.GetFirst(); + int i = 0; + while (node) { + wxRect* rect = node->GetData(); + m_rects[i] = * rect; + node = node->GetNext(); + i ++; + } +} + +void wxRegionRefData::SetRects(int count, const wxRect* rects) +{ + DeleteRects(); + m_usingRects = (count > 0); + if (m_usingRects) + { + m_rectCount = count; + m_rects = new wxRect[m_rectCount]; + int i; + for (i = 0; i < m_rectCount; i++) + m_rects[i] = rects[i]; + } +} + +void wxRegionRefData::DeleteRects() +{ + if (m_rects) + { + delete[] m_rects; + m_rects = (wxRect*) NULL; + } + m_rectCount = 0; + m_usingRects = FALSE; + } + +#define M_REGION (((wxRegionRefData*)m_refData)->m_region) //----------------------------------------------------------------------------- // wxRegion @@ -51,26 +135,42 @@ public: */ wxRegion::wxRegion() { - m_refData = new wxRegionRefData; - // TODO create empty region } -wxRegion::wxRegion(long x, long y, long w, long h) +wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) { m_refData = new wxRegionRefData; - // TODO create rect region + + XRectangle rect; + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XUnionRectWithRegion(&rect, M_REGION, M_REGION); } wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight) { m_refData = new wxRegionRefData; - // TODO create rect region + + XRectangle rect; + rect.x = topLeft.x; + rect.y = topLeft.y; + rect.width = bottomRight.x - topLeft.x; + rect.height = bottomRight.y - topLeft.y; + XUnionRectWithRegion(&rect, M_REGION, M_REGION); } wxRegion::wxRegion(const wxRect& rect) { m_refData = new wxRegionRefData; - // TODO create rect region + + XRectangle rect1; + rect1.x = rect.x; + rect1.y = rect.y; + rect1.width = rect.width; + rect1.height = rect.height; + XUnionRectWithRegion(&rect1, M_REGION, M_REGION); } /*! @@ -81,6 +181,14 @@ wxRegion::~wxRegion() // m_refData unrefed in ~wxObject } +// Get the internal region handle +WXRegion wxRegion::GetXRegion() const +{ + wxASSERT( m_refData !=NULL ); + + return (WXRegion) ((wxRegionRefData*)m_refData)->m_region; +} + //----------------------------------------------------------------------------- //# Modify region //----------------------------------------------------------------------------- @@ -92,28 +200,34 @@ void wxRegion::Clear() } //! Combine rectangle (x, y, w, h) with this. -bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op) -{ - // Don't change shared data - if (!m_refData) { - m_refData = new wxRegionRefData(); - } else if (m_refData->GetRefCount() > 1) { - wxRegionRefData* ref = (wxRegionRefData*)m_refData; - UnRef(); - m_refData = new wxRegionRefData(*ref); - } +bool wxRegion::Combine(wxCoord x, wxCoord y, wxCoord width, wxCoord height, wxRegionOp op) +{ + // Don't change shared data + if (!m_refData) { + m_refData = new wxRegionRefData(); + } else if (m_refData->GetRefCount() > 1) { + wxRegionRefData* ref = (wxRegionRefData*)m_refData; + UnRef(); + m_refData = new wxRegionRefData(*ref); + } // If ref count is 1, that means it's 'ours' anyway so no action. - // TODO create rect region + Region rectRegion = XCreateRegion(); + + XRectangle rect; + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + XUnionRectWithRegion(&rect, rectRegion, rectRegion); - int mode = 0; // TODO platform-specific code switch (op) { case wxRGN_AND: - // TODO + XIntersectRegion(M_REGION, rectRegion, M_REGION); break ; case wxRGN_OR: - // TODO + XUnionRegion(M_REGION, rectRegion, M_REGION); break ; case wxRGN_XOR: // TODO @@ -121,40 +235,39 @@ bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op) case wxRGN_DIFF: // TODO break ; - case wxRGN_COPY: + case wxRGN_COPY: // Don't have to do this one default: // TODO break ; } - // TODO do combine region - return FALSE; } //! Union /e region with this. bool wxRegion::Combine(const wxRegion& region, wxRegionOp op) { - if (region.Empty()) - return FALSE; - - // Don't change shared data - if (!m_refData) { - m_refData = new wxRegionRefData(); - } else if (m_refData->GetRefCount() > 1) { - wxRegionRefData* ref = (wxRegionRefData*)m_refData; - UnRef(); - m_refData = new wxRegionRefData(*ref); - } + if (region.Empty()) + return FALSE; + + // Don't change shared data + if (!m_refData) { + m_refData = new wxRegionRefData(); + } else if (m_refData->GetRefCount() > 1) { + wxRegionRefData* ref = (wxRegionRefData*)m_refData; + UnRef(); + m_refData = new wxRegionRefData(*ref); + } - int mode = 0; // TODO platform-specific code switch (op) { case wxRGN_AND: - // TODO + XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, + M_REGION); break ; case wxRGN_OR: - // TODO + XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, + M_REGION); break ; case wxRGN_XOR: // TODO @@ -162,15 +275,13 @@ bool wxRegion::Combine(const wxRegion& region, wxRegionOp op) case wxRGN_DIFF: // TODO break ; - case wxRGN_COPY: + case wxRGN_COPY: // Don't have to do this one default: // TODO break ; } - // TODO combine region - - return FALSE; + return FALSE; } bool wxRegion::Combine(const wxRect& rect, wxRegionOp op) @@ -183,18 +294,23 @@ bool wxRegion::Combine(const wxRect& rect, wxRegionOp op) //----------------------------------------------------------------------------- // Outer bounds of region -void wxRegion::GetBox(long& x, long& y, long&w, long &h) const +void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const { - if (m_refData) { - // TODO get box - } else { - x = y = w = h = 0; - } + if (m_refData) { + XRectangle rect; + XClipBox(M_REGION, &rect); + x = rect.x; + y = rect.y; + w = rect.width; + h = rect.height; + } else { + x = y = w = h = 0; + } } wxRect wxRegion::GetBox() const { - long x, y, w, h; + wxCoord x, y, w, h; GetBox(x, y, w, h); return wxRect(x, y, w, h); } @@ -202,8 +318,7 @@ wxRect wxRegion::GetBox() const // Is region empty? bool wxRegion::Empty() const { - // TODO - return FALSE; + return m_refData ? XEmptyRegion(M_REGION) : TRUE; } //----------------------------------------------------------------------------- @@ -211,10 +326,10 @@ bool wxRegion::Empty() const //----------------------------------------------------------------------------- // Does the region contain the point (x,y)? -wxRegionContain wxRegion::Contains(long x, long y) const +wxRegionContain wxRegion::Contains(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const { - if (!m_refData) - return wxOutRegion; + if (!m_refData) + return wxOutRegion; // TODO. Return wxInRegion if within region. if (0) @@ -225,36 +340,32 @@ wxRegionContain wxRegion::Contains(long x, long y) const // Does the region contain the point pt? wxRegionContain wxRegion::Contains(const wxPoint& pt) const { - if (!m_refData) - return wxOutRegion; - - // TODO. Return wxInRegion if within region. - if (0) - return wxInRegion; - else + if (!m_refData) return wxOutRegion; + + return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion; } // Does the region contain the rectangle (x, y, w, h)? -wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const +wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const { - if (!m_refData) - return wxOutRegion; - - // TODO. Return wxInRegion if within region. - if (0) - return wxInRegion; - else + if (!m_refData) return wxOutRegion; + + switch (XRectInRegion(M_REGION, x, y, w, h)) { + case RectangleIn: return wxInRegion; + case RectanglePart: return wxPartRegion; + } + return wxOutRegion; } // Does the region contain the rectangle rect wxRegionContain wxRegion::Contains(const wxRect& rect) const { - if (!m_refData) - return wxOutRegion; + if (!m_refData) + return wxOutRegion; - long x, y, w, h; + wxCoord x, y, w, h; x = rect.x; y = rect.y; w = rect.GetWidth(); @@ -262,10 +373,42 @@ wxRegionContain wxRegion::Contains(const wxRect& rect) const return Contains(x, y, w, h); } +bool wxRegion::UsingRects() const +{ + return ((wxRegionRefData*)m_refData)->UsingRects(); +} + +/* +wxRectList& wxRegion::GetRectList() +{ + return ((wxRegionRefData*)m_refData)->GetRectList(); +} +*/ + +wxRect* wxRegion::GetRects() +{ + return ((wxRegionRefData*)m_refData)->GetRects(); +} + +int wxRegion::GetRectCount() const +{ + return ((wxRegionRefData*)m_refData)->GetRectCount(); +} + +void wxRegion::SetRects(const wxRectList& rectList) +{ + ((wxRegionRefData*)m_refData)->SetRects(rectList); +} + +void wxRegion::SetRects(int count, const wxRect* rects) +{ + ((wxRegionRefData*)m_refData)->SetRects(count, rects); +} + /////////////////////////////////////////////////////////////////////////////// -// // -// wxRegionIterator // -// // +// // +// wxRegionIterator // +// // /////////////////////////////////////////////////////////////////////////////// /*! @@ -288,7 +431,7 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region) { m_rects = NULL; - Reset(region); + Reset(region); } /*! @@ -296,20 +439,50 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region) */ void wxRegionIterator::Reset(const wxRegion& region) { - m_current = 0; - m_region = region; + m_current = 0; + m_region = region; if (m_rects) delete[] m_rects; m_rects = NULL; - if (m_region.Empty()) - m_numRects = 0; - else - { - // TODO create m_rects and fill with rectangles for this region + if (m_region.Empty()) m_numRects = 0; + else + { + // Create m_rects and fill with rectangles for this region. + // Since we can't find the rectangles in a region, we cheat + // by retrieving the rectangles explicitly set in wxPaintDC::wxPaintDC + // (dcclient.cpp). + if (m_region.UsingRects()) + { + wxRect* rects = m_region.GetRects(); + int count = m_region.GetRectCount(); + m_numRects = count; + m_rects = new wxRect[m_numRects]; + + for (size_t i = 0; i < m_numRects; i++) + m_rects[i] = rects[i]; + + /* + int i = 0; + wxRectList::Node* node = rectList.GetFirst(); + while (node) { + wxRect* rect = node->GetData(); + m_rects[i] = * rect; + node = node->GetNext(); + i ++; + } + */ + } + else + { + // For now, fudge by getting the whole bounding box. + m_rects = new wxRect[1]; + m_numRects = 1; + m_rects[0] = m_region.GetBox(); + } } } @@ -319,8 +492,8 @@ void wxRegionIterator::Reset(const wxRegion& region) */ void wxRegionIterator::operator ++ () { - if (m_current < m_numRects) - ++m_current; + if (m_current < m_numRects) + ++m_current; } /*! @@ -329,35 +502,35 @@ void wxRegionIterator::operator ++ () */ void wxRegionIterator::operator ++ (int) { - if (m_current < m_numRects) - ++m_current; + if (m_current < m_numRects) + ++m_current; } -long wxRegionIterator::GetX() const +wxCoord wxRegionIterator::GetX() const { - if (m_current < m_numRects) - return m_rects[m_current].x; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].x; + return 0; } -long wxRegionIterator::GetY() const +wxCoord wxRegionIterator::GetY() const { - if (m_current < m_numRects) - return m_rects[m_current].y; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].y; + return 0; } -long wxRegionIterator::GetW() const +wxCoord wxRegionIterator::GetW() const { - if (m_current < m_numRects) - return m_rects[m_current].width ; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].width ; + return 0; } -long wxRegionIterator::GetH() const +wxCoord wxRegionIterator::GetH() const { - if (m_current < m_numRects) - return m_rects[m_current].height; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].height; + return 0; }