]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: common/pseudodc.cpp | |
3 | // Purpose: Implementation of the wxPseudoDC Class | |
4 | // Author: Paul Lanier | |
5 | // Modified by: | |
6 | // Created: 05/25/06 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) wxWidgets team | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // For compilers that support precompilation, includes "wx.h". | |
13 | #include "wx/wxprec.h" | |
14 | ||
15 | #include "wx/wxPython/pseudodc.h" | |
16 | #include <stdio.h> | |
17 | ||
18 | // wxList based class definitions | |
19 | #include <wx/listimpl.cpp> | |
20 | WX_DEFINE_LIST(pdcOpList); | |
21 | WX_DEFINE_LIST(pdcObjectList); | |
22 | ||
23 | // ============================================================================ | |
24 | // various pdcOp class implementation methods | |
25 | // ============================================================================ | |
26 | ||
27 | // ---------------------------------------------------------------------------- | |
28 | // pdcDrawPolyPolygonOp constructor | |
29 | // ---------------------------------------------------------------------------- | |
30 | pdcDrawPolyPolygonOp::pdcDrawPolyPolygonOp(int n, int count[], wxPoint points[], | |
31 | wxCoord xoffset, wxCoord yoffset, int fillStyle) | |
32 | { | |
33 | m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle; | |
34 | int total_n=0; | |
35 | if (n) | |
36 | { | |
37 | m_count = new int[n]; | |
38 | for(int i=0; i<n; i++) | |
39 | { | |
40 | total_n+=count[i]; | |
41 | m_count[i]=count[i]; | |
42 | } | |
43 | if (total_n) | |
44 | { | |
45 | m_points = new wxPoint[total_n]; | |
46 | for(int j=0; j<total_n; j++) | |
47 | m_points[j] = points[j]; | |
48 | } | |
49 | else m_points=NULL; | |
50 | } | |
51 | else | |
52 | { | |
53 | m_points=NULL; | |
54 | m_count=NULL; | |
55 | } | |
56 | m_totaln = total_n; | |
57 | } | |
58 | ||
59 | // ---------------------------------------------------------------------------- | |
60 | // pdcDrawPolyPolygonOp destructor | |
61 | // ---------------------------------------------------------------------------- | |
62 | pdcDrawPolyPolygonOp::~pdcDrawPolyPolygonOp() | |
63 | { | |
64 | if (m_points) delete m_points; | |
65 | if (m_count) delete m_count; | |
66 | m_points=NULL; | |
67 | m_count=NULL; | |
68 | } | |
69 | ||
70 | // ---------------------------------------------------------------------------- | |
71 | // pdcDrawLinesOp constructor | |
72 | // ---------------------------------------------------------------------------- | |
73 | pdcDrawLinesOp::pdcDrawLinesOp(int n, wxPoint points[], | |
74 | wxCoord xoffset, wxCoord yoffset) | |
75 | { | |
76 | m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; | |
77 | if (n) | |
78 | { | |
79 | m_points = new wxPoint[n]; | |
80 | for (int i=0; i<n; i++) | |
81 | m_points[i] = points[i]; | |
82 | } | |
83 | else m_points=NULL; | |
84 | } | |
85 | ||
86 | // ---------------------------------------------------------------------------- | |
87 | // pdcDrawLinesOp destructor | |
88 | // ---------------------------------------------------------------------------- | |
89 | pdcDrawLinesOp::~pdcDrawLinesOp() | |
90 | { | |
91 | if (m_points) delete m_points; | |
92 | m_points=NULL; | |
93 | } | |
94 | ||
95 | // ---------------------------------------------------------------------------- | |
96 | // pdcDrawPolygonOp constructor | |
97 | // ---------------------------------------------------------------------------- | |
98 | pdcDrawPolygonOp::pdcDrawPolygonOp(int n, wxPoint points[], | |
99 | wxCoord xoffset, wxCoord yoffset, int fillStyle) | |
100 | { | |
101 | m_n=n; m_xoffset=xoffset; m_yoffset=yoffset; m_fillStyle=fillStyle; | |
102 | if (n) | |
103 | { | |
104 | m_points = new wxPoint[n]; | |
105 | for (int i=0; i<n; i++) | |
106 | m_points[i] = points[i]; | |
107 | } | |
108 | else m_points=NULL; | |
109 | } | |
110 | ||
111 | // ---------------------------------------------------------------------------- | |
112 | // pdcDrawPolygonOp destructor | |
113 | // ---------------------------------------------------------------------------- | |
114 | pdcDrawPolygonOp::~pdcDrawPolygonOp() | |
115 | { | |
116 | if (m_points) delete m_points; | |
117 | m_points=NULL; | |
118 | } | |
119 | ||
120 | #if wxUSE_SPLINES | |
121 | // ---------------------------------------------------------------------------- | |
122 | // pdcDrawSplineOp constructor | |
123 | // ---------------------------------------------------------------------------- | |
124 | pdcDrawSplineOp::pdcDrawSplineOp(int n, wxPoint points[]) | |
125 | { | |
126 | m_n=n; | |
127 | if (n) | |
128 | { | |
129 | m_points = new wxPoint[n]; | |
130 | for(int i=0; i<n; i++) | |
131 | m_points[i] = points[i]; | |
132 | } | |
133 | else m_points=NULL; | |
134 | } | |
135 | ||
136 | // ---------------------------------------------------------------------------- | |
137 | // pdcDrawSplineOp destructor | |
138 | // ---------------------------------------------------------------------------- | |
139 | pdcDrawSplineOp::~pdcDrawSplineOp() | |
140 | { | |
141 | if (m_points) delete m_points; | |
142 | m_points=NULL; | |
143 | } | |
144 | #endif // wxUSE_SPLINES | |
145 | ||
146 | // ============================================================================ | |
147 | // pdcObject implementation | |
148 | // ============================================================================ | |
149 | // ---------------------------------------------------------------------------- | |
150 | // DrawToDC - play back the op list to the DC | |
151 | // ---------------------------------------------------------------------------- | |
152 | void pdcObject::DrawToDC(wxDC *dc) | |
153 | { | |
154 | pdcOpList::Node *node = m_oplist.GetFirst(); | |
155 | while(node) | |
156 | { | |
157 | node->GetData()->DrawToDC(dc); | |
158 | node = node->GetNext(); | |
159 | } | |
160 | } | |
161 | ||
162 | // ---------------------------------------------------------------------------- | |
163 | // Translate - translate all the operations by some dx,dy | |
164 | // ---------------------------------------------------------------------------- | |
165 | void pdcObject::Translate(wxCoord dx, wxCoord dy) | |
166 | { | |
167 | pdcOpList::Node *node = m_oplist.GetFirst(); | |
168 | while(node) | |
169 | { | |
170 | node->GetData()->Translate(dx,dy); | |
171 | node = node->GetNext(); | |
172 | } | |
173 | if (m_bounded) | |
174 | { | |
175 | m_bounds.x += dx; | |
176 | m_bounds.y += dy; | |
177 | } | |
178 | } | |
179 | ||
180 | // ============================================================================ | |
181 | // wxPseudoDC implementation | |
182 | // ============================================================================ | |
183 | ||
184 | // ---------------------------------------------------------------------------- | |
185 | // Destructor | |
186 | // ---------------------------------------------------------------------------- | |
187 | wxPseudoDC::~wxPseudoDC() | |
188 | { | |
189 | // delete all the nodes in the list | |
190 | RemoveAll(); | |
191 | ||
192 | } | |
193 | ||
194 | // ---------------------------------------------------------------------------- | |
195 | // ClearAll - remove all nodes from list | |
196 | // ---------------------------------------------------------------------------- | |
197 | void wxPseudoDC::RemoveAll(void) | |
198 | { | |
199 | m_objectlist.Clear(); | |
200 | m_currId = -1; | |
201 | m_lastObjNode = NULL; | |
202 | } | |
203 | ||
204 | // ---------------------------------------------------------------------------- | |
205 | // GetLen - return the number of operations in the current op list | |
206 | // ---------------------------------------------------------------------------- | |
207 | int wxPseudoDC::GetLen(void) | |
208 | { | |
209 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
210 | int len=0; | |
211 | while (pt) | |
212 | { | |
213 | len += pt->GetData()->GetLen(); | |
214 | pt = pt->GetNext(); | |
215 | } | |
216 | return len; | |
217 | } | |
218 | ||
219 | // ---------------------------------------------------------------------------- | |
220 | // FindObjNode - find and return an object node by id. If node doesn't exist | |
221 | // and create is true then create one and return it. Otherwise | |
222 | // return NULL. | |
223 | // ---------------------------------------------------------------------------- | |
224 | pdcObjectList::Node *wxPseudoDC::FindObjNode(int id, bool create) | |
225 | { | |
226 | // see if last operation was for same id | |
227 | if (m_lastObjNode && m_lastObjNode->GetData()->GetId() == id) | |
228 | return m_lastObjNode; | |
229 | // if not then search for it | |
230 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
231 | while (pt) | |
232 | { | |
233 | if (pt->GetData()->GetId() == id) | |
234 | { | |
235 | ||
236 | // cache this node for future operations | |
237 | m_lastObjNode = pt; | |
238 | return pt; | |
239 | } | |
240 | pt = pt->GetNext(); | |
241 | } | |
242 | // if create then create and return a new node | |
243 | if (create) | |
244 | { | |
245 | // cache this node for future operations | |
246 | m_lastObjNode = m_objectlist.Append(new pdcObject(id)); | |
247 | return m_lastObjNode; | |
248 | } | |
249 | // otherwise just return NULL | |
250 | return NULL; | |
251 | } | |
252 | ||
253 | // ---------------------------------------------------------------------------- | |
254 | // AddToList - Add a node to the list at the end (preserve draw order) | |
255 | // ---------------------------------------------------------------------------- | |
256 | void wxPseudoDC::AddToList(pdcOp *newOp) | |
257 | { | |
258 | pdcObjectList::Node *pt = FindObjNode(m_currId, true); | |
259 | pt->GetData()->AddOp(newOp); | |
260 | } | |
261 | ||
262 | // ---------------------------------------------------------------------------- | |
263 | // ClearID - remove all the operations associated with a single ID | |
264 | // ---------------------------------------------------------------------------- | |
265 | void wxPseudoDC::ClearId(int id) | |
266 | { | |
267 | pdcObjectList::Node *pt = FindObjNode(id); | |
268 | if (pt) pt->GetData()->Clear(); | |
269 | } | |
270 | ||
271 | // ---------------------------------------------------------------------------- | |
272 | // RemoveID - Remove the object node (and all operations) associated with an id | |
273 | // ---------------------------------------------------------------------------- | |
274 | void wxPseudoDC::RemoveId(int id) | |
275 | { | |
276 | pdcObjectList::Node *pt = FindObjNode(id); | |
277 | if (pt) | |
278 | { | |
279 | if (m_lastObjNode == pt) | |
280 | m_lastObjNode = NULL; | |
281 | m_objectlist.DeleteNode(pt); | |
282 | } | |
283 | } | |
284 | ||
285 | // ---------------------------------------------------------------------------- | |
286 | // SetIdBounds - Set the bounding rect for a given id | |
287 | // ---------------------------------------------------------------------------- | |
288 | void wxPseudoDC::SetIdBounds(int id, wxRect& rect) | |
289 | { | |
290 | pdcObjectList::Node *pt = FindObjNode(id, true); | |
291 | pt->GetData()->SetBounds(rect); | |
292 | } | |
293 | ||
294 | // ---------------------------------------------------------------------------- | |
295 | // GetIdBounds - Get the bounding rect for a given id | |
296 | // ---------------------------------------------------------------------------- | |
297 | void wxPseudoDC::GetIdBounds(int id, wxRect& rect) | |
298 | { | |
299 | pdcObjectList::Node *pt = FindObjNode(id); | |
300 | if (pt && pt->GetData()->IsBounded()) | |
301 | rect = pt->GetData()->GetBounds(); | |
302 | else | |
303 | rect.x = rect.y = rect.width = rect.height = 0; | |
304 | } | |
305 | ||
306 | // ---------------------------------------------------------------------------- | |
307 | // TranslateId - Translate all the operations of a single id | |
308 | // ---------------------------------------------------------------------------- | |
309 | void wxPseudoDC::TranslateId(int id, wxCoord dx, wxCoord dy) | |
310 | { | |
311 | pdcObjectList::Node *pt = FindObjNode(id); | |
312 | if (pt) pt->GetData()->Translate(dx,dy); | |
313 | } | |
314 | ||
315 | // ---------------------------------------------------------------------------- | |
316 | // DrawIdToDC - Draw a specific id to the dc passed in | |
317 | // ---------------------------------------------------------------------------- | |
318 | void wxPseudoDC::DrawIdToDC(int id, wxDC *dc) | |
319 | { | |
320 | pdcObjectList::Node *pt = FindObjNode(id); | |
321 | if (pt) pt->GetData()->DrawToDC(dc); | |
322 | } | |
323 | ||
324 | // ---------------------------------------------------------------------------- | |
325 | // DrawToDCClipped - play back the op list to the DC but clip any objects | |
326 | // known to be not in rect. This is a coarse level of | |
327 | // clipping to speed things up when lots of objects are off | |
328 | // screen and doesn't affect the dc level clipping | |
329 | // ---------------------------------------------------------------------------- | |
330 | void wxPseudoDC::DrawToDCClipped(wxDC *dc, const wxRect& rect) | |
331 | { | |
332 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
333 | pdcObject *obj; | |
334 | while (pt) | |
335 | { | |
336 | obj = pt->GetData(); | |
337 | if (!obj->IsBounded() || rect.Intersects(obj->GetBounds())) | |
338 | obj->DrawToDC(dc); | |
339 | pt = pt->GetNext(); | |
340 | } | |
341 | } | |
342 | void wxPseudoDC::DrawToDCClippedRgn(wxDC *dc, const wxRegion& region) | |
343 | { | |
344 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
345 | pdcObject *obj; | |
346 | while (pt) | |
347 | { | |
348 | obj = pt->GetData(); | |
349 | if (!obj->IsBounded() || | |
350 | (region.Contains(obj->GetBounds()) != wxOutRegion)) | |
351 | obj->DrawToDC(dc); | |
352 | pt = pt->GetNext(); | |
353 | } | |
354 | } | |
355 | ||
356 | // ---------------------------------------------------------------------------- | |
357 | // DrawToDC - play back the op list to the DC | |
358 | // ---------------------------------------------------------------------------- | |
359 | void wxPseudoDC::DrawToDC(wxDC *dc) | |
360 | { | |
361 | pdcObjectList::Node *pt = m_objectlist.GetFirst(); | |
362 | while (pt) | |
363 | { | |
364 | pt->GetData()->DrawToDC(dc); | |
365 | pt = pt->GetNext(); | |
366 | } | |
367 | } | |
368 |