]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/region.cpp
Ops
[wxWidgets.git] / src / gtk1 / region.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
5fc7ede9 2// Name: gtk/region.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
f96aa4d9
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
5fc7ede9 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
c801d85f
KB
10#ifdef __GNUG__
11#pragma implementation "region.h"
12#endif
13
14#include "wx/region.h"
15
aed8ac3f
RR
16#include <gdk/gdk.h>
17#include <gtk/gtk.h>
bbe0af5b 18
864e8bd0 19
c801d85f
KB
20//-----------------------------------------------------------------------------
21// wxRegion
22//-----------------------------------------------------------------------------
23
24class wxRegionRefData: public wxObjectRefData
25{
864e8bd0 26public:
bf57d1ad
VZ
27 wxRegionRefData();
28 ~wxRegionRefData();
5fc7ede9 29
c801d85f 30 GdkRegion *m_region;
8429bec1 31 wxList m_rects;
c801d85f
KB
32};
33
bf57d1ad 34wxRegionRefData::wxRegionRefData()
c801d85f 35{
bbe0af5b 36 m_region = (GdkRegion *) NULL;
ff7b1510 37}
c801d85f 38
bf57d1ad 39wxRegionRefData::~wxRegionRefData()
c801d85f 40{
bbe0af5b 41 if (m_region) gdk_region_destroy( m_region );
5fc7ede9 42
bbe0af5b
RR
43 wxNode *node = m_rects.First();
44 while (node)
45 {
46 wxRect *r = (wxRect*)node->Data();
47 delete r;
48 node = node->Next();
49 }
ff7b1510 50}
c801d85f
KB
51
52//-----------------------------------------------------------------------------
53
54#define M_REGIONDATA ((wxRegionRefData *)m_refData)
55
56IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject);
5fc7ede9
VZ
57
58wxRegion::wxRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
c801d85f 59{
bbe0af5b
RR
60 m_refData = new wxRegionRefData();
61 GdkRegion *reg = gdk_region_new();
62 GdkRectangle rect;
63 rect.x = x;
64 rect.y = y;
65 rect.width = w;
66 rect.height = h;
67 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
68 gdk_region_destroy( reg );
69 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,w,h) );
ff7b1510 70}
c801d85f
KB
71
72wxRegion::wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight )
73{
bbe0af5b
RR
74 m_refData = new wxRegionRefData();
75 GdkRegion *reg = gdk_region_new();
76 GdkRectangle rect;
77 rect.x = topLeft.x;
78 rect.y = topLeft.y;
79 rect.width = bottomRight.x - rect.x;
80 rect.height = bottomRight.y - rect.y;
81 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
82 gdk_region_destroy( reg );
83 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(topLeft,bottomRight) );
ff7b1510 84}
c801d85f
KB
85
86wxRegion::wxRegion( const wxRect& rect )
87{
bbe0af5b
RR
88 m_refData = new wxRegionRefData();
89 GdkRegion *reg = gdk_region_new();
90 GdkRectangle g_rect;
91 g_rect.x = rect.x;
92 g_rect.y = rect.y;
93 g_rect.width = rect.width;
94 g_rect.height = rect.height;
95 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &g_rect );
96 gdk_region_destroy( reg );
5fc7ede9 97
bbe0af5b
RR
98 wxNode *node = M_REGIONDATA->m_rects.First();
99 while (node)
100 {
101 wxRect *r = (wxRect*)node->Data();
102 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
103 node = node->Next();
104 }
ff7b1510 105}
c801d85f 106
bf57d1ad 107wxRegion::wxRegion()
c801d85f 108{
bbe0af5b
RR
109 m_refData = new wxRegionRefData();
110 M_REGIONDATA->m_region = gdk_region_new();
ff7b1510 111}
c801d85f 112
bf57d1ad 113wxRegion::~wxRegion()
c801d85f 114{
ff7b1510 115}
c801d85f 116
76ed8f8d
RR
117bool wxRegion::operator == ( const wxRegion& region )
118{
5fc7ede9 119 return m_refData == region.m_refData;
76ed8f8d
RR
120}
121
122bool wxRegion::operator != ( const wxRegion& region )
123{
5fc7ede9 124 return m_refData != region.m_refData;
76ed8f8d
RR
125}
126
bf57d1ad 127void wxRegion::Clear()
c801d85f 128{
bbe0af5b
RR
129 UnRef();
130 m_refData = new wxRegionRefData();
131 M_REGIONDATA->m_region = gdk_region_new();
ff7b1510 132}
c801d85f 133
5fc7ede9 134bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 135{
bbe0af5b
RR
136 GdkRectangle rect;
137 rect.x = x;
138 rect.y = y;
139 rect.width = width;
140 rect.height = height;
141 GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
142 gdk_region_destroy( M_REGIONDATA->m_region );
143 M_REGIONDATA->m_region = reg;
144 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) );
145 return TRUE;
ff7b1510 146}
c801d85f
KB
147
148bool wxRegion::Union( const wxRect& rect )
149{
bbe0af5b
RR
150 GdkRectangle g_rect;
151 g_rect.x = rect.x;
152 g_rect.y = rect.y;
153 g_rect.width = rect.width;
154 g_rect.height = rect.height;
155 GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &g_rect );
156 gdk_region_destroy( M_REGIONDATA->m_region );
157 M_REGIONDATA->m_region = reg;
158 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
159 return TRUE;
ff7b1510 160}
c801d85f
KB
161
162bool wxRegion::Union( const wxRegion& region )
163{
bbe0af5b
RR
164 GdkRegion *reg = gdk_regions_union( M_REGIONDATA->m_region, region.GetRegion() );
165 gdk_region_destroy( M_REGIONDATA->m_region );
166 M_REGIONDATA->m_region = reg;
5fc7ede9 167
bbe0af5b
RR
168 wxNode *node = region.GetRectList()->First();
169 while (node)
170 {
171 wxRect *r = (wxRect*)node->Data();
172 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
173 node = node->Next();
174 }
5fc7ede9 175
bbe0af5b 176 return TRUE;
ff7b1510 177}
c801d85f 178
5fc7ede9 179bool wxRegion::Intersect( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 180{
bbe0af5b
RR
181 wxRegion reg( x, y, width, height );
182 Intersect( reg );
183 return TRUE;
ff7b1510 184}
c801d85f
KB
185
186bool wxRegion::Intersect( const wxRect& rect )
187{
bbe0af5b
RR
188 wxRegion reg( rect );
189 Intersect( reg );
190 return TRUE;
ff7b1510 191}
c801d85f
KB
192
193bool wxRegion::Intersect( const wxRegion& region )
194{
bbe0af5b
RR
195 GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
196 gdk_region_destroy( M_REGIONDATA->m_region );
197 M_REGIONDATA->m_region = reg;
198 return TRUE;
ff7b1510 199}
c801d85f 200
5fc7ede9 201bool wxRegion::Subtract( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 202{
bbe0af5b
RR
203 wxRegion reg( x, y, width, height );
204 Subtract( reg );
205 return TRUE;
ff7b1510 206}
c801d85f
KB
207
208bool wxRegion::Subtract( const wxRect& rect )
209{
bbe0af5b
RR
210 wxRegion reg( rect );
211 Subtract( reg );
212 return TRUE;
ff7b1510 213}
c801d85f
KB
214
215bool wxRegion::Subtract( const wxRegion& region )
216{
bbe0af5b
RR
217 GdkRegion *reg = gdk_regions_subtract( M_REGIONDATA->m_region, region.GetRegion() );
218 gdk_region_destroy( M_REGIONDATA->m_region );
219 M_REGIONDATA->m_region = reg;
220 return TRUE;
ff7b1510 221}
c801d85f 222
5fc7ede9 223bool wxRegion::Xor( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 224{
bbe0af5b
RR
225 wxRegion reg( x, y, width, height );
226 Xor( reg );
227 return TRUE;
ff7b1510 228}
c801d85f
KB
229
230bool wxRegion::Xor( const wxRect& rect )
231{
bbe0af5b
RR
232 wxRegion reg( rect );
233 Xor( reg );
234 return TRUE;
ff7b1510 235}
c801d85f
KB
236
237bool wxRegion::Xor( const wxRegion& region )
238{
bbe0af5b
RR
239 GdkRegion *reg = gdk_regions_xor( M_REGIONDATA->m_region, region.GetRegion() );
240 gdk_region_destroy( M_REGIONDATA->m_region );
241 M_REGIONDATA->m_region = reg;
5fc7ede9 242
bbe0af5b
RR
243 wxNode *node = region.GetRectList()->First();
244 while (node)
245 {
246 wxRect *r = (wxRect*)node->Data();
247 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
248 node = node->Next();
249 }
5fc7ede9 250
bbe0af5b 251 return TRUE;
ff7b1510 252}
c801d85f 253
5fc7ede9 254void wxRegion::GetBox( wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h ) const
c801d85f 255{
bbe0af5b
RR
256 x = 0;
257 y = 0;
258 w = -1;
259 h = -1;
864e8bd0
RR
260 GdkRectangle rect;
261 gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect );
262 x = rect.x;
263 y = rect.y;
264 w = rect.width;
265 h = rect.height;
ff7b1510 266}
c801d85f 267
bf57d1ad 268wxRect wxRegion::GetBox() const
c801d85f 269{
5fc7ede9
VZ
270 wxCoord x = 0;
271 wxCoord y = 0;
272 wxCoord w = -1;
273 wxCoord h = -1;
bbe0af5b
RR
274 GetBox( x, y, w, h );
275 return wxRect( x, y, w, h );
ff7b1510 276}
c801d85f 277
bf57d1ad 278bool wxRegion::Empty() const
c801d85f 279{
bbe0af5b 280 return gdk_region_empty( M_REGIONDATA->m_region );
ff7b1510 281}
c801d85f 282
5fc7ede9 283wxRegionContain wxRegion::Contains( wxCoord x, wxCoord y ) const
c801d85f 284{
bbe0af5b
RR
285 if (gdk_region_point_in( M_REGIONDATA->m_region, x, y ))
286 return wxInRegion;
287 else
288 return wxOutRegion;
ff7b1510 289}
c801d85f 290
5fc7ede9 291wxRegionContain wxRegion::Contains( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) const
c801d85f 292{
bbe0af5b
RR
293 GdkRectangle rect;
294 rect.x = x;
295 rect.y = y;
296 rect.width = w;
297 rect.height = h;
298 GdkOverlapType res = gdk_region_rect_in( M_REGIONDATA->m_region, &rect );
299 switch (res)
300 {
301 case GDK_OVERLAP_RECTANGLE_IN: return wxInRegion;
302 case GDK_OVERLAP_RECTANGLE_OUT: return wxOutRegion;
303 case GDK_OVERLAP_RECTANGLE_PART: return wxPartRegion;
304 }
305 return wxOutRegion;
ff7b1510 306}
c801d85f 307
8429bec1
RR
308wxRegionContain wxRegion::Contains(const wxPoint& pt) const
309{
bbe0af5b 310 return Contains( pt.x, pt.y );
8429bec1
RR
311}
312
313wxRegionContain wxRegion::Contains(const wxRect& rect) const
314{
bbe0af5b 315 return Contains( rect.x, rect.y, rect.width, rect.height );
8429bec1
RR
316}
317
bf57d1ad 318GdkRegion *wxRegion::GetRegion() const
c801d85f 319{
bbe0af5b 320 return M_REGIONDATA->m_region;
ff7b1510 321}
c801d85f 322
8429bec1
RR
323wxList *wxRegion::GetRectList() const
324{
bbe0af5b 325 return &(M_REGIONDATA->m_rects);
8429bec1
RR
326}
327
328//-----------------------------------------------------------------------------
329// wxRegion
330//-----------------------------------------------------------------------------
331
332IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject);
5fc7ede9 333
bf57d1ad 334wxRegionIterator::wxRegionIterator()
8429bec1 335{
6f2a55e3 336 Reset();
8429bec1
RR
337}
338
339wxRegionIterator::wxRegionIterator( const wxRegion& region )
340{
6f2a55e3 341 Reset(region);
8429bec1
RR
342}
343
344void wxRegionIterator::Reset( const wxRegion& region )
345{
bbe0af5b 346 m_region = region;
6f2a55e3 347 Reset();
8429bec1
RR
348}
349
5fc7ede9
VZ
350wxRegionIterator::operator bool () const
351{
674ac8b9 352 return m_current < (size_t)m_region.GetRectList()->Number();
8429bec1
RR
353}
354
5fc7ede9
VZ
355bool wxRegionIterator::HaveRects() const
356{
674ac8b9 357 return m_current < (size_t)m_region.GetRectList()->Number();
8429bec1
RR
358}
359
bf57d1ad 360void wxRegionIterator::operator ++ ()
8429bec1 361{
674ac8b9 362 if (m_current < (size_t)m_region.GetRectList()->Number()) ++m_current;
8429bec1
RR
363}
364
365void wxRegionIterator::operator ++ (int)
366{
674ac8b9 367 if (m_current < (size_t)m_region.GetRectList()->Number()) ++m_current;
8429bec1
RR
368}
369
bf57d1ad 370wxCoord wxRegionIterator::GetX() const
8429bec1 371{
bbe0af5b
RR
372 wxNode *node = m_region.GetRectList()->Nth( m_current );
373 if (!node) return 0;
374 wxRect *r = (wxRect*)node->Data();
375 return r->x;
8429bec1
RR
376}
377
bf57d1ad 378wxCoord wxRegionIterator::GetY() const
8429bec1 379{
bbe0af5b
RR
380 wxNode *node = m_region.GetRectList()->Nth( m_current );
381 if (!node) return 0;
382 wxRect *r = (wxRect*)node->Data();
383 return r->y;
8429bec1
RR
384}
385
bf57d1ad 386wxCoord wxRegionIterator::GetW() const
8429bec1 387{
bbe0af5b
RR
388 wxNode *node = m_region.GetRectList()->Nth( m_current );
389 if (!node) return 0;
390 wxRect *r = (wxRect*)node->Data();
391 return r->width;
8429bec1
RR
392}
393
bf57d1ad 394wxCoord wxRegionIterator::GetH() const
8429bec1 395{
bbe0af5b
RR
396 wxNode *node = m_region.GetRectList()->Nth( m_current );
397 if (!node) return 0;
398 wxRect *r = (wxRect*)node->Data();
399 return r->height;
8429bec1
RR
400}
401
402