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
This commit is contained in:
Mattia Barbon
2003-05-24 19:41:05 +00:00
parent 69108ccb4e
commit 148b44a1e7
8 changed files with 166 additions and 788 deletions

View File

@@ -652,7 +652,6 @@ msgdlg.cpp Motif
palette.cpp Motif palette.cpp Motif
radiobox.cpp Motif radiobox.cpp Motif
radiobut.cpp Motif radiobut.cpp Motif
region.cpp Motif
scrolbar.cpp Motif scrolbar.cpp Motif
settings.cpp Motif settings.cpp Motif
slider.cpp Motif slider.cpp Motif
@@ -693,7 +692,7 @@ minifram.cpp X11
palette.cpp X11 palette.cpp X11
pen.cpp X11 Motif pen.cpp X11 Motif
popupwin.cpp X11 popupwin.cpp X11
region.cpp X11 region.cpp X11 Motif
reparent.cpp X11 reparent.cpp X11
settings.cpp X11 settings.cpp X11
toplevel.cpp X11 toplevel.cpp X11
@@ -1273,7 +1272,6 @@ print.h MotifH
private.h MotifH private.h MotifH
radiobox.h MotifH radiobox.h MotifH
radiobut.h MotifH radiobut.h MotifH
region.h MotifH
scrolbar.h MotifH scrolbar.h MotifH
settings.h MotifH settings.h MotifH
slider.h MotifH slider.h MotifH
@@ -1314,7 +1312,7 @@ pen.h X11H Motif
print.h X11H print.h X11H
private.h X11H private.h X11H
privx.h X11H Motif privx.h X11H Motif
region.h X11H region.h X11H Motif
reparent.h X11H reparent.h X11H
textctrl.h X11H textctrl.h X11H
toplevel.h X11H toplevel.h X11H

View File

@@ -78,7 +78,7 @@ public:
virtual void DestroyClippingRegion(); virtual void DestroyClippingRegion();
// Helper function for setting clipping // Helper function for setting clipping
void SetDCClipping(); void SetDCClipping(WXRegion region);
// implementation from now on // implementation from now on
// -------------------------- // --------------------------
@@ -150,15 +150,15 @@ protected:
WXGC m_gcBacking; WXGC m_gcBacking;
WXDisplay* m_display; WXDisplay* m_display;
wxWindow* m_window; wxWindow* m_window;
// Current clipping region (incl. paint clip region) // Pixmap for drawing on
WXRegion m_currentRegion; WXPixmap m_pixmap;
WXRegion m_userRegion; // User-defined clipping region // Last clipping region set on th GC, this is the combination
WXPixmap m_pixmap; // Pixmap for drawing on // of paint clipping region and all user-defined clipping regions
WXRegion m_clipRegion;
// Not sure if we'll need all of these // Not sure if we'll need all of these
int m_backgroundPixel; int m_backgroundPixel;
wxColour m_currentColour; wxColour m_currentColour;
// int m_currentBkMode;
int m_currentPenWidth ; int m_currentPenWidth ;
int m_currentPenJoin ; int m_currentPenJoin ;
int m_currentPenCap ; int m_currentPenCap ;

View File

@@ -142,15 +142,8 @@ public:
// (for wxWindowDC and Motif callbacks only) // (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 // Adds a recangle to the updates list
void AddUpdateRect(int x, int y, int w, int h) 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 ClearUpdateRegion() { m_updateRegion.Clear(); } void ClearUpdateRegion() { m_updateRegion.Clear(); }
void SetUpdateRegion(const wxRegion& region) { m_updateRegion = region; } void SetUpdateRegion(const wxRegion& region) { m_updateRegion = region; }
@@ -189,6 +182,10 @@ protected:
void DoMoveWindowIntr(int x, int y, int width, int height, void DoMoveWindowIntr(int x, int y, int width, int height,
int flags); int flags);
// helper function, to remove duplicate code, used in wxScrollBar
WXWidget DoCreateScrollBar(WXWidget parent, wxOrientation orientation,
void (*callback)());
public: public:
WXPixmap GetBackingPixmap() const { return m_backingPixmap; } WXPixmap GetBackingPixmap() const { return m_backingPixmap; }
void SetBackingPixmap(WXPixmap pixmap) { m_backingPixmap = pixmap; } void SetBackingPixmap(WXPixmap pixmap) { m_backingPixmap = pixmap; }
@@ -265,9 +262,6 @@ protected:
long m_lastTS; // last timestamp long m_lastTS; // last timestamp
unsigned m_lastButton:2; // last pressed button unsigned m_lastButton:2; // last pressed button
// List of wxRects representing damaged region
wxRectList m_updateRects;
protected: protected:
WXWidget m_mainWidget; WXWidget m_mainWidget;
WXWidget m_hScrollBar; WXWidget m_hScrollBar;

