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