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