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