Header changes (gtk.h etc no longer included in defs.h
[wxWidgets.git] / src / gtk1 / region.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: region.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10
11 #ifdef __GNUG__
12 #pragma implementation "region.h"
13 #endif
14
15 #include "wx/region.h"
16
17 #include "gdk/gdk.h"
18 #include "gtk/gtk.h"
19
20 //-----------------------------------------------------------------------------
21 // wxRegion
22 //-----------------------------------------------------------------------------
23
24 class wxRegionRefData: public wxObjectRefData
25 {
26 public:
27
28 wxRegionRefData(void);
29 ~wxRegionRefData(void);
30
31 public:
32
33 GdkRegion *m_region;
34 wxList m_rects;
35 };
36
37 wxRegionRefData::wxRegionRefData(void)
38 {
39 m_region = (GdkRegion *) NULL;
40 }
41
42 wxRegionRefData::~wxRegionRefData(void)
43 {
44 if (m_region) gdk_region_destroy( m_region );
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 }
53 }
54
55 //-----------------------------------------------------------------------------
56
57 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
58
59 IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject);
60
61 wxRegion::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 );
72 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,w,h) );
73 }
74
75 wxRegion::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 );
86 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(topLeft,bottomRight) );
87 }
88
89 wxRegion::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 );
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 }
108 }
109
110 wxRegion::wxRegion(void)
111 {
112 m_refData = new wxRegionRefData();
113 M_REGIONDATA->m_region = gdk_region_new();
114 }
115
116 wxRegion::~wxRegion(void)
117 {
118 }
119
120 bool wxRegion::operator == ( const wxRegion& region )
121 {
122 return m_refData == region.m_refData;
123 }
124
125 bool wxRegion::operator != ( const wxRegion& region )
126 {
127 return m_refData != region.m_refData;
128 }
129
130 void wxRegion::Clear(void)
131 {
132 UnRef();
133 m_refData = new wxRegionRefData();
134 M_REGIONDATA->m_region = gdk_region_new();
135 }
136
137 bool 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;
147 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) );
148 return TRUE;
149 }
150
151 bool 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;
161 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
162 return TRUE;
163 }
164
165 bool 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;
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
179 return TRUE;
180 }
181
182 bool wxRegion::Intersect( long x, long y, long width, long height )
183 {
184 wxRegion reg( x, y, width, height );
185 Intersect( reg );
186 return TRUE;
187 }
188
189 bool wxRegion::Intersect( const wxRect& rect )
190 {
191 wxRegion reg( rect );
192 Intersect( reg );
193 return TRUE;
194 }
195
196 bool 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;
202 }
203
204 bool wxRegion::Subtract( long x, long y, long width, long height )
205 {
206 wxRegion reg( x, y, width, height );
207 Subtract( reg );
208 return TRUE;
209 }
210
211 bool wxRegion::Subtract( const wxRect& rect )
212 {
213 wxRegion reg( rect );
214 Subtract( reg );
215 return TRUE;
216 }
217
218 bool 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;
224 }
225
226 bool wxRegion::Xor( long x, long y, long width, long height )
227 {
228 wxRegion reg( x, y, width, height );
229 Xor( reg );
230 return TRUE;
231 }
232
233 bool wxRegion::Xor( const wxRect& rect )
234 {
235 wxRegion reg( rect );
236 Xor( reg );
237 return TRUE;
238 }
239
240 bool 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;
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
254 return TRUE;
255 }
256
257 void wxRegion::GetBox( long& x, long& y, long&w, long &h ) const
258 {
259 x = 0;
260 y = 0;
261 w = -1;
262 h = -1;
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 }
297 }
298
299 wxRect wxRegion::GetBox(void) const
300 {
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 );
307 }
308
309 bool wxRegion::Empty(void) const
310 {
311 return gdk_region_empty( M_REGIONDATA->m_region );
312 }
313
314 wxRegionContain 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;
320 }
321
322 wxRegionContain 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;
335 }
336 return wxOutRegion;
337 }
338
339 wxRegionContain wxRegion::Contains(const wxPoint& pt) const
340 {
341 return Contains( pt.x, pt.y );
342 }
343
344 wxRegionContain wxRegion::Contains(const wxRect& rect) const
345 {
346 return Contains( rect.x, rect.y, rect.width, rect.height );
347 }
348
349 GdkRegion *wxRegion::GetRegion(void) const
350 {
351 return M_REGIONDATA->m_region;
352 }
353
354 wxList *wxRegion::GetRectList() const
355 {
356 return &(M_REGIONDATA->m_rects);
357 }
358
359 //-----------------------------------------------------------------------------
360 // wxRegion
361 //-----------------------------------------------------------------------------
362
363 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject);
364
365 wxRegionIterator::wxRegionIterator(void)
366 {
367 m_current = 0;
368 }
369
370 wxRegionIterator::wxRegionIterator( const wxRegion& region )
371 {
372 m_region = region;
373 m_current = 0;
374 }
375
376 void wxRegionIterator::Reset( const wxRegion& region )
377 {
378 m_region = region;
379 m_current = 0;
380 }
381
382 wxRegionIterator::operator bool (void) const
383 {
384 return m_current < m_region.GetRectList()->Number();
385 }
386
387 bool wxRegionIterator::HaveRects(void) const
388 {
389 return m_current < m_region.GetRectList()->Number();
390 }
391
392 void wxRegionIterator::operator ++ (void)
393 {
394 if (m_current < m_region.GetRectList()->Number()) ++m_current;
395 }
396
397 void wxRegionIterator::operator ++ (int)
398 {
399 if (m_current < m_region.GetRectList()->Number()) ++m_current;
400 }
401
402 long 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
410 long 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
418 long 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
426 long 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