]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/drawlist.cpp
Add GetMaxTotalWidth
[wxWidgets.git] / wxPython / src / drawlist.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: drawlist.cpp
3 // Purpose: Helper functions for optimized list drawing on a wxDC
4 //
5 // Author: Robin Dunn, Chris Barker
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>
16 #include "wx/wxPython/wxPython.h"
17 #include "wx/wxPython/pydrawxxx.h"
18
19
20 //---------------------------------------------------------------------------
21
22
23 // Called from _gdiinit so we can do the API import while the GIL is held
24 void wxPyDrawList_SetAPIPtr()
25 {
26 wxPyCoreAPI_IMPORT();
27 }
28
29
30 PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw,
31 PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)
32 {
33 bool blocked = wxPyBeginBlockThreads();
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;
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 }
69 if (! wxPyConvertSwigPtr(obj, (void **) &pen, wxT("wxPen"))) {
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 }
87 if (!wxPyConvertSwigPtr(obj, (void **) &brush, wxT("wxBrush"))) {
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:
141 wxPyEndBlockThreads(blocked);
142 return retval;
143 }
144
145
146
147 bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords)
148 {
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.");
153 return False;
154 }
155 dc.DrawPoint(x, y);
156 return True;
157 }
158
159 bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords)
160 {
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.");
165 return False;
166 }
167 dc.DrawLine(x1,y1, x2,y2);
168 return True;
169 }
170
171 bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords)
172 {
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.");
177 return False;
178 }
179 dc.DrawRectangle(x, y, w, h);
180 return True;
181 }
182
183 bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords)
184 {
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.");
189 return False;
190 }
191 dc.DrawEllipse(x, y, w, h);
192 return True;
193 }
194
195
196 bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords)
197 {
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.");
204 return False;
205 }
206 dc.DrawPolygon(numPoints, points);
207 return True;
208 }
209
210
211 //---------------------------------------------------------------------------
212
213
214
215 PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)
216 {
217 bool blocked = wxPyBeginBlockThreads();
218
219 bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints);
220 bool isFastText = PyList_Check(textList) || PyTuple_Check(textList);
221 bool isFastForeground = PyList_Check(foregroundList) || PyTuple_Check(foregroundList);
222 bool isFastBackground = PyList_Check(backgroundList) || PyTuple_Check(backgroundList);
223 int numText = 0;
224 int numPoints = 0;
225 int numForeground = 0;
226 int numBackground = 0;
227 PyObject* obj;
228 int x1, y1;
229 int i = 0;
230 wxColor* color;
231 PyObject* retval;
232 wxString string;
233
234 if (!PySequence_Check(pyPoints)) {
235 goto err0;
236 }
237 if (!PySequence_Check(textList)) {
238 goto err1;
239 }
240 if (!PySequence_Check(foregroundList)) {
241 goto err2;
242 }
243 if (!PySequence_Check(backgroundList)) {
244 goto err3;
245 }
246 numPoints = PySequence_Length(pyPoints);
247 numText = PySequence_Length(textList);
248 numForeground = PySequence_Length(foregroundList);
249 numBackground = PySequence_Length(backgroundList);
250
251 for (i = 0; i < numPoints; i++) {
252 // Use a new string ?
253 if (i < numText) {
254 if ( isFastText ) {
255 obj = PySequence_Fast_GET_ITEM(textList, i);
256 }
257 else {
258 obj = PySequence_GetItem(textList, i);
259 }
260 if (! PyString_Check(obj) ) {
261 Py_DECREF(obj);
262 goto err1;
263 }
264 string = Py2wxString(obj);
265 if ( !isFastText )
266 Py_DECREF(obj);
267 }
268
269 if (i < numForeground) {
270 // Use a new foreground ?
271 if ( isFastForeground ) {
272 obj = PySequence_Fast_GET_ITEM(foregroundList, i);
273 }
274 else {
275 obj = PySequence_GetItem(foregroundList, i);
276 }
277 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) {
278 if (!isFastForeground)
279 Py_DECREF(obj);
280 goto err2;
281 }
282 dc.SetTextForeground(*color);
283 if ( !isFastForeground )
284 Py_DECREF(obj);
285 }
286
287 if (i < numBackground) {
288 // Use a new background ?
289 if ( isFastBackground ) {
290 obj = PySequence_Fast_GET_ITEM(backgroundList, i);
291 }
292 else {
293 obj = PySequence_GetItem(backgroundList, i);
294 }
295 if (! wxPyConvertSwigPtr(obj, (void **) &color, wxT("wxColour"))) {
296 if (!isFastBackground)
297 Py_DECREF(obj);
298 goto err3;
299 }
300 dc.SetTextBackground(*color);
301 if ( !isFastBackground )
302 Py_DECREF(obj);
303 }
304
305 // Get the point coordinates
306 if (isFastSeq) {
307 obj = PySequence_Fast_GET_ITEM(pyPoints, i);
308 }
309 else {
310 obj = PySequence_GetItem(pyPoints, i);
311 }
312 if (! wxPy2int_seq_helper(obj, &x1, &y1)) {
313 if (! isFastSeq)
314 Py_DECREF(obj);
315 goto err0;
316 }
317 if (PyErr_Occurred()) {
318 retval = NULL;
319 if (!isFastSeq)
320 Py_DECREF(obj);
321 goto exit;
322 }
323
324
325 // Now draw the text
326 dc.DrawText(string, x1, y1);
327
328 if (!isFastText)
329 Py_DECREF(obj);
330 }
331
332 Py_INCREF(Py_None);
333 retval = Py_None;
334 goto exit;
335
336 err0:
337 PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences.");
338 retval = NULL;
339 goto exit;
340 err1:
341 PyErr_SetString(PyExc_TypeError, "Expected a sequence of strings");
342 retval = NULL;
343 goto exit;
344
345 err2:
346 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for foregrounds");
347 retval = NULL;
348 goto exit;
349
350 err3:
351 PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for backgrounds");
352 retval = NULL;
353 goto exit;
354
355 exit:
356 wxPyEndBlockThreads(blocked);
357 return retval;
358 }
359
360
361
362 //---------------------------------------------------------------------------