]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/region.cpp
no message
[wxWidgets.git] / src / gtk / region.cpp
... / ...
CommitLineData
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;
32 wxList m_rects;
33};
34
35wxRegionRefData::wxRegionRefData(void)
36{
37 m_region = (GdkRegion *) NULL;
38}
39
40wxRegionRefData::~wxRegionRefData(void)
41{
42 if (m_region) gdk_region_destroy( m_region );
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 }
51}
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 );
70 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,w,h) );
71}
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 );
84 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(topLeft,bottomRight) );
85}
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 );
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 }
106}
107
108wxRegion::wxRegion(void)
109{
110 m_refData = new wxRegionRefData();
111 M_REGIONDATA->m_region = gdk_region_new();
112}
113
114wxRegion::~wxRegion(void)
115{
116}
117
118void wxRegion::Clear(void)
119{
120 UnRef();
121 m_refData = new wxRegionRefData();
122 M_REGIONDATA->m_region = gdk_region_new();
123}
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;
135 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) );
136 return TRUE;
137}
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;
149 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
150 return TRUE;
151}
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;
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
167 return TRUE;
168}
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;
175}
176
177bool wxRegion::Intersect( const wxRect& rect )
178{
179 wxRegion reg( rect );
180 Intersect( reg );
181 return TRUE;
182}
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;
190}
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;
197}
198
199bool wxRegion::Subtract( const wxRect& rect )
200{
201 wxRegion reg( rect );
202 Subtract( reg );
203 return TRUE;
204}
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;
212}
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;
219}
220
221bool wxRegion::Xor( const wxRect& rect )
222{
223 wxRegion reg( rect );
224 Xor( reg );
225 return TRUE;
226}
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;
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
242 return TRUE;
243}
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;
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 }
285}
286
287wxRect wxRegion::GetBox(void) const
288{
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 );
295}
296
297bool wxRegion::Empty(void) const
298{
299 return gdk_region_empty( M_REGIONDATA->m_region );
300}
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;
308}
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;
323 }
324 return wxOutRegion;
325}
326
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
337GdkRegion *wxRegion::GetRegion(void) const
338{
339 return M_REGIONDATA->m_region;
340}
341
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