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