View File

@@ -4,7 +4,7 @@
#if defined(__WXMSW__) #if defined(__WXMSW__)
#include "wx/msw/region.h" #include "wx/msw/region.h"
#elif defined(__WXMOTIF__) #elif defined(__WXMOTIF__)
#include "wx/motif/region.h" #include "wx/x11/region.h"
#elif defined(__WXGTK__) #elif defined(__WXGTK__)
#include "wx/gtk/region.h" #include "wx/gtk/region.h"
#elif defined(__WXX11__) #elif defined(__WXX11__)

View File

@@ -140,12 +140,11 @@ void wxWindowDC::Init()
m_currentFill = -1; m_currentFill = -1;
m_colour = wxColourDisplay(); m_colour = wxColourDisplay();
m_display = (WXDisplay*) NULL; m_display = (WXDisplay*) NULL;
m_currentRegion = (WXRegion) 0;
m_userRegion = (WXRegion) 0;
m_pixmap = (WXPixmap) 0; m_pixmap = (WXPixmap) 0;
m_autoSetting = 0; m_autoSetting = 0;
m_oldFont = (WXFont) 0; m_oldFont = (WXFont) 0;
m_ok = false; m_ok = false;
m_clipRegion = (WXRegion) 0;
} }
wxWindowDC::wxWindowDC() wxWindowDC::wxWindowDC()
@@ -215,13 +214,9 @@ wxWindowDC::~wxWindowDC()
XFreeGC ((Display*) m_display, (GC) m_gcBacking); XFreeGC ((Display*) m_display, (GC) m_gcBacking);
m_gcBacking = (WXGC) 0; m_gcBacking = (WXGC) 0;
if (m_currentRegion) if (m_clipRegion)
XDestroyRegion ((Region) m_currentRegion); XDestroyRegion ((Region) m_clipRegion);
m_currentRegion = (WXRegion) 0; m_clipRegion = (WXRegion) 0;
if (m_userRegion)
XDestroyRegion ((Region) m_userRegion);
m_userRegion = (WXRegion) 0;
} }
extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
@@ -788,9 +783,12 @@ bool wxWindowDC::CanDrawBitmap() const
return TRUE; return TRUE;
} }
// TODO: use scaled Blit e.g. as per John Price's implementation in Contrib/Utilities // TODO: use scaled Blit e.g. as per John Price's implementation
bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, // in Contrib/Utilities
wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask, 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 ) wxCoord xsrcMask, wxCoord ysrcMask )
{ {
wxCHECK_MSG( Ok(), FALSE, "invalid dc" ); wxCHECK_MSG( Ok(), FALSE, "invalid dc" );
@@ -912,7 +910,12 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he
if ( useMask ) 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); 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 ) 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); XSetClipOrigin ((Display*) m_display, (GC) m_gc, 0, 0);
} }
@@ -2077,57 +2085,54 @@ void wxWindowDC::SetPalette( const wxPalette& palette )
} }
} }
// Helper function static void wxCopyRegion( WXRegion src, WXRegion& dst )
void wxWindowDC::SetDCClipping()
{ {
// m_userRegion is the region set by calling SetClippingRegion if( !dst )
dst = XCreateRegion();
if (m_currentRegion) XUnionRegion( (Region)src, (Region)src, (Region)dst );
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 (m_currentRegion)
{
XSetRegion ((Display*) m_display, (GC) m_gc, (Region) m_currentRegion);
}
else
{
XSetClipMask ((Display*) m_display, (GC) m_gc, None);
}
} }
void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) // 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 )
{
if( m_clipRegion )
XDestroyRegion( (Region)m_clipRegion );
m_clipRegion = (WXRegion)NULL;
if( hasUpdateRegion )
wxCopyRegion( m_window->GetUpdateRegion().GetX11Region(),
m_clipRegion );
}
// intersect the user region, if any, with the
// exisiting clip region
else // if( userRegion )
{
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 )
{ {
wxDC::DoSetClippingRegion( x, y, width, height ); wxDC::DoSetClippingRegion( x, y, width, height );
if (m_userRegion) wxRegion temp(x, y, width, height);
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);
SetDCClipping (); SetDCClipping(temp.GetX11Region());
// Needs to work differently for Pixmap: without this, // Needs to work differently for Pixmap: without this,
// there's a nasty (Display*) m_display bug. 8/12/94 // 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].y = YLOG2DEV_2(y);
rects[0].width = XLOG2DEVREL(width); rects[0].width = XLOG2DEVREL(width);
rects[0].height = YLOG2DEVREL(height); 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 ); wxDC::DoSetClippingRegion( box.x, box.y, box.width, box.height );
if (m_userRegion) SetDCClipping(region.GetX11Region());
XDestroyRegion ((Region) m_userRegion);
m_userRegion = (WXRegion) XCreateRegion ();
XUnionRegion((Region) m_userRegion, (Region) region.GetXRegion(), (Region) m_userRegion);
SetDCClipping ();
// Needs to work differently for Pixmap: without this, // Needs to work differently for Pixmap: without this,
// there's a nasty (Display*) m_display bug. 8/12/94 // 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].y = YLOG2DEV_2(box.y);
rects[0].width = XLOG2DEVREL(box.width); rects[0].width = XLOG2DEVREL(box.width);
rects[0].height = YLOG2DEVREL(box.height); 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(); wxDC::DestroyClippingRegion();
if (m_userRegion) SetDCClipping(NULL);
XDestroyRegion ((Region) m_userRegion);
m_userRegion = NULL;
SetDCClipping ();
XGCValues gc_val;
gc_val.clip_mask = None;
if (m_window && m_window->GetBackingPixmap()) 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 // Resolution in pixels per logical inch
wxSize wxWindowDC::GetPPI() const wxSize wxWindowDC::GetPPI() const
{ {
// TODO
return wxSize(100, 100); return wxSize(100, 100);
} }
@@ -2207,51 +2203,15 @@ int wxWindowDC::GetDepth() const
wxPaintDC::wxPaintDC(wxWindow* win) : wxWindowDC(win) wxPaintDC::wxPaintDC(wxWindow* win) : wxWindowDC(win)
{ {
wxRegion* region = NULL; // Set the clipping region.to the update region
SetDCClipping((WXRegion)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;
} }
wxPaintDC::~wxPaintDC() wxPaintDC::~wxPaintDC()
{ {
XSetClipMask ((Display*) m_display, (GC) m_gc, None);
if (m_window) if (m_window)
m_window->ClearUpdateRegion(); m_window->ClearUpdateRegion();
SetDCClipping((WXRegion)NULL);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -216,7 +216,6 @@ ALL_SOURCES = \
motif/palette.cpp \ motif/palette.cpp \
motif/radiobox.cpp \ motif/radiobox.cpp \
motif/radiobut.cpp \ motif/radiobut.cpp \
motif/region.cpp \
motif/scrolbar.cpp \ motif/scrolbar.cpp \
motif/settings.cpp \ motif/settings.cpp \
motif/slider.cpp \ motif/slider.cpp \
@@ -233,6 +232,7 @@ ALL_SOURCES = \
x11/bitmap.cpp \ x11/bitmap.cpp \
x11/brush.cpp \ x11/brush.cpp \
x11/pen.cpp \ x11/pen.cpp \
x11/region.cpp \
x11/utilsx.cpp \ x11/utilsx.cpp \
unix/dialup.cpp \ unix/dialup.cpp \
unix/dir.cpp \ unix/dir.cpp \
@@ -545,7 +545,6 @@ ALL_HEADERS = \
motif/private.h \ motif/private.h \
motif/radiobox.h \ motif/radiobox.h \
motif/radiobut.h \ motif/radiobut.h \
motif/region.h \
motif/scrolbar.h \ motif/scrolbar.h \
motif/settings.h \ motif/settings.h \
motif/slider.h \ motif/slider.h \
@@ -624,7 +623,8 @@ ALL_HEADERS = \
x11/bitmap.h \ x11/bitmap.h \
x11/brush.h \ x11/brush.h \
x11/pen.h \ x11/pen.h \
x11/privx.h x11/privx.h \
x11/region.h
COMMONOBJS = \ COMMONOBJS = \
accesscmn.o \ accesscmn.o \
@@ -847,7 +847,6 @@ GUIOBJS = \
palette.o \ palette.o \
radiobox.o \ radiobox.o \
radiobut.o \ radiobut.o \
region.o \
scrolbar.o \ scrolbar.o \
settings.o \ settings.o \
slider.o \ slider.o \
@@ -864,6 +863,7 @@ GUIOBJS = \
bitmap.o \ bitmap.o \
brush.o \ brush.o \
pen.o \ pen.o \
region.o \
utilsx.o utilsx.o
UNIXOBJS = \ UNIXOBJS = \

View File

@@ -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 <Xm/Xm.h>
#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;
}

View File

@@ -375,8 +375,6 @@ wxWindow::~wxWindow()
DetachWidget(wMain); DetachWidget(wMain);
} }
ClearUpdateRects();
if ( m_parent ) if ( m_parent )
m_parent->RemoveChild( this ); m_parent->RemoveChild( this );
@@ -456,120 +454,107 @@ wxWindow::~wxWindow()
// scrollbar management // 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 // Helper function
void wxWindow::CreateScrollbar(wxOrientation orientation) void wxWindow::CreateScrollbar(wxOrientation orientation)
{ {
wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" ); 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 // Add scrollbars if required
if (orientation == wxHORIZONTAL) if (orientation == wxHORIZONTAL)
{ {
Widget hScrollBar = XtVaCreateManagedWidget ("hsb", m_hScrollBar = DoCreateScrollBar( m_scrolledWindow, wxHORIZONTAL,
xmScrollBarWidgetClass, (Widget) m_scrolledWindow, (void (*)())wxScrollBarCallback );
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;
wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE); wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE);
XtRealizeWidget(hScrollBar); XtRealizeWidget( (Widget)m_hScrollBar );
XtVaSetValues((Widget) m_scrolledWindow, XtVaSetValues((Widget) m_scrolledWindow,
XmNhorizontalScrollBar, (Widget) m_hScrollBar, XmNhorizontalScrollBar, (Widget) m_hScrollBar,
NULL); NULL);
wxAddWindowToTable( hScrollBar, this ); wxAddWindowToTable( (Widget)m_hScrollBar, this );
} }
else if (orientation == wxVERTICAL)
if (orientation == wxVERTICAL)
{ {
Widget vScrollBar = XtVaCreateManagedWidget ("vsb", m_vScrollBar = DoCreateScrollBar( m_scrolledWindow, wxVERTICAL,
xmScrollBarWidgetClass, (Widget) m_scrolledWindow, (void (*)())wxScrollBarCallback );
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 = (WXWidget) vScrollBar;
wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE); wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE);
XtRealizeWidget(vScrollBar); XtRealizeWidget((Widget)m_vScrollBar);
XtVaSetValues((Widget) m_scrolledWindow, XtVaSetValues((Widget) m_scrolledWindow,
XmNverticalScrollBar, (Widget) m_vScrollBar, XmNverticalScrollBar, (Widget) m_vScrollBar,
NULL); 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) void wxWindow::DestroyScrollbar(wxOrientation orientation)
{ {
wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" ); wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL); XtVaSetValues((Widget) m_scrolledWindow,
// Add scrollbars if required XmNresizePolicy, XmRESIZE_NONE,
if (orientation == wxHORIZONTAL) NULL);
String stringSB = orientation == wxHORIZONTAL ?
XmNhorizontalScrollBar : XmNverticalScrollBar;
WXWidget* widgetSB = orientation == wxHORIZONTAL ?
&m_hScrollBar : &m_vScrollBar;
if( *widgetSB )
{ {
if (m_hScrollBar) wxDeleteWindowFromTable( (Widget)*widgetSB );
{ XtDestroyWidget( (Widget)*widgetSB );
wxDeleteWindowFromTable((Widget)m_hScrollBar); *widgetSB = (WXWidget)NULL;
XtDestroyWidget((Widget) m_hScrollBar);
}
m_hScrollBar = (WXWidget) 0;
XtVaSetValues((Widget) m_scrolledWindow,
XmNhorizontalScrollBar, (Widget) 0,
NULL);
} }
if (orientation == wxVERTICAL) XtVaSetValues( (Widget)m_scrolledWindow,
{ stringSB, (Widget) 0,
if (m_vScrollBar) NULL );
{
wxDeleteWindowFromTable((Widget)m_vScrollBar);
XtDestroyWidget((Widget) m_vScrollBar);
}
m_vScrollBar = (WXWidget) 0;
XtVaSetValues((Widget) m_scrolledWindow, XtVaSetValues((Widget) m_scrolledWindow,
XmNverticalScrollBar, (Widget) 0, XmNresizePolicy, XmRESIZE_ANY,
NULL); NULL);
}
XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -1544,6 +1529,11 @@ void wxWindow::GetTextExtent(const wxString& string,
// painting // 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) void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
{ {
m_needsRefresh = TRUE; m_needsRefresh = TRUE;
@@ -1596,19 +1586,6 @@ void wxWindow::Clear()
dc.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() void wxWindow::DoPaint()
{ {
//TODO : make a temporary gc so we can do the XCopyArea below //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, win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height); event->xexpose.width, event->xexpose.height);
if (event -> xexpose.count == 0) if (event -> xexpose.count == 0)
{ {
win->DoPaint(); win->DoPaint();
win->ClearUpdateRects();
} }
break; break;
} }
@@ -2144,7 +2120,7 @@ static void wxScrollBarCallback(Widget scrollbar,
XmScrollBarCallbackStruct *cbs) XmScrollBarCallbackStruct *cbs)
{ {
wxWindow *win = wxGetWindowFromTable(scrollbar); wxWindow *win = wxGetWindowFromTable(scrollbar);
int orientation = (int) clientData; wxOrientation orientation = (wxOrientation)(int)clientData;
wxEventType eventType = wxEVT_NULL; wxEventType eventType = wxEVT_NULL;
switch (cbs->reason) switch (cbs->reason)
@@ -2199,8 +2175,7 @@ static void wxScrollBarCallback(Widget scrollbar,
wxScrollWinEvent event(eventType, wxScrollWinEvent event(eventType,
cbs->value, cbs->value,
((orientation == XmHORIZONTAL) ? orientation);
wxHORIZONTAL : wxVERTICAL));
event.SetEventObject( win ); event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent(event); win->GetEventHandler()->ProcessEvent(event);
} }
@@ -2222,16 +2197,12 @@ void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event,
window = (Window) win -> GetXWindow(); window = (Window) win -> GetXWindow();
display = (Display *) win -> GetXDisplay(); display = (Display *) win -> GetXDisplay();
win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height);
if (event -> xexpose.count == 0) if (event -> xexpose.count == 0)
{ {
win->DoPaint(); win->DoPaint();
win->ClearUpdateRects();
}
else
{
win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height);
} }
break; break;