]> git.saurik.com Git - wxWidgets.git/blame - src/motif/region.cpp
Changed my mind and used FNSTRINGCAST instead
[wxWidgets.git] / src / motif / region.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// File: region.cpp
3// Purpose: Region class
f97c9854 4// Author: Markus Holzem/Julian Smart
4bb6408c 5// Created: Fri Oct 24 10:46:34 MET 1997
dfe1eee3 6// RCS-ID: $Id$
f97c9854 7// Copyright: (c) 1997 Markus Holzem/Julian Smart
4bb6408c
JS
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
f97c9854
JS
18#include <Xm/Xm.h>
19// #include "wx/motif/private.h"
20
4bb6408c 21#if !USE_SHARED_LIBRARY
dfe1eee3
VZ
22 IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
23 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
4bb6408c
JS
24#endif
25
26//-----------------------------------------------------------------------------
27// wxRegionRefData implementation
28//-----------------------------------------------------------------------------
29
30class WXDLLEXPORT wxRegionRefData : public wxGDIRefData {
31public:
dfe1eee3
VZ
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 }
f97c9854 47 Region m_region;
4bb6408c
JS
48};
49
f97c9854 50#define M_REGION (((wxRegionRefData*)m_refData)->m_region)
4bb6408c
JS
51
52//-----------------------------------------------------------------------------
53// wxRegion
54//-----------------------------------------------------------------------------
55
56/*!
57 * Create an empty region.
58 */
59wxRegion::wxRegion()
60{
4bb6408c
JS
61}
62
63wxRegion::wxRegion(long x, long y, long w, long h)
64{
65 m_refData = new wxRegionRefData;
f97c9854 66
dfe1eee3
VZ
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);
4bb6408c
JS
73}
74
75wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
76{
77 m_refData = new wxRegionRefData;
f97c9854 78
dfe1eee3
VZ
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);
4bb6408c
JS
85}
86
87wxRegion::wxRegion(const wxRect& rect)
88{
89 m_refData = new wxRegionRefData;
f97c9854
JS
90
91 XRectangle rect1;
dfe1eee3
VZ
92 rect1.x = rect.x;
93 rect1.y = rect.y;
94 rect1.width = rect.width;
f97c9854
JS
95 rect1.height = rect.height;
96 XUnionRectWithRegion(&rect1, M_REGION, M_REGION);
4bb6408c
JS
97}
98
99/*!
100 * Destroy the region.
101 */
102wxRegion::~wxRegion()
103{
104 // m_refData unrefed in ~wxObject
105}
106
55acd85e 107// Get the internal region handle
45d49251 108WXRegion wxRegion::GetXRegion() const
55acd85e
JS
109{
110 wxASSERT( m_refData !=NULL );
111
112 return (WXRegion) ((wxRegionRefData*)m_refData)->m_region;
113}
114
4bb6408c
JS
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{
dfe1eee3
VZ
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 }
4bb6408c
JS
136 // If ref count is 1, that means it's 'ours' anyway so no action.
137
f97c9854
JS
138 Region rectRegion = XCreateRegion();
139
dfe1eee3
VZ
140 XRectangle rect;
141 rect.x = x;
142 rect.y = y;
143 rect.width = width;
144 rect.height = height;
145 XUnionRectWithRegion(&rect, rectRegion, rectRegion);
4bb6408c 146
4bb6408c
JS
147 switch (op)
148 {
149 case wxRGN_AND:
dfe1eee3 150 XIntersectRegion(M_REGION, rectRegion, M_REGION);
4bb6408c
JS
151 break ;
152 case wxRGN_OR:
dfe1eee3 153 XUnionRegion(M_REGION, rectRegion, M_REGION);
4bb6408c
JS
154 break ;
155 case wxRGN_XOR:
156 // TODO
157 break ;
158 case wxRGN_DIFF:
159 // TODO
160 break ;
f97c9854 161 case wxRGN_COPY: // Don't have to do this one
4bb6408c
JS
162 default:
163 // TODO
164 break ;
165 }
166
4bb6408c
JS
167 return FALSE;
168}
169
170//! Union /e region with this.
171bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
172{
dfe1eee3
VZ
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
4bb6408c
JS
185 switch (op)
186 {
187 case wxRGN_AND:
dfe1eee3
VZ
188 XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
189 M_REGION);
4bb6408c
JS
190 break ;
191 case wxRGN_OR:
dfe1eee3
VZ
192 XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
193 M_REGION);
4bb6408c
JS
194 break ;
195 case wxRGN_XOR:
196 // TODO
197 break ;
198 case wxRGN_DIFF:
199 // TODO
200 break ;
f97c9854 201 case wxRGN_COPY: // Don't have to do this one
4bb6408c
JS
202 default:
203 // TODO
204 break ;
205 }
206
a724d789 207 return FALSE;
4bb6408c
JS
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{
dfe1eee3
VZ
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 }
4bb6408c
JS
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{
dfe1eee3 244 return m_refData ? XEmptyRegion(M_REGION) : TRUE;
4bb6408c
JS
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{
dfe1eee3
VZ
254 if (!m_refData)
255 return wxOutRegion;
4bb6408c
JS
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{
dfe1eee3
VZ
266 if (!m_refData)
267 return wxOutRegion;
4bb6408c 268
dfe1eee3 269 return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion;
4bb6408c
JS
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{
dfe1eee3
VZ
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;
4bb6408c
JS
283}
284
285// Does the region contain the rectangle rect
286wxRegionContain wxRegion::Contains(const wxRect& rect) const
287{
dfe1eee3
VZ
288 if (!m_refData)
289 return wxOutRegion;
4bb6408c
JS
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///////////////////////////////////////////////////////////////////////////////
dfe1eee3
VZ
300// //
301// wxRegionIterator //
302// //
4bb6408c
JS
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
dfe1eee3 325 Reset(region);
4bb6408c
JS
326}
327
328/*!
329 * Reset iterator for a new /e region.
330 */
331void wxRegionIterator::Reset(const wxRegion& region)
332{
dfe1eee3
VZ
333 m_current = 0;
334 m_region = region;
4bb6408c
JS
335
336 if (m_rects)
337 delete[] m_rects;
338
339 m_rects = NULL;
340
dfe1eee3
VZ
341 if (m_region.Empty())
342 m_numRects = 0;
343 else
4bb6408c
JS
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{
dfe1eee3
VZ
356 if (m_current < m_numRects)
357 ++m_current;
4bb6408c
JS
358}
359
360/*!
361 * Increment iterator. The rectangle returned is the one before the
362 * incrementation.
363 */
364void wxRegionIterator::operator ++ (int)
365{
dfe1eee3
VZ
366 if (m_current < m_numRects)
367 ++m_current;
4bb6408c
JS
368}
369
370long wxRegionIterator::GetX() const
371{
dfe1eee3
VZ
372 if (m_current < m_numRects)
373 return m_rects[m_current].x;
374 return 0;
4bb6408c
JS
375}
376
377long wxRegionIterator::GetY() const
378{
dfe1eee3
VZ
379 if (m_current < m_numRects)
380 return m_rects[m_current].y;
381 return 0;
4bb6408c
JS
382}
383
384long wxRegionIterator::GetW() const
385{
dfe1eee3
VZ
386 if (m_current < m_numRects)
387 return m_rects[m_current].width ;
388 return 0;
4bb6408c
JS
389}
390
391long wxRegionIterator::GetH() const
392{
dfe1eee3
VZ
393 if (m_current < m_numRects)
394 return m_rects[m_current].height;
395 return 0;
4bb6408c
JS
396}
397