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