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
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

View File

@@ -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 ;

View File

@@ -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;

View File

@@ -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__)

View File

@@ -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 (m_currentRegion)
{
XSetRegion ((Display*) m_display, (GC) m_gc, (Region) m_currentRegion);
}
else
{
XSetClipMask ((Display*) m_display, (GC) m_gc, None);
}
if( !dst )
dst = XCreateRegion();
XUnionRegion( (Region)src, (Region)src, (Region)dst );
}
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 );
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);
}
// ----------------------------------------------------------------------------

View File

@@ -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 = \

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);
}
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);
m_hScrollBar = DoCreateScrollBar( m_scrolledWindow, wxHORIZONTAL,
(void (*)())wxScrollBarCallback );
XtVaSetValues (hScrollBar,
XmNincrement, 1,
XmNvalue, 0,
NULL);
m_hScrollBar = (WXWidget) hScrollBar;
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);
m_vScrollBar = DoCreateScrollBar( m_scrolledWindow, wxVERTICAL,
(void (*)())wxScrollBarCallback );
XtVaSetValues (vScrollBar,
XmNincrement, 1,
XmNvalue, 0,
NULL);
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)
XtVaSetValues((Widget) m_scrolledWindow,
XmNresizePolicy, XmRESIZE_NONE,
NULL);
String stringSB = orientation == wxHORIZONTAL ?
XmNhorizontalScrollBar : XmNverticalScrollBar;
WXWidget* widgetSB = orientation == wxHORIZONTAL ?
&m_hScrollBar : &m_vScrollBar;
if( *widgetSB )
{
if (m_hScrollBar)
{
wxDeleteWindowFromTable((Widget)m_hScrollBar);
XtDestroyWidget((Widget) m_hScrollBar);
}
m_hScrollBar = (WXWidget) 0;
XtVaSetValues((Widget) m_scrolledWindow,
XmNhorizontalScrollBar, (Widget) 0,
NULL);
wxDeleteWindowFromTable( (Widget)*widgetSB );
XtDestroyWidget( (Widget)*widgetSB );
*widgetSB = (WXWidget)NULL;
}
if (orientation == wxVERTICAL)
{
if (m_vScrollBar)
{
wxDeleteWindowFromTable((Widget)m_vScrollBar);
XtDestroyWidget((Widget) m_vScrollBar);
}
m_vScrollBar = (WXWidget) 0;
XtVaSetValues( (Widget)m_scrolledWindow,
stringSB, (Widget) 0,
NULL );
XtVaSetValues((Widget) m_scrolledWindow,
XmNverticalScrollBar, (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;