]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/drawlist.cpp
better report if the subclass factory has import problems
[wxWidgets.git] / wxPython / src / drawlist.cpp
CommitLineData
1e4a197e
RD
1/////////////////////////////////////////////////////////////////////////////
2// Name: drawlist.cpp
3// Purpose: Helper functions for optimized list drawing on a wxDC
4//
d14a1e28 5// Author: Robin Dunn, Chris Barker
1e4a197e
RD
6//
7// Created:
8// RCS-ID: $Id$
9// Copyright: (c) 2003 by Total Control Software
10// Licence: wxWindows license
11/////////////////////////////////////////////////////////////////////////////
12
13
14#undef DEBUG
15#include <Python.h>
d14a1e28
RD
16#include "wx/wxPython/wxPython.h"
17#include "wx/wxPython/pydrawxxx.h"
1e4a197e
RD
18
19
7722248d 20//---------------------------------------------------------------------------
1e4a197e
RD
21
22
7722248d
RD
23// Called from _gdiinit so we can do the API import while the GIL is held
24void wxPyDrawList_SetAPIPtr()
25{
26 wxPyCoreAPI_IMPORT();
27}
1e4a197e 28
1e4a197e 29
7722248d
RD
30PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw,
31 PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)
32{
6e6b3557 33 wxPyBlock_t blocked = wxPyBeginBlockThreads();
1e4a197e
RD
34
35 bool isFastSeq = PyList_Check(pyCoords) || PyTuple_Check(pyCoords);
36 bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens);
37 bool isFastBrushes = PyList_Check(pyBrushes) || PyTuple_Check(pyBrushes);
38 int numObjs = 0;
39 int numPens = 0;
40 int numBrushes = 0;
41 wxPen* pen;
42 wxBrush* brush;
43 PyObject* obj;
44 PyObject* coords;
1e4a197e
RD
45 int i = 0;
46 PyObject* retval;
47
48 if (!PySequence_Check(pyCoords)) {
49 goto err0;
50 }
51 if (!PySequence_Check(pyPens)) {
52 goto err1;
53 }
54 if (!PySequence_Check(pyBrushes)) {
55 goto err2;
56 }
57 numObjs = PySequence_Length(pyCoords);
58 numPens = PySequence_Length(pyPens);
59 numBrushes = PySequence_Length(pyBrushes);
60 for (i = 0; i < numObjs; i++) {
61 // Use a new pen?
62 if (i < numPens) {
63 if (isFastPens) {
64 obj = PySequence_Fast_GET_ITEM(pyPens, i);
65 }
66 else {
67 obj = PySequence_GetItem(pyPens, i);
68 }
d14a1e28 69 if (! wxPyConvertSwigPtr(obj, (void **) &pen, wxT("wxPen"))) {
1e4a197e
RD
70 if (!isFastPens)
71 Py_DECREF(obj);
72 goto err1;
73 }
74
75 dc.SetPen(*pen);
76 if (!isFastPens)
77 Py_DECREF(obj);
78 }
79 // Use a new brush?
80 if (i < numBrushes) {
81 if (isFastBrushes) {
82 obj = PySequence_Fast_GET_ITEM(pyBrushes, i);
83 }
84 else {
85 obj = PySequence_GetItem(pyBrushes, i);
86 }
d14a1e28 87 if (!wxPyConvertSwigPtr(obj, (void **) &brush, wxT("wxBrush"))) {
1e4a197e
RD
88 if (!isFastBrushes)
89 Py_DECREF(obj);
90 goto err2;
91 }
92
93 dc.SetBrush(*brush);
94 if (!isFastBrushes)
95 Py_DECREF(obj);
96 }
97
98 // Get the Coordinates
99 if (isFastSeq) {
100 coords = PySequence_Fast_GET_ITEM(pyCoords, i);
101 }
102 else {
103 coords = PySequence_GetItem(pyCoords, i);
104 }
105
106
107 // call the drawOp
108 bool success = doDraw(dc, coords);
109 if (!isFastSeq)
110 Py_DECREF(coords);
111
112 if (! success) {
113 retval = NULL;
114 goto exit;
115 }
116
117 } // end of main for loop
118
119 Py_INCREF(Py_None);
120 retval = Py_None;
121 goto exit;
122
123
124 err0:
125 PyErr_SetString(PyExc_TypeError, "Expected a sequence of coordinates");
126 retval = NULL;
127 goto exit;
128
129 err1:
130 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens");
131 retval = NULL;
132 goto exit;
133
134 err2:
135 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxBrushes");
136 retval = NULL;
137 goto exit;
138
139
140 exit:
da32eb53 141 wxPyEndBlockThreads(blocked);
1e4a197e
RD
142 return retval;
143}
144
145
146
7722248d
RD
147bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords)
148{
1e4a197e
RD
149 int x, y;
150
151 if (! wxPy2int_seq_helper(coords, &x, &y)) {
152 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences.");
4519a2d9 153 return false;
1e4a197e
RD
154 }
155 dc.DrawPoint(x, y);
4519a2d9 156 return true;
1e4a197e
RD
157}
158
7722248d
RD
159bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords)
160{
1e4a197e
RD
161 int x1, y1, x2, y2;
162
163 if (! wxPy4int_seq_helper(coords, &x1, &y1, &x2, &y2)) {
164 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x1,y1, x1,y2) sequences.");
4519a2d9 165 return false;
1e4a197e
RD
166 }
167 dc.DrawLine(x1,y1, x2,y2);
4519a2d9 168 return true;
1e4a197e
RD
169}
170
7722248d
RD
171bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords)
172{
1e4a197e
RD
173 int x, y, w, h;
174
175 if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) {
176 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences.");
4519a2d9 177 return false;
1e4a197e
RD
178 }
179 dc.DrawRectangle(x, y, w, h);
4519a2d9 180 return true;
1e4a197e
RD
181}
182
7722248d
RD
183bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords)
184{
1e4a197e
RD
185 int x, y, w, h;
186
187 if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) {
188 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences.");
4519a2d9 189 return false;
1e4a197e
RD
190 }
191 dc.DrawEllipse(x, y, w, h);
4519a2d9 192 return true;
1e4a197e
RD
193}
194
195
7722248d
RD
196bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords)
197{
1e4a197e
RD
198 wxPoint* points;
199 int numPoints;
200
201 points = wxPoint_LIST_helper(coords, &numPoints);
202 if (! points) {
203 PyErr_SetString(PyExc_TypeError, "Expected a sequence of sequences of (x,y) sequences.");
4519a2d9 204 return false;
1e4a197e
RD
205 }
206 dc.DrawPolygon(numPoints, points);
ba383492 207 delete [] points;
4519a2d9 208 return true;
1e4a197e
RD
209}
210
211
7722248d 212//---------------------------------------------------------------------------
1e4a197e
RD
213
214
215
7722248d
RD
216PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)
217{
6e6b3557 218 wxPyBlock_t blocked = wxPyBeginBlockThreads();
1e4a197e
RD
219
220 bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints);
221 bool isFastText = PyList_Check(textList) || PyTuple_Check(textList);
222 bool isFastForeground = PyList_Check(foregroundList) || PyTuple_Check(foregroundList);
223 bool isFastBackground = PyList_Check(backgroundList) || PyTuple_Check(backgroundList);
224 int numText = 0;
225 int numPoints = 0;
226 int numForeground = 0;
227 int numBackground = 0;
228 PyObject* obj;
229 int x1, y1;
230 int i = 0;
231 wxColor* color;
232 PyObject* retval;
233 wxString string;
234
235 if (!PySequence_Check(pyPoints)) {
236 goto err0;
237 }
238 if (!PySequence_Check(textList)) {
239 goto err1;
240 }
241 if (!PySequence_Check(foregroundList)) {
242 goto err2;
243 }
244 if (!PySequence_Check(backgroundList)) {
245 goto err3;
246 }
247 numPoints = PySequence_Length(pyPoints);
248 numText = PySequence_Length(textList);
249 numForeground = PySequence_Length(foregroundList);
250 numBackground = PySequence_Length(backgroundList);
251
252 for (i = 0; i < numPoints; i++) {
253 // Use a new string ?
254 if (i < numText) {
255 if ( isFastText ) {
256 obj = PySequence_Fast_GET_ITEM(textList, i);
257 }
258 else {
259 obj = PySequence_GetItem(textList, i);
260 }
06223aa3 261 if (! PyString_Check(obj) && !PyUnicode_Check(obj) ) {
1e4a197e
RD
262 Py_DECREF(obj);
263 goto err1;
264 }
265 string = Py2wxString(obj);
266 if ( !isFastText )
267 Py_DECREF(obj);
268 }
269
270 if (i < numForeground) {
271 // Use a new foreground ?
272 if ( isFastForeground ) {
273 obj = PySequence_Fast_GET_ITEM(foregroundList, i);
274 }
275 else {
276 obj = PySequence_GetItem(foregroundList, i);
277 }
fd3f2efe 278 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) {
1e4a197e
RD
279 if (!isFastForeground)
280 Py_DECREF(obj);
281 goto err2;
282 }
283 dc.SetTextForeground(*color);
284 if ( !isFastForeground )
285 Py_DECREF(obj);
286 }
287
288 if (i < numBackground) {
289 // Use a new background ?
290 if ( isFastBackground ) {
291 obj = PySequence_Fast_GET_ITEM(backgroundList, i);
292 }
293 else {
294 obj = PySequence_GetItem(backgroundList, i);
295 }
d14a1e28 296 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) {
1e4a197e
RD
297 if (!isFastBackground)
298 Py_DECREF(obj);
299 goto err3;
300 }
301 dc.SetTextBackground(*color);
302 if ( !isFastBackground )
303 Py_DECREF(obj);
304 }
305
306 // Get the point coordinates
307 if (isFastSeq) {
308 obj = PySequence_Fast_GET_ITEM(pyPoints, i);
309 }
310 else {
311 obj = PySequence_GetItem(pyPoints, i);
312 }
313 if (! wxPy2int_seq_helper(obj, &x1, &y1)) {
314 if (! isFastSeq)
315 Py_DECREF(obj);
316 goto err0;
317 }
318 if (PyErr_Occurred()) {
319 retval = NULL;
320 if (!isFastSeq)
321 Py_DECREF(obj);
322 goto exit;
323 }
324
325
326 // Now draw the text
327 dc.DrawText(string, x1, y1);
328
329 if (!isFastText)
330 Py_DECREF(obj);
331 }
332
333 Py_INCREF(Py_None);
334 retval = Py_None;
335 goto exit;
336
337 err0:
338 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences.");
339 retval = NULL;
340 goto exit;
341 err1:
342 PyErr_SetString(PyExc_TypeError, "Expected a sequence of strings");
343 retval = NULL;
344 goto exit;
345
346 err2:
347 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for foregrounds");
348 retval = NULL;
349 goto exit;
350
351 err3:
352 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for backgrounds");
353 retval = NULL;
354 goto exit;
355
356 exit:
da32eb53 357 wxPyEndBlockThreads(blocked);
1e4a197e
RD
358 return retval;
359}
360
361
362
7722248d 363//---------------------------------------------------------------------------