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