From 148b44a1e7d050307bba3f10fd4520aa514e196f Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Sat, 24 May 2003 19:41:05 +0000 Subject: [PATCH] Used wxRegion code from wxX11. Removed update rect list from wxWindow (not necessary anymore). Simplified and corrected clipping region handling in wxWindowDC. Stopped wxWindowDC::DoBlit from destroying the clipping region. Simplified wxPaintDC code. Added wxWindow::DoCreateScrollBar helper function. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20721 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- distrib/msw/tmake/filelist.txt | 6 +- include/wx/motif/dcclient.h | 14 +- include/wx/motif/window.h | 16 +- include/wx/region.h | 2 +- src/motif/dcclient.cpp | 176 ++++------- src/motif/files.lst | 8 +- src/motif/region.cpp | 545 --------------------------------- src/motif/window.cpp | 175 +++++------ 8 files changed, 160 insertions(+), 782 deletions(-) delete mode 100644 src/motif/region.cpp diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index 13303bd38f..0b300e0919 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -652,7 +652,6 @@ msgdlg.cpp Motif palette.cpp Motif radiobox.cpp Motif radiobut.cpp Motif -region.cpp Motif scrolbar.cpp Motif settings.cpp Motif slider.cpp Motif @@ -693,7 +692,7 @@ minifram.cpp X11 palette.cpp X11 pen.cpp X11 Motif popupwin.cpp X11 -region.cpp X11 +region.cpp X11 Motif reparent.cpp X11 settings.cpp X11 toplevel.cpp X11 @@ -1273,7 +1272,6 @@ print.h MotifH private.h MotifH radiobox.h MotifH radiobut.h MotifH -region.h MotifH scrolbar.h MotifH settings.h MotifH slider.h MotifH @@ -1314,7 +1312,7 @@ pen.h X11H Motif print.h X11H private.h X11H privx.h X11H Motif -region.h X11H +region.h X11H Motif reparent.h X11H textctrl.h X11H toplevel.h X11H diff --git a/include/wx/motif/dcclient.h b/include/wx/motif/dcclient.h index 58059b7fda..ef1fabd10b 100644 --- a/include/wx/motif/dcclient.h +++ b/include/wx/motif/dcclient.h @@ -78,7 +78,7 @@ public: virtual void DestroyClippingRegion(); // Helper function for setting clipping - void SetDCClipping(); + void SetDCClipping(WXRegion region); // implementation from now on // -------------------------- @@ -150,15 +150,15 @@ protected: WXGC m_gcBacking; WXDisplay* m_display; wxWindow* m_window; - // Current clipping region (incl. paint clip region) - WXRegion m_currentRegion; - WXRegion m_userRegion; // User-defined clipping region - WXPixmap m_pixmap; // Pixmap for drawing on - + // Pixmap for drawing on + WXPixmap m_pixmap; + // Last clipping region set on th GC, this is the combination + // of paint clipping region and all user-defined clipping regions + WXRegion m_clipRegion; + // Not sure if we'll need all of these int m_backgroundPixel; wxColour m_currentColour; - // int m_currentBkMode; int m_currentPenWidth ; int m_currentPenJoin ; int m_currentPenCap ; diff --git a/include/wx/motif/window.h b/include/wx/motif/window.h index 2e0dbaa1ac..84d7303a64 100644 --- a/include/wx/motif/window.h +++ b/include/wx/motif/window.h @@ -142,15 +142,8 @@ public: // (for wxWindowDC and Motif callbacks only) // ----------------------------------------- - // read/write access to the update rect list - const wxRectList& GetUpdateRects() const { return m_updateRects; } - // Adds a recangle to the updates list - void AddUpdateRect(int x, int y, int w, int h) - { m_updateRects.Append(new wxRect(x, y, w, h)); } - - // Empties the m_updateRects list - void ClearUpdateRects(); + void AddUpdateRect(int x, int y, int w, int h); void ClearUpdateRegion() { m_updateRegion.Clear(); } void SetUpdateRegion(const wxRegion& region) { m_updateRegion = region; } @@ -189,6 +182,10 @@ protected: void DoMoveWindowIntr(int x, int y, int width, int height, int flags); + + // helper function, to remove duplicate code, used in wxScrollBar + WXWidget DoCreateScrollBar(WXWidget parent, wxOrientation orientation, + void (*callback)()); public: WXPixmap GetBackingPixmap() const { return m_backingPixmap; } void SetBackingPixmap(WXPixmap pixmap) { m_backingPixmap = pixmap; } @@ -265,9 +262,6 @@ protected: long m_lastTS; // last timestamp unsigned m_lastButton:2; // last pressed button - // List of wxRects representing damaged region - wxRectList m_updateRects; - protected: WXWidget m_mainWidget; WXWidget m_hScrollBar; diff --git a/include/wx/region.h b/include/wx/region.h index 09d1500623..5bb9cd1118 100644 --- a/include/wx/region.h +++ b/include/wx/region.h @@ -4,7 +4,7 @@ #if defined(__WXMSW__) #include "wx/msw/region.h" #elif defined(__WXMOTIF__) -#include "wx/motif/region.h" +#include "wx/x11/region.h" #elif defined(__WXGTK__) #include "wx/gtk/region.h" #elif defined(__WXX11__) diff --git a/src/motif/dcclient.cpp b/src/motif/dcclient.cpp index d702b6d764..1211436700 100644 --- a/src/motif/dcclient.cpp +++ b/src/motif/dcclient.cpp @@ -140,12 +140,11 @@ void wxWindowDC::Init() m_currentFill = -1; m_colour = wxColourDisplay(); m_display = (WXDisplay*) NULL; - m_currentRegion = (WXRegion) 0; - m_userRegion = (WXRegion) 0; m_pixmap = (WXPixmap) 0; m_autoSetting = 0; m_oldFont = (WXFont) 0; m_ok = false; + m_clipRegion = (WXRegion) 0; } wxWindowDC::wxWindowDC() @@ -215,13 +214,9 @@ wxWindowDC::~wxWindowDC() XFreeGC ((Display*) m_display, (GC) m_gcBacking); m_gcBacking = (WXGC) 0; - if (m_currentRegion) - XDestroyRegion ((Region) m_currentRegion); - m_currentRegion = (WXRegion) 0; - - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = (WXRegion) 0; + if (m_clipRegion) + XDestroyRegion ((Region) m_clipRegion); + m_clipRegion = (WXRegion) 0; } extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, @@ -788,9 +783,12 @@ bool wxWindowDC::CanDrawBitmap() const return TRUE; } -// TODO: use scaled Blit e.g. as per John Price's implementation in Contrib/Utilities -bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, - wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask, +// TODO: use scaled Blit e.g. as per John Price's implementation +// in Contrib/Utilities +bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, + wxCoord width, wxCoord height, + wxDC *source, wxCoord xsrc, wxCoord ysrc, + int rop, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { wxCHECK_MSG( Ok(), FALSE, "invalid dc" ); @@ -912,7 +910,12 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he if ( useMask ) { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); + if ( m_clipRegion ) + XSetRegion ((Display*) m_display, (GC) m_gc, + (Region) m_clipRegion); + else + XSetClipMask ((Display*) m_display, (GC) m_gc, None); + XSetClipOrigin ((Display*) m_display, (GC) m_gc, 0, 0); } @@ -976,7 +979,12 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he } if ( useMask ) { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); + if ( m_clipRegion ) + XSetRegion ((Display*) m_display, (GC) m_gc, + (Region) m_clipRegion); + else + XSetClipMask ((Display*) m_display, (GC) m_gc, None); + XSetClipOrigin ((Display*) m_display, (GC) m_gc, 0, 0); } @@ -2077,57 +2085,54 @@ void wxWindowDC::SetPalette( const wxPalette& palette ) } } -// Helper function -void wxWindowDC::SetDCClipping() +static void wxCopyRegion( WXRegion src, WXRegion& dst ) { - // m_userRegion is the region set by calling SetClippingRegion - - if (m_currentRegion) - XDestroyRegion ((Region) m_currentRegion); - - // We need to take into account - // clipping imposed on a window by a repaint. - // We'll combine it with the user region. But for now, - // just use the currently-defined user clipping region. - if (m_userRegion || (m_window && m_window->GetUpdateRegion().Ok()) ) - m_currentRegion = (WXRegion) XCreateRegion (); - else - m_currentRegion = (WXRegion) NULL; - - if ((m_window && m_window->GetUpdateRegion().Ok()) && m_userRegion) - XIntersectRegion ((Region) m_window->GetUpdateRegion().GetXRegion(), (Region) m_userRegion, (Region) m_currentRegion); - else if (m_userRegion) - XIntersectRegion ((Region) m_userRegion, (Region) m_userRegion, (Region) m_currentRegion); - else if (m_window && m_window->GetUpdateRegion().Ok()) - XIntersectRegion ((Region) m_window->GetUpdateRegion().GetXRegion(), (Region) m_window->GetUpdateRegion().GetXRegion(), - (Region) m_currentRegion); + if( !dst ) + dst = XCreateRegion(); + XUnionRegion( (Region)src, (Region)src, (Region)dst ); +} - if (m_currentRegion) +// Helper function; userRegion is the region set by calling SetClippingRegion +void wxWindowDC::SetDCClipping( WXRegion userRegion ) +{ + bool hasUpdateRegion = m_window && m_window->GetUpdateRegion().Ok(); + // this means that we should start the clip region from scratch, + // or from the update region, if any + if( !userRegion ) { - XSetRegion ((Display*) m_display, (GC) m_gc, (Region) m_currentRegion); + if( m_clipRegion ) + XDestroyRegion( (Region)m_clipRegion ); + m_clipRegion = (WXRegion)NULL; + + if( hasUpdateRegion ) + wxCopyRegion( m_window->GetUpdateRegion().GetX11Region(), + m_clipRegion ); } - else + // intersect the user region, if any, with the + // exisiting clip region + else // if( userRegion ) { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); + if( !m_clipRegion ) + wxCopyRegion( userRegion, m_clipRegion ); + else + XIntersectRegion( (Region)m_clipRegion, + (Region)userRegion, (Region)m_clipRegion ); } + if( m_clipRegion ) + XSetRegion( (Display*)m_display, (GC)m_gc, (Region)m_clipRegion ); + else + XSetClipMask( (Display*)m_display, (GC)m_gc, None ); } -void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, + wxCoord width, wxCoord height ) { wxDC::DoSetClippingRegion( x, y, width, height ); - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = (WXRegion) XCreateRegion (); - XRectangle r; - r.x = XLOG2DEV (x); - r.y = YLOG2DEV (y); - r.width = XLOG2DEVREL(width); - r.height = YLOG2DEVREL(height); - XUnionRectWithRegion (&r, (Region) m_userRegion, (Region) m_userRegion); + wxRegion temp(x, y, width, height); - SetDCClipping (); + SetDCClipping(temp.GetX11Region()); // Needs to work differently for Pixmap: without this, // there's a nasty (Display*) m_display bug. 8/12/94 @@ -2138,7 +2143,8 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo rects[0].y = YLOG2DEV_2(y); rects[0].width = XLOG2DEVREL(width); rects[0].height = YLOG2DEVREL(height); - XSetClipRectangles((Display*) m_display, (GC) m_gcBacking, 0, 0, rects, 1, Unsorted); + XSetClipRectangles((Display*) m_display, (GC) m_gcBacking, + 0, 0, rects, 1, Unsorted); } } @@ -2148,13 +2154,7 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region ) wxDC::DoSetClippingRegion( box.x, box.y, box.width, box.height ); - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = (WXRegion) XCreateRegion (); - - XUnionRegion((Region) m_userRegion, (Region) region.GetXRegion(), (Region) m_userRegion); - - SetDCClipping (); + SetDCClipping(region.GetX11Region()); // Needs to work differently for Pixmap: without this, // there's a nasty (Display*) m_display bug. 8/12/94 @@ -2165,7 +2165,8 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region ) rects[0].y = YLOG2DEV_2(box.y); rects[0].width = XLOG2DEVREL(box.width); rects[0].height = YLOG2DEVREL(box.height); - XSetClipRectangles((Display*) m_display, (GC) m_gcBacking, 0, 0, rects, 1, Unsorted); + XSetClipRectangles((Display*) m_display, (GC) m_gcBacking, + 0, 0, rects, 1, Unsorted); } } @@ -2174,21 +2175,16 @@ void wxWindowDC::DestroyClippingRegion() { wxDC::DestroyClippingRegion(); - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = NULL; + SetDCClipping(NULL); - SetDCClipping (); - - XGCValues gc_val; - gc_val.clip_mask = None; if (m_window && m_window->GetBackingPixmap()) - XChangeGC((Display*) m_display, (GC) m_gcBacking, GCClipMask, &gc_val); + XSetClipMask ((Display*) m_display, (GC) m_gcBacking, None); } // Resolution in pixels per logical inch wxSize wxWindowDC::GetPPI() const { + // TODO return wxSize(100, 100); } @@ -2207,51 +2203,15 @@ int wxWindowDC::GetDepth() const wxPaintDC::wxPaintDC(wxWindow* win) : wxWindowDC(win) { - wxRegion* region = NULL; - - // Combine all the update rects into a region - const wxRectList& updateRects(win->GetUpdateRects()); - if ( updateRects.GetCount() != 0 ) - { - for ( wxRectList::Node *node = updateRects.GetFirst(); - node; - node = node->GetNext() ) - { - wxRect* rect = node->GetData(); - - if (!region) - region = new wxRegion(*rect); - else - // TODO: is this correct? In SetDCClipping above, - // XIntersectRegion is used to combine paint and user - // regions. XIntersectRegion appears to work in that case... - region->Union(*rect); - } - } - else - { - int cw, ch; - win->GetClientSize(&cw, &ch); - region = new wxRegion(wxRect(0, 0, cw, ch)); - } - - win->SetUpdateRegion(*region); - - wxRegion& theRegion(win->GetUpdateRegion()); - theRegion.SetRects(updateRects); // We also store in terms of rects, for iteration to work. - - // Set the clipping region. Any user-defined region will be combined with this - // one in SetDCClipping. - XSetRegion ((Display*) m_display, (GC) m_gc, (Region) region->GetXRegion()); - - delete region; + // Set the clipping region.to the update region + SetDCClipping((WXRegion)NULL); } wxPaintDC::~wxPaintDC() { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); if (m_window) m_window->ClearUpdateRegion(); + SetDCClipping((WXRegion)NULL); } // ---------------------------------------------------------------------------- diff --git a/src/motif/files.lst b/src/motif/files.lst index 2bc3205bfd..91ad6317f6 100644 --- a/src/motif/files.lst +++ b/src/motif/files.lst @@ -216,7 +216,6 @@ ALL_SOURCES = \ motif/palette.cpp \ motif/radiobox.cpp \ motif/radiobut.cpp \ - motif/region.cpp \ motif/scrolbar.cpp \ motif/settings.cpp \ motif/slider.cpp \ @@ -233,6 +232,7 @@ ALL_SOURCES = \ x11/bitmap.cpp \ x11/brush.cpp \ x11/pen.cpp \ + x11/region.cpp \ x11/utilsx.cpp \ unix/dialup.cpp \ unix/dir.cpp \ @@ -545,7 +545,6 @@ ALL_HEADERS = \ motif/private.h \ motif/radiobox.h \ motif/radiobut.h \ - motif/region.h \ motif/scrolbar.h \ motif/settings.h \ motif/slider.h \ @@ -624,7 +623,8 @@ ALL_HEADERS = \ x11/bitmap.h \ x11/brush.h \ x11/pen.h \ - x11/privx.h + x11/privx.h \ + x11/region.h COMMONOBJS = \ accesscmn.o \ @@ -847,7 +847,6 @@ GUIOBJS = \ palette.o \ radiobox.o \ radiobut.o \ - region.o \ scrolbar.o \ settings.o \ slider.o \ @@ -864,6 +863,7 @@ GUIOBJS = \ bitmap.o \ brush.o \ pen.o \ + region.o \ utilsx.o UNIXOBJS = \ diff --git a/src/motif/region.cpp b/src/motif/region.cpp deleted file mode 100644 index 6417ac967e..0000000000 --- a/src/motif/region.cpp +++ /dev/null @@ -1,545 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// File: region.cpp -// Purpose: Region class -// Author: Julian Smart -// Created: Fri Oct 24 10:46:34 MET 1997 -// RCS-ID: $Id$ -// Copyright: (c) 1997 Julian Smart -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifdef __GNUG__ -#pragma implementation "region.h" -#endif - -#include "wx/region.h" -#include "wx/gdicmn.h" - -#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 -//----------------------------------------------------------------------------- - -class WXDLLEXPORT wxRegionRefData : public wxGDIRefData { -public: - 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.GetCount() > 0); - if (m_usingRects) - { - m_rectCount = rectList.GetCount(); - 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 -//----------------------------------------------------------------------------- - -/*! - * Create an empty region. - */ -wxRegion::wxRegion() -{ -} - -wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) -{ - m_refData = new wxRegionRefData; - - 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; - - 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; - - XRectangle rect1; - rect1.x = rect.x; - rect1.y = rect.y; - rect1.width = rect.width; - rect1.height = rect.height; - XUnionRectWithRegion(&rect1, M_REGION, M_REGION); -} - -/*! - * Destroy the region. - */ -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 -//----------------------------------------------------------------------------- - -//! Clear current region -void wxRegion::Clear() -{ - UnRef(); -} - -//! Combine rectangle (x, y, w, h) with this. -bool -wxRegion::Combine(wxCoord x, wxCoord y, - wxCoord width, wxCoord height, - wxRegionOp op) -{ - // work around for XUnionRectWithRegion() bug: taking a union with an empty - // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this - // problem) - if ( op == wxRGN_OR && (!width || !height) ) - return TRUE; - - // 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. - - Region rectRegion = XCreateRegion(); - - XRectangle rect; - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - XUnionRectWithRegion(&rect, rectRegion, rectRegion); - - switch (op) - { - case wxRGN_AND: - XIntersectRegion(M_REGION, rectRegion, M_REGION); - break ; - case wxRGN_OR: - XUnionRegion(M_REGION, rectRegion, M_REGION); - break ; - case wxRGN_XOR: - // TODO - break ; - case wxRGN_DIFF: - // TODO - break ; - case wxRGN_COPY: // Don't have to do this one - default: - // TODO - break ; - } - - 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); - } - - switch (op) - { - case wxRGN_AND: - XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, - M_REGION); - break ; - case wxRGN_OR: - XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, - M_REGION); - break ; - case wxRGN_XOR: - // TODO - break ; - case wxRGN_DIFF: - // TODO - break ; - case wxRGN_COPY: // Don't have to do this one - default: - // TODO - break ; - } - - return FALSE; -} - -bool wxRegion::Combine(const wxRect& rect, wxRegionOp op) -{ - return Combine(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight(), op); -} - -//----------------------------------------------------------------------------- -//# Information on region -//----------------------------------------------------------------------------- - -// Outer bounds of region -void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const -{ - 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 -{ - wxCoord x, y, w, h; - GetBox(x, y, w, h); - return wxRect(x, y, w, h); -} - -// Is region empty? -bool wxRegion::Empty() const -{ - return m_refData ? XEmptyRegion(M_REGION) : TRUE; -} - -//----------------------------------------------------------------------------- -//# Tests -//----------------------------------------------------------------------------- - -// Does the region contain the point (x,y)? -wxRegionContain wxRegion::Contains(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const -{ - if (!m_refData) - return wxOutRegion; - - // TODO. Return wxInRegion if within region. - if (0) - return wxInRegion; - return wxOutRegion; -} - -// Does the region contain the point pt? -wxRegionContain wxRegion::Contains(const wxPoint& pt) const -{ - 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(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const -{ - 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; - - wxCoord x, y, w, h; - x = rect.x; - y = rect.y; - w = rect.GetWidth(); - h = rect.GetHeight(); - 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 // -// // -/////////////////////////////////////////////////////////////////////////////// - -/*! - * Initialize empty iterator - */ -wxRegionIterator::wxRegionIterator() : m_current(0), m_numRects(0), m_rects(NULL) -{ -} - -wxRegionIterator::~wxRegionIterator() -{ - if (m_rects) - delete[] m_rects; -} - -/*! - * Initialize iterator for region - */ -wxRegionIterator::wxRegionIterator(const wxRegion& region) -{ - m_rects = NULL; - - Reset(region); -} - -/*! - * Reset iterator for a new /e region. - */ -void wxRegionIterator::Reset(const wxRegion& region) -{ - m_current = 0; - m_region = region; - - if (m_rects) - delete[] m_rects; - - m_rects = NULL; - - 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(); - } - } -} - -/*! - * Increment iterator. The rectangle returned is the one after the - * incrementation. - */ -void wxRegionIterator::operator ++ () -{ - if (m_current < m_numRects) - ++m_current; -} - -/*! - * Increment iterator. The rectangle returned is the one before the - * incrementation. - */ -void wxRegionIterator::operator ++ (int) -{ - if (m_current < m_numRects) - ++m_current; -} - -wxCoord wxRegionIterator::GetX() const -{ - if (m_current < m_numRects) - return m_rects[m_current].x; - return 0; -} - -wxCoord wxRegionIterator::GetY() const -{ - if (m_current < m_numRects) - return m_rects[m_current].y; - return 0; -} - -wxCoord wxRegionIterator::GetW() const -{ - if (m_current < m_numRects) - return m_rects[m_current].width ; - return 0; -} - -wxCoord wxRegionIterator::GetH() const -{ - if (m_current < m_numRects) - return m_rects[m_current].height; - return 0; -} - diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 2e9b48a49a..abf0b434a0 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -375,8 +375,6 @@ wxWindow::~wxWindow() DetachWidget(wMain); } - ClearUpdateRects(); - if ( m_parent ) m_parent->RemoveChild( this ); @@ -456,120 +454,107 @@ wxWindow::~wxWindow() // scrollbar management // ---------------------------------------------------------------------------- +WXWidget wxWindow::DoCreateScrollBar(WXWidget parent, + wxOrientation orientation, + void (*callback)()) +{ + int orient = ( orientation & wxHORIZONTAL ) ? XmHORIZONTAL : XmVERTICAL; + Widget sb = + XtVaCreateManagedWidget( "scrollBarWidget", + xmScrollBarWidgetClass, (Widget)parent, + XmNorientation, orient, + XmNincrement, 1, + XmNvalue, 0, + NULL ); + + XtPointer o = (XtPointer)orientation; + XtCallbackProc cb = (XtCallbackProc)callback; + + XtAddCallback( sb, XmNvalueChangedCallback, cb, o ); + XtAddCallback( sb, XmNdragCallback, cb, o ); + XtAddCallback( sb, XmNincrementCallback, cb, o ); + XtAddCallback( sb, XmNdecrementCallback, cb, o ); + XtAddCallback( sb, XmNpageIncrementCallback, cb, o ); + XtAddCallback( sb, XmNpageDecrementCallback, cb, o ); + XtAddCallback( sb, XmNtoTopCallback, cb, o ); + XtAddCallback( sb, XmNtoBottomCallback, cb, o ); + + return (WXWidget)sb; +} + // Helper function void wxWindow::CreateScrollbar(wxOrientation orientation) { wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" ); - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL); + XtVaSetValues( (Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_NONE, + NULL ); + wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); // Add scrollbars if required if (orientation == wxHORIZONTAL) { - Widget hScrollBar = XtVaCreateManagedWidget ("hsb", - xmScrollBarWidgetClass, (Widget) m_scrolledWindow, - XmNorientation, XmHORIZONTAL, - NULL); - XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - - XtVaSetValues (hScrollBar, - XmNincrement, 1, - XmNvalue, 0, - NULL); - - m_hScrollBar = (WXWidget) hScrollBar; + m_hScrollBar = DoCreateScrollBar( m_scrolledWindow, wxHORIZONTAL, + (void (*)())wxScrollBarCallback ); - wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE); - XtRealizeWidget(hScrollBar); + XtRealizeWidget( (Widget)m_hScrollBar ); XtVaSetValues((Widget) m_scrolledWindow, XmNhorizontalScrollBar, (Widget) m_hScrollBar, NULL); - wxAddWindowToTable( hScrollBar, this ); + wxAddWindowToTable( (Widget)m_hScrollBar, this ); } - - if (orientation == wxVERTICAL) + else if (orientation == wxVERTICAL) { - Widget vScrollBar = XtVaCreateManagedWidget ("vsb", - xmScrollBarWidgetClass, (Widget) m_scrolledWindow, - XmNorientation, XmVERTICAL, - NULL); - XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - - XtVaSetValues (vScrollBar, - XmNincrement, 1, - XmNvalue, 0, - NULL); + m_vScrollBar = DoCreateScrollBar( m_scrolledWindow, wxVERTICAL, + (void (*)())wxScrollBarCallback ); - m_vScrollBar = (WXWidget) vScrollBar; - wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE); - XtRealizeWidget(vScrollBar); + XtRealizeWidget((Widget)m_vScrollBar); XtVaSetValues((Widget) m_scrolledWindow, XmNverticalScrollBar, (Widget) m_vScrollBar, NULL); - wxAddWindowToTable( vScrollBar, this ); + wxAddWindowToTable( (Widget)m_vScrollBar, this ); } - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL); + XtVaSetValues( (Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_ANY, + NULL ); } void wxWindow::DestroyScrollbar(wxOrientation orientation) { wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" ); - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL); - // Add scrollbars if required - if (orientation == wxHORIZONTAL) - { - if (m_hScrollBar) - { - wxDeleteWindowFromTable((Widget)m_hScrollBar); - XtDestroyWidget((Widget) m_hScrollBar); - } - m_hScrollBar = (WXWidget) 0; - - XtVaSetValues((Widget) m_scrolledWindow, - XmNhorizontalScrollBar, (Widget) 0, - NULL); + XtVaSetValues((Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_NONE, + NULL); + String stringSB = orientation == wxHORIZONTAL ? + XmNhorizontalScrollBar : XmNverticalScrollBar; + WXWidget* widgetSB = orientation == wxHORIZONTAL ? + &m_hScrollBar : &m_vScrollBar; - } - - if (orientation == wxVERTICAL) + if( *widgetSB ) { - if (m_vScrollBar) - { - wxDeleteWindowFromTable((Widget)m_vScrollBar); - XtDestroyWidget((Widget) m_vScrollBar); - } - m_vScrollBar = (WXWidget) 0; + wxDeleteWindowFromTable( (Widget)*widgetSB ); + XtDestroyWidget( (Widget)*widgetSB ); + *widgetSB = (WXWidget)NULL; + } - XtVaSetValues((Widget) m_scrolledWindow, - XmNverticalScrollBar, (Widget) 0, - NULL); + XtVaSetValues( (Widget)m_scrolledWindow, + stringSB, (Widget) 0, + NULL ); - } - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL); + XtVaSetValues((Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_ANY, + NULL); } // --------------------------------------------------------------------------- @@ -1544,6 +1529,11 @@ void wxWindow::GetTextExtent(const wxString& string, // painting // ---------------------------------------------------------------------------- +void wxWindow::AddUpdateRect(int x, int y, int w, int h) +{ + m_updateRegion.Union( x, y, w, h ); +} + void wxWindow::Refresh(bool eraseBack, const wxRect *rect) { m_needsRefresh = TRUE; @@ -1596,19 +1586,6 @@ void wxWindow::Clear() dc.Clear(); } -void wxWindow::ClearUpdateRects() -{ - wxRectList::Node* node = m_updateRects.GetFirst(); - while (node) - { - wxRect* rect = node->GetData(); - delete rect; - node = node->GetNext(); - } - - m_updateRects.Clear(); -} - void wxWindow::DoPaint() { //TODO : make a temporary gc so we can do the XCopyArea below @@ -1975,11 +1952,10 @@ static void wxCanvasRepaintProc(Widget drawingArea, { win->AddUpdateRect(event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height); - + if (event -> xexpose.count == 0) { win->DoPaint(); - win->ClearUpdateRects(); } break; } @@ -2144,7 +2120,7 @@ static void wxScrollBarCallback(Widget scrollbar, XmScrollBarCallbackStruct *cbs) { wxWindow *win = wxGetWindowFromTable(scrollbar); - int orientation = (int) clientData; + wxOrientation orientation = (wxOrientation)(int)clientData; wxEventType eventType = wxEVT_NULL; switch (cbs->reason) @@ -2199,8 +2175,7 @@ static void wxScrollBarCallback(Widget scrollbar, wxScrollWinEvent event(eventType, cbs->value, - ((orientation == XmHORIZONTAL) ? - wxHORIZONTAL : wxVERTICAL)); + orientation); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent(event); } @@ -2222,16 +2197,12 @@ void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, window = (Window) win -> GetXWindow(); display = (Display *) win -> GetXDisplay(); + win->AddUpdateRect(event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (event -> xexpose.count == 0) { win->DoPaint(); - - win->ClearUpdateRects(); - } - else - { - win->AddUpdateRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); } break; -- 2.47.2