]> git.saurik.com Git - wxWidgets.git/blame - src/mac/region.cpp
added carbon events for navigation keys, size corrections
[wxWidgets.git] / src / mac / region.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// File: region.cpp
3// Purpose: Region class
4// Author: Markus Holzem/Julian Smart/AUTHOR
5// Created: Fri Oct 24 10:46:34 MET 1997
6// RCS-ID: $Id$
7// Copyright: (c) 1997 Markus Holzem/Julian Smart/AUTHOR
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifdef __GNUG__
12#pragma implementation "region.h"
13#endif
14
15#include "wx/region.h"
16#include "wx/gdicmn.h"
2f1ae414 17#include "wx/mac/uma.h"
e9576ca5 18
2f1ae414 19#if !USE_SHARED_LIBRARY
e9576ca5
SC
20 IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
21 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
2f1ae414 22#endif
e9576ca5
SC
23
24//-----------------------------------------------------------------------------
25// wxRegionRefData implementation
26//-----------------------------------------------------------------------------
27
28class WXDLLEXPORT wxRegionRefData : public wxGDIRefData {
29public:
e7600a2c
GD
30 wxRegionRefData()
31 {
32 m_macRgn = NewRgn() ;
33 }
e9576ca5 34
e7600a2c
GD
35 wxRegionRefData(const wxRegionRefData& data)
36 : wxGDIRefData()
37 {
38 m_macRgn = NewRgn() ;
519cb848 39 CopyRgn( data.m_macRgn , m_macRgn ) ;
e7600a2c 40 }
e9576ca5 41
e7600a2c
GD
42 ~wxRegionRefData()
43 {
519cb848 44 DisposeRgn( m_macRgn ) ;
e7600a2c
GD
45 }
46 RgnHandle m_macRgn ;
e9576ca5
SC
47};
48
519cb848
SC
49#define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn)
50#define OTHER_M_REGION(a) (((wxRegionRefData*)(a.m_refData))->m_macRgn)
e9576ca5
SC
51
52//-----------------------------------------------------------------------------
53// wxRegion
54//-----------------------------------------------------------------------------
55
56/*!
57 * Create an empty region.
58 */
59wxRegion::wxRegion()
60{
61 m_refData = new wxRegionRefData;
519cb848
SC
62}
63
64wxRegion::wxRegion(WXHRGN hRegion )
65{
66 m_refData = new wxRegionRefData;
76a5e5d2 67 CopyRgn( (RgnHandle) hRegion , (RgnHandle) M_REGION ) ;
e9576ca5
SC
68}
69
70wxRegion::wxRegion(long x, long y, long w, long h)
71{
72 m_refData = new wxRegionRefData;
76a5e5d2 73 SetRectRgn( (RgnHandle) M_REGION , x , y , x+w , y+h ) ;
e9576ca5
SC
74}
75
76wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
77{
78 m_refData = new wxRegionRefData;
76a5e5d2 79 SetRectRgn( (RgnHandle) M_REGION , topLeft.x , topLeft.y , bottomRight.x , bottomRight.y ) ;
e9576ca5
SC
80}
81
82wxRegion::wxRegion(const wxRect& rect)
83{
84 m_refData = new wxRegionRefData;
76a5e5d2 85 SetRectRgn( (RgnHandle) M_REGION , rect.x , rect.y , rect.x+rect.width , rect.y+rect.height ) ;
e9576ca5
SC
86}
87
88/*!
89 * Destroy the region.
90 */
91wxRegion::~wxRegion()
92{
93 // m_refData unrefed in ~wxObject
94}
95
96//-----------------------------------------------------------------------------
97//# Modify region
98//-----------------------------------------------------------------------------
99
100//! Clear current region
101void wxRegion::Clear()
102{
103 UnRef();
104}
105
106//! Combine rectangle (x, y, w, h) with this.
107bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
108{
109 // Don't change shared data
519cb848
SC
110 if (!m_refData)
111 {
e9576ca5 112 m_refData = new wxRegionRefData();
519cb848
SC
113 }
114 else if (m_refData->GetRefCount() > 1)
115 {
e9576ca5
SC
116 wxRegionRefData* ref = (wxRegionRefData*)m_refData;
117 UnRef();
118 m_refData = new wxRegionRefData(*ref);
119 }
519cb848
SC
120 RgnHandle rgn = NewRgn() ;
121 SetRectRgn( rgn , x , y, x+width,y + height ) ;
122
e9576ca5
SC
123 switch (op)
124 {
125 case wxRGN_AND:
519cb848 126 SectRgn( M_REGION , rgn , M_REGION ) ;
e9576ca5
SC
127 break ;
128 case wxRGN_OR:
519cb848 129 UnionRgn( M_REGION , rgn , M_REGION ) ;
e9576ca5
SC
130 break ;
131 case wxRGN_XOR:
519cb848 132 XorRgn( M_REGION , rgn , M_REGION ) ;
e9576ca5
SC
133 break ;
134 case wxRGN_DIFF:
519cb848 135 DiffRgn( M_REGION , rgn , M_REGION ) ;
e9576ca5
SC
136 break ;
137 case wxRGN_COPY:
138 default:
519cb848 139 CopyRgn( rgn ,M_REGION ) ;
e9576ca5
SC
140 break ;
141 }
142
519cb848 143 DisposeRgn( rgn ) ;
e9576ca5 144
519cb848 145 return TRUE;
e9576ca5
SC
146}
147
148//! Union /e region with this.
149bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
150{
151 if (region.Empty())
152 return FALSE;
153
154 // Don't change shared data
155 if (!m_refData) {
156 m_refData = new wxRegionRefData();
519cb848
SC
157 }
158 else if (m_refData->GetRefCount() > 1)
159 {
e9576ca5
SC
160 wxRegionRefData* ref = (wxRegionRefData*)m_refData;
161 UnRef();
162 m_refData = new wxRegionRefData(*ref);
163 }
164
e9576ca5
SC
165 switch (op)
166 {
167 case wxRGN_AND:
519cb848 168 SectRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
e9576ca5
SC
169 break ;
170 case wxRGN_OR:
519cb848 171 UnionRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
e9576ca5
SC
172 break ;
173 case wxRGN_XOR:
519cb848 174 XorRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
e9576ca5
SC
175 break ;
176 case wxRGN_DIFF:
519cb848 177 DiffRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
e9576ca5
SC
178 break ;
179 case wxRGN_COPY:
180 default:
519cb848 181 CopyRgn( OTHER_M_REGION(region) ,M_REGION ) ;
e9576ca5
SC
182 break ;
183 }
184
519cb848 185 return TRUE;
e9576ca5
SC
186}
187
188bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
189{
190 return Combine(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight(), op);
191}
192
193//-----------------------------------------------------------------------------
194//# Information on region
195//-----------------------------------------------------------------------------
196
197// Outer bounds of region
c0cd186f 198void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord& w, wxCoord& h) const
e9576ca5 199{
519cb848
SC
200 if (m_refData)
201 {
2f1ae414
SC
202 Rect box ;
203 GetRegionBounds( M_REGION , &box ) ;
519cb848
SC
204 x = box.left ;
205 y = box.top ;
206 w = box.right - box.left ;
207 h = box.bottom - box.top ;
208 }
209 else
210 {
e9576ca5
SC
211 x = y = w = h = 0;
212 }
213}
214
215wxRect wxRegion::GetBox() const
216{
c0cd186f 217 wxCoord x, y, w, h;
e9576ca5
SC
218 GetBox(x, y, w, h);
219 return wxRect(x, y, w, h);
220}
221
222// Is region empty?
223bool wxRegion::Empty() const
224{
519cb848
SC
225 return EmptyRgn( M_REGION ) ;
226}
227
228const WXHRGN wxRegion::GetWXHRGN() const
229{
230 return M_REGION ;
e9576ca5
SC
231}
232
233//-----------------------------------------------------------------------------
234//# Tests
235//-----------------------------------------------------------------------------
236
237// Does the region contain the point (x,y)?
238wxRegionContain wxRegion::Contains(long x, long y) const
239{
240 if (!m_refData)
241 return wxOutRegion;
242
243 // TODO. Return wxInRegion if within region.
244 if (0)
245 return wxInRegion;
246 return wxOutRegion;
247}
248
249// Does the region contain the point pt?
250wxRegionContain wxRegion::Contains(const wxPoint& pt) const
251{
252 if (!m_refData)
253 return wxOutRegion;
254
519cb848
SC
255 Point p = { pt.y , pt.x } ;
256 if (PtInRgn( p , M_REGION ) )
e9576ca5 257 return wxInRegion;
519cb848
SC
258
259 return wxOutRegion;
e9576ca5
SC
260}
261
262// Does the region contain the rectangle (x, y, w, h)?
263wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const
264{
265 if (!m_refData)
266 return wxOutRegion;
267
519cb848
SC
268 Rect rect = { y , x , y + h , x + w } ;
269 if (RectInRgn( &rect , M_REGION ) )
e9576ca5
SC
270 return wxInRegion;
271 else
272 return wxOutRegion;
273}
274
275// Does the region contain the rectangle rect
276wxRegionContain wxRegion::Contains(const wxRect& rect) const
277{
278 if (!m_refData)
279 return wxOutRegion;
280
281 long x, y, w, h;
282 x = rect.x;
283 y = rect.y;
284 w = rect.GetWidth();
285 h = rect.GetHeight();
286 return Contains(x, y, w, h);
287}
288
289///////////////////////////////////////////////////////////////////////////////
e7600a2c
GD
290// //
291// wxRegionIterator //
292// //
e9576ca5
SC
293///////////////////////////////////////////////////////////////////////////////
294
295/*!
296 * Initialize empty iterator
297 */
e7600a2c
GD
298wxRegionIterator::wxRegionIterator()
299 : m_current(0), m_numRects(0), m_rects(NULL)
e9576ca5
SC
300{
301}
302
303wxRegionIterator::~wxRegionIterator()
304{
305 if (m_rects)
306 delete[] m_rects;
307}
308
e7600a2c
GD
309wxRegionIterator::wxRegionIterator(const wxRegionIterator& iterator)
310 : wxObject()
311 , m_current(iterator.m_current)
312 , m_numRects(iterator.m_numRects)
313 , m_rects(iterator.m_rects)
314{
315}
316
317wxRegionIterator& wxRegionIterator::operator=(const wxRegionIterator& iterator)
318{
319 m_current = iterator.m_current;
320 m_numRects = iterator.m_numRects;
321 m_rects = iterator.m_rects;
322 return *this;
323}
324
e9576ca5
SC
325/*!
326 * Initialize iterator for region
327 */
328wxRegionIterator::wxRegionIterator(const wxRegion& region)
329{
330 m_rects = NULL;
331
e7600a2c 332 Reset(region);
e9576ca5
SC
333}
334
335/*!
336 * Reset iterator for a new /e region.
337 */
338void wxRegionIterator::Reset(const wxRegion& region)
339{
340 m_current = 0;
341 m_region = region;
342
343 if (m_rects)
344 delete[] m_rects;
345
346 m_rects = NULL;
347
348 if (m_region.Empty())
349 m_numRects = 0;
350 else
351 {
519cb848
SC
352 // we cannot dissolve it into rects on mac
353 m_rects = new wxRect[1];
2f1ae414
SC
354 Rect rect ;
355 GetRegionBounds( OTHER_M_REGION( region ) , &rect ) ;
519cb848
SC
356 m_rects[0].x = rect.left;
357 m_rects[0].y = rect.top;
358 m_rects[0].width = rect.right - rect.left;
359 m_rects[0].height = rect.bottom - rect.top;
360 m_numRects = 1;
e9576ca5
SC
361 }
362}
363
364/*!
365 * Increment iterator. The rectangle returned is the one after the
366 * incrementation.
367 */
e7600a2c 368wxRegionIterator& wxRegionIterator::operator ++ ()
e9576ca5 369{
e7600a2c
GD
370 if (m_current < m_numRects)
371 ++m_current;
372 return *this;
e9576ca5
SC
373}
374
375/*!
376 * Increment iterator. The rectangle returned is the one before the
377 * incrementation.
378 */
e7600a2c 379wxRegionIterator wxRegionIterator::operator ++ (int)
e9576ca5 380{
e7600a2c
GD
381 wxRegionIterator previous(*this);
382
383 if (m_current < m_numRects)
384 ++m_current;
385
386 return previous;
e9576ca5
SC
387}
388
389long wxRegionIterator::GetX() const
390{
391 if (m_current < m_numRects)
392 return m_rects[m_current].x;
393 return 0;
394}
395
396long wxRegionIterator::GetY() const
397{
398 if (m_current < m_numRects)
399 return m_rects[m_current].y;
400 return 0;
401}
402
403long wxRegionIterator::GetW() const
404{
405 if (m_current < m_numRects)
406 return m_rects[m_current].width ;
407 return 0;
408}
409
410long wxRegionIterator::GetH() const
411{
412 if (m_current < m_numRects)
413 return m_rects[m_current].height;
414 return 0;
415}
416