==Sequencer==
[blender-staging.git] / source / blender / python / api2_2x / windowTheme.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32
33 #include "windowTheme.h" /*This must come first*/
34
35 #include "BLI_blenlib.h"
36 #include "MEM_guardedalloc.h"
37 #include "charRGBA.h"
38 #include "gen_utils.h"
39
40 #define EXPP_THEME_VTX_SIZE_MIN 1
41 #define EXPP_THEME_VTX_SIZE_MAX 10
42 #define EXPP_THEME_FDOT_SIZE_MIN 1
43 #define EXPP_THEME_FDOT_SIZE_MAX 10
44 #define EXPP_THEME_DRAWTYPE_MIN 1
45 #define EXPP_THEME_DRAWTYPE_MAX 4
46
47 #define EXPP_THEME_NUMBEROFTHEMES 15
48 static const EXPP_map_pair themes_map[] = {
49         {"ui", -1},
50         {"buts", SPACE_BUTS},
51         {"view3d", SPACE_VIEW3D},
52         {"file", SPACE_FILE},
53         {"ipo", SPACE_IPO},
54         {"info", SPACE_INFO},
55         {"sound", SPACE_SOUND},
56         {"action", SPACE_ACTION},
57         {"nla", SPACE_NLA},
58         {"seq", SPACE_SEQ},
59         {"image", SPACE_IMAGE},
60         {"imasel", SPACE_IMASEL},
61         {"text", SPACE_TEXT},
62         {"oops", SPACE_OOPS},
63         {"time", SPACE_TIME},
64         {NULL, 0}
65 };
66
67 static PyObject *M_Theme_New( PyObject * self, PyObject * args );
68 static PyObject *M_Theme_Get( PyObject * self, PyObject * args );
69
70 static char M_Theme_doc[] = "The Blender Theme module\n\n\
71 This module provides access to UI Theme data in Blender";
72
73 static char M_Theme_New_doc[] = "Theme.New (name = 'New Theme',\
74 theme = <default>):\n\
75         Return a new Theme Data object.\n\
76 (name) - string: the Theme's name, it defaults to 'New Theme';\n\
77 (theme) - bpy Theme: a base Theme to copy all data from, it defaults to the\n\
78 current one.";
79
80 static char M_Theme_Get_doc[] = "Theme.Get (name = None):\n\
81         Return the theme data with the given 'name', None if not found, or\n\
82         Return a list with all Theme Data objects if no argument was given.";
83
84 /*****************************************************************************/
85 /* Python method structure definition for Blender.Theme module:            */
86 /*****************************************************************************/
87 struct PyMethodDef M_Theme_methods[] = {
88         {"New", M_Theme_New, METH_VARARGS, M_Theme_New_doc},
89         {"Get", M_Theme_Get, METH_VARARGS, M_Theme_Get_doc},
90         {NULL, NULL, 0, NULL}
91 };
92
93 static void ThemeSpace_dealloc( BPy_ThemeSpace * self );
94 static int ThemeSpace_compare( BPy_ThemeSpace * a, BPy_ThemeSpace * b );
95 static PyObject *ThemeSpace_repr( BPy_ThemeSpace * self );
96 static PyObject *ThemeSpace_getAttr( BPy_ThemeSpace * self, char *name );
97 static int ThemeSpace_setAttr( BPy_ThemeSpace * self, char *name,
98                                PyObject * val );
99
100 static PyMethodDef BPy_ThemeSpace_methods[] = {
101         {NULL, NULL, 0, NULL}
102 };
103
104 PyTypeObject ThemeSpace_Type = {
105         PyObject_HEAD_INIT( NULL ) 0,   /* ob_size */
106         "Blender Space Theme",  /* tp_name */
107         sizeof( BPy_ThemeSpace ),       /* tp_basicsize */
108         0,                      /* tp_itemsize */
109         /* methods */
110         ( destructor ) ThemeSpace_dealloc,      /* tp_dealloc */
111         0,                      /* tp_print */
112         ( getattrfunc ) ThemeSpace_getAttr,     /* tp_getattr */
113         ( setattrfunc ) ThemeSpace_setAttr,     /* tp_setattr */
114         ( cmpfunc ) ThemeSpace_compare, /* tp_compare */
115         ( reprfunc ) ThemeSpace_repr,   /* tp_repr */
116         0,                      /* tp_as_number */
117         0,                      /* tp_as_sequence */
118         0,                      /* tp_as_mapping */
119         0,                      /* tp_as_hash */
120         0, 0, 0, 0, 0, 0,
121         0,                      /* tp_doc */
122         0, 0, 0, 0, 0, 0,
123         0,                      //BPy_ThemeSpace_methods,            /* tp_methods */
124         0,                      /* tp_members */
125         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
126 };
127
128 static void ThemeSpace_dealloc( BPy_ThemeSpace * self )
129 {
130         PyObject_DEL( self );
131 }
132
133 #define ELSEIF_TSP_RGBA(attr)\
134         else if (!strcmp(name, #attr))\
135                 attrib = charRGBA_New(&tsp->attr[0]);
136
137 /* Example: ELSEIF_TSP_RGBA(back) becomes:
138  * else if (!strcmp(name, "back")
139  *      attrib = charRGBA_New(&tsp->back[0])
140  */
141
142 static PyObject *ThemeSpace_getAttr( BPy_ThemeSpace * self, char *name )
143 {
144         PyObject *attrib = Py_None;
145         ThemeSpace *tsp = self->tsp;
146
147         if( !strcmp( name, "theme" ) )
148                 attrib = PyString_FromString( self->theme->name );
149                 ELSEIF_TSP_RGBA( back )
150                 ELSEIF_TSP_RGBA( text )
151                 ELSEIF_TSP_RGBA( text_hi )
152                 ELSEIF_TSP_RGBA( header )
153                 ELSEIF_TSP_RGBA( panel )
154                 ELSEIF_TSP_RGBA( shade1 )
155                 ELSEIF_TSP_RGBA( shade2 )
156                 ELSEIF_TSP_RGBA( hilite )
157                 ELSEIF_TSP_RGBA( grid )
158                 ELSEIF_TSP_RGBA( wire )
159                 ELSEIF_TSP_RGBA( lamp )
160                 ELSEIF_TSP_RGBA( select )
161                 ELSEIF_TSP_RGBA( active )
162                 ELSEIF_TSP_RGBA( transform )
163                 ELSEIF_TSP_RGBA( vertex )
164                 ELSEIF_TSP_RGBA( vertex_select )
165                 ELSEIF_TSP_RGBA( edge )
166                 ELSEIF_TSP_RGBA( edge_select )
167                 ELSEIF_TSP_RGBA( edge_seam )
168                 ELSEIF_TSP_RGBA( edge_facesel )
169                 ELSEIF_TSP_RGBA( face )
170                 ELSEIF_TSP_RGBA( face_select )
171                 ELSEIF_TSP_RGBA( face_dot )
172                 ELSEIF_TSP_RGBA( normal )
173                 ELSEIF_TSP_RGBA( bone_solid )
174                 ELSEIF_TSP_RGBA( bone_pose )
175                 ELSEIF_TSP_RGBA( strip )
176                 ELSEIF_TSP_RGBA( strip_select )
177                 ELSEIF_TSP_RGBA( syntaxl )
178                 ELSEIF_TSP_RGBA( syntaxn )
179                 ELSEIF_TSP_RGBA( syntaxb )
180                 ELSEIF_TSP_RGBA( syntaxv )
181                 ELSEIF_TSP_RGBA( syntaxc )
182                 ELSEIF_TSP_RGBA( movie )
183                 ELSEIF_TSP_RGBA( image )
184                 ELSEIF_TSP_RGBA( scene )
185                 ELSEIF_TSP_RGBA( audio )
186                 ELSEIF_TSP_RGBA( effect )
187                 ELSEIF_TSP_RGBA( plugin )
188                 ELSEIF_TSP_RGBA( transition )
189                 ELSEIF_TSP_RGBA( meta )
190                 else if( !strcmp( name, "vertex_size" ) )
191                 attrib = Py_BuildValue( "i", tsp->vertex_size );
192                 else if( !strcmp( name, "facedot_size" ) )
193                 attrib = Py_BuildValue( "i", tsp->facedot_size );
194         else if( !strcmp( name, "__members__" ) )
195                 attrib = Py_BuildValue("[sssssssssssssssssssssssssssssssssssssssssss]", "theme",
196                                         "back", "text", "text_hi", "header",
197                                         "panel", "shade1", "shade2", "hilite",
198                                         "grid", "wire", "lamp", "select", "active",
199                                         "transform", "vertex", "vertex_select",
200                                         "edge", "edge_select", "edge_seam",
201                                         "edge_facesel", "face", "face_select",
202                                         "face_dot", "normal", "bone_solid", "bone_pose",
203                                         "strip", "strip_select",
204                                         "syntaxl", "syntaxn", "syntaxb", "syntaxv", "syntaxc",
205                                         "movie", "image", "scene", "audio", "effect", "plugin", "transition", "meta", 
206                                         "vertex_size", "facedot_size" );
207
208         if( attrib != Py_None )
209                 return attrib;
210
211         return Py_FindMethod( BPy_ThemeSpace_methods, ( PyObject * ) self,
212                               name );
213 }
214
215 static int ThemeSpace_setAttr( BPy_ThemeSpace * self, char *name,
216                                PyObject * value )
217 {
218         PyObject *attrib = NULL;
219         ThemeSpace *tsp = self->tsp;
220         int ret = -1;
221
222         if( !strcmp( name, "back" ) )
223                 attrib = charRGBA_New( &tsp->back[0] );
224                 ELSEIF_TSP_RGBA( text )
225                 ELSEIF_TSP_RGBA( text_hi )
226                 ELSEIF_TSP_RGBA( header )
227                 ELSEIF_TSP_RGBA( panel )
228                 ELSEIF_TSP_RGBA( shade1 )
229                 ELSEIF_TSP_RGBA( shade2 )
230                 ELSEIF_TSP_RGBA( hilite )
231                 ELSEIF_TSP_RGBA( grid )
232                 ELSEIF_TSP_RGBA( wire )
233                 ELSEIF_TSP_RGBA( lamp )
234                 ELSEIF_TSP_RGBA( select )
235                 ELSEIF_TSP_RGBA( active )
236                 ELSEIF_TSP_RGBA( transform )
237                 ELSEIF_TSP_RGBA( vertex )
238                 ELSEIF_TSP_RGBA( vertex_select )
239                 ELSEIF_TSP_RGBA( edge )
240                 ELSEIF_TSP_RGBA( edge_select )
241                 ELSEIF_TSP_RGBA( edge_seam )
242                 ELSEIF_TSP_RGBA( edge_facesel )
243                 ELSEIF_TSP_RGBA( face )
244                 ELSEIF_TSP_RGBA( face_select )
245                 ELSEIF_TSP_RGBA( face_dot )
246                 ELSEIF_TSP_RGBA( normal )
247                 ELSEIF_TSP_RGBA( bone_solid )
248                 ELSEIF_TSP_RGBA( bone_pose )
249                 ELSEIF_TSP_RGBA( strip )
250                 ELSEIF_TSP_RGBA( strip_select )
251                 ELSEIF_TSP_RGBA( syntaxl )
252                 ELSEIF_TSP_RGBA( syntaxn )
253                 ELSEIF_TSP_RGBA( syntaxb )
254                 ELSEIF_TSP_RGBA( syntaxv )
255                 ELSEIF_TSP_RGBA( syntaxc )
256                 ELSEIF_TSP_RGBA( movie )
257                 ELSEIF_TSP_RGBA( image )
258                 ELSEIF_TSP_RGBA( scene )
259                 ELSEIF_TSP_RGBA( audio )
260                 ELSEIF_TSP_RGBA( effect )
261                 ELSEIF_TSP_RGBA( plugin )
262                 ELSEIF_TSP_RGBA( transition )
263                 ELSEIF_TSP_RGBA( meta )
264                 else if( !strcmp( name, "vertex_size" ) ) {
265                 int val;
266
267                 if( !PyInt_Check( value ) )
268                         return EXPP_ReturnIntError( PyExc_TypeError,
269                                                     "expected integer value" );
270
271                 val = ( int ) PyInt_AsLong( value );
272                 tsp->vertex_size = (char)EXPP_ClampInt( val,
273                                                   EXPP_THEME_VTX_SIZE_MIN,
274                                                   EXPP_THEME_VTX_SIZE_MAX );
275                 ret = 0;
276         }
277         else if( !strcmp( name, "facedot_size" ) ) {
278                 int val;
279
280                 if( !PyInt_Check( value ) )
281                         return EXPP_ReturnIntError( PyExc_TypeError,
282                                                     "expected integer value" );
283
284                 val = ( int ) PyInt_AsLong( value );
285                 tsp->vertex_size = (char)EXPP_ClampInt( val,
286                                                   EXPP_THEME_FDOT_SIZE_MIN,
287                                                   EXPP_THEME_FDOT_SIZE_MAX );
288                 ret = 0;
289         } else
290                 return EXPP_ReturnIntError( PyExc_AttributeError,
291                                             "attribute not found" );
292
293         if( attrib ) {
294                 PyObject *pyret = NULL;
295                 PyObject *valtuple = Py_BuildValue( "(O)", value );
296
297                 if( !valtuple )
298                         return EXPP_ReturnIntError( PyExc_MemoryError,
299                                                     "couldn't create tuple!" );
300
301                 pyret = charRGBA_setCol( ( BPy_charRGBA * ) attrib, valtuple );
302                 Py_DECREF( valtuple );
303
304                 if( pyret == Py_None ) {
305                         Py_DECREF( Py_None );   /* was increfed by charRGBA_setCol */
306                         ret = 0;
307                 }
308
309                 Py_DECREF( attrib );    /* we're done with it */
310         }
311
312         return ret;             /* 0 if all went well */
313 }
314
315 static int ThemeSpace_compare( BPy_ThemeSpace * a, BPy_ThemeSpace * b )
316 {
317         ThemeSpace *pa = a->tsp, *pb = b->tsp;
318         return ( pa == pb ) ? 0 : -1;
319 }
320
321 static PyObject *ThemeSpace_repr( BPy_ThemeSpace * self )
322 {
323         return PyString_FromFormat( "[Space theme from theme \"%s\"]",
324                                     self->theme->name );
325 }
326
327 static void ThemeUI_dealloc( BPy_ThemeUI * self );
328 static int ThemeUI_compare( BPy_ThemeUI * a, BPy_ThemeUI * b );
329 static PyObject *ThemeUI_repr( BPy_ThemeUI * self );
330 static PyObject *ThemeUI_getAttr( BPy_ThemeUI * self, char *name );
331 static int ThemeUI_setAttr( BPy_ThemeUI * self, char *name, PyObject * val );
332
333 static PyMethodDef BPy_ThemeUI_methods[] = {
334         {NULL, NULL, 0, NULL}
335 };
336
337 PyTypeObject ThemeUI_Type = {
338         PyObject_HEAD_INIT( NULL ) 0,   /* ob_size */
339         "Blender UI Theme",     /* tp_name */
340         sizeof( BPy_ThemeUI ),  /* tp_basicsize */
341         0,                      /* tp_itemsize */
342         /* methods */
343         ( destructor ) ThemeUI_dealloc, /* tp_dealloc */
344         0,                      /* tp_print */
345         ( getattrfunc ) ThemeUI_getAttr,        /* tp_getattr */
346         ( setattrfunc ) ThemeUI_setAttr,        /* tp_setattr */
347         ( cmpfunc ) ThemeUI_compare,    /* tp_compare */
348         ( reprfunc ) ThemeUI_repr,      /* tp_repr */
349         0,                      /* tp_as_number */
350         0,                      /* tp_as_sequence */
351         0,                      /* tp_as_mapping */
352         0,                      /* tp_as_hash */
353         0, 0, 0, 0, 0, 0,
354         0,                      /* tp_doc */
355         0, 0, 0, 0, 0, 0,
356         0,                      //BPy_ThemeUI_methods,         /* tp_methods */
357         0,                      /* tp_members */
358         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
359 };
360
361 static void ThemeUI_dealloc( BPy_ThemeUI * self )
362 {
363         PyObject_DEL( self );
364 }
365
366 #define ELSEIF_TUI_RGBA(attr)\
367         else if (!strcmp(name, #attr))\
368                 attrib = charRGBA_New(&tui->attr[0]);
369
370 /* Example: ELSEIF_TUI_RGBA(outline) becomes:
371  * else if (!strcmp(name, "outline")
372  *      attr = charRGBA_New(&tui->outline[0])
373  */
374
375 static PyObject *ThemeUI_getAttr( BPy_ThemeUI * self, char *name )
376 {
377         PyObject *attrib = Py_None;
378         ThemeUI *tui = self->tui;
379
380         if( !strcmp( name, "theme" ) )
381                 attrib = PyString_FromString( self->theme->name );
382         ELSEIF_TUI_RGBA( outline )
383                 ELSEIF_TUI_RGBA( neutral )
384                 ELSEIF_TUI_RGBA( action )
385                 ELSEIF_TUI_RGBA( setting )
386                 ELSEIF_TUI_RGBA( setting1 )
387                 ELSEIF_TUI_RGBA( setting2 )
388                 ELSEIF_TUI_RGBA( num )
389                 ELSEIF_TUI_RGBA( textfield )
390                 ELSEIF_TUI_RGBA( textfield_hi )
391                 ELSEIF_TUI_RGBA( popup )
392                 ELSEIF_TUI_RGBA( text )
393                 ELSEIF_TUI_RGBA( text_hi )
394                 ELSEIF_TUI_RGBA( menu_back )
395                 ELSEIF_TUI_RGBA( menu_item )
396                 ELSEIF_TUI_RGBA( menu_hilite )
397                 ELSEIF_TUI_RGBA( menu_text )
398                 ELSEIF_TUI_RGBA( menu_text_hi )
399                 else if( !strcmp( name, "drawType" ) )
400                 attrib = PyInt_FromLong( ( char ) tui->but_drawtype );
401         else if( !strcmp( name, "__members__" ) )
402                 attrib = Py_BuildValue( "[ssssssssssssssssss]", "theme",
403                                         "outline", "neutral", "action",
404                                         "setting", "setting1", "setting2",
405                                         "num", "textfield", "textfield_hi", "popup", "text",
406                                         "text_hi", "menu_back", "menu_item",
407                                         "menu_hilite", "menu_text",
408                                         "menu_text_hi", "drawType" );
409
410         if( attrib != Py_None )
411                 return attrib;
412
413         return Py_FindMethod( BPy_ThemeUI_methods, ( PyObject * ) self, name );
414 }
415
416 static int ThemeUI_setAttr( BPy_ThemeUI * self, char *name, PyObject * value )
417 {
418         PyObject *attrib = NULL;
419         ThemeUI *tui = self->tui;
420         int ret = -1;
421
422         if( !strcmp( name, "outline" ) )
423                 attrib = charRGBA_New( &tui->outline[0] );
424         ELSEIF_TUI_RGBA( neutral )
425                 ELSEIF_TUI_RGBA( action )
426                 ELSEIF_TUI_RGBA( setting )
427                 ELSEIF_TUI_RGBA( setting1 )
428                 ELSEIF_TUI_RGBA( setting2 )
429                 ELSEIF_TUI_RGBA( num )
430                 ELSEIF_TUI_RGBA( textfield )
431                 ELSEIF_TUI_RGBA( textfield_hi )
432                 ELSEIF_TUI_RGBA( popup )
433                 ELSEIF_TUI_RGBA( text )
434                 ELSEIF_TUI_RGBA( text_hi )
435                 ELSEIF_TUI_RGBA( menu_back )
436                 ELSEIF_TUI_RGBA( menu_item )
437                 ELSEIF_TUI_RGBA( menu_hilite )
438                 ELSEIF_TUI_RGBA( menu_text )
439                 ELSEIF_TUI_RGBA( menu_text_hi )
440                 else if( !strcmp( name, "drawType" ) ) {
441                 int val;
442
443                 if( !PyInt_Check( value ) )
444                         return EXPP_ReturnIntError( PyExc_TypeError,
445                                                     "expected integer value" );
446
447                 val = ( int ) PyInt_AsLong( value );
448                 tui->but_drawtype = (char)EXPP_ClampInt( val,
449                                                    EXPP_THEME_DRAWTYPE_MIN,
450                                                    EXPP_THEME_DRAWTYPE_MAX );
451                 ret = 0;
452         } else
453                 return EXPP_ReturnIntError( PyExc_AttributeError,
454                                             "attribute not found" );
455
456         if( attrib ) {
457                 PyObject *pyret = NULL;
458                 PyObject *valtuple = Py_BuildValue( "(O)", value );
459
460                 if( !valtuple )
461                         return EXPP_ReturnIntError( PyExc_MemoryError,
462                                                     "couldn't create tuple!" );
463
464                 pyret = charRGBA_setCol( ( BPy_charRGBA * ) attrib, valtuple );
465                 Py_DECREF( valtuple );
466
467                 if( pyret == Py_None ) {
468                         Py_DECREF( Py_None );   /* was increfed by charRGBA_setCol */
469                         ret = 0;
470                 }
471
472                 Py_DECREF( attrib );    /* we're done with it */
473         }
474
475         return ret;             /* 0 if all went well */
476 }
477
478
479 static int ThemeUI_compare( BPy_ThemeUI * a, BPy_ThemeUI * b )
480 {
481         ThemeUI *pa = a->tui, *pb = b->tui;
482         return ( pa == pb ) ? 0 : -1;
483 }
484
485 static PyObject *ThemeUI_repr( BPy_ThemeUI * self )
486 {
487         return PyString_FromFormat( "[UI theme from theme \"%s\"]",
488                                     self->theme->name );
489 }
490
491 static void Theme_dealloc( BPy_Theme * self );
492 static int Theme_compare( BPy_Theme * a, BPy_Theme * b );
493 static PyObject *Theme_getAttr( BPy_Theme * self, char *name );
494 static PyObject *Theme_repr( BPy_Theme * self );
495
496 static PyObject *Theme_get( BPy_Theme * self, PyObject * args );
497 static PyObject *Theme_getName( BPy_Theme * self );
498 static PyObject *Theme_setName( BPy_Theme * self, PyObject * args );
499
500 static PyMethodDef BPy_Theme_methods[] = {
501         {"get", ( PyCFunction ) Theme_get, METH_VARARGS,
502          "(param) - Return UI or Space theme object.\n\
503 (param) - the chosen theme object as an int or a string:\n\
504 - () - default: UI;\n\
505 - (i) - int: an entry from the Blender.Window.Types dictionary;\n\
506 - (s) - string: 'UI' or a space name, like 'VIEW3D', etc."},
507         {"getName", ( PyCFunction ) Theme_getName, METH_NOARGS,
508          "() - Return Theme name"},
509         {"setName", ( PyCFunction ) Theme_setName, METH_VARARGS,
510          "(s) - Set Theme name"},
511         {NULL, NULL, 0, NULL}
512 };
513
514 PyTypeObject Theme_Type = {
515         PyObject_HEAD_INIT( NULL ) 
516         0,      /* ob_size */
517         "Blender Theme",        /* tp_name */
518         sizeof( BPy_Theme ),    /* tp_basicsize */
519         0,                      /* tp_itemsize */
520         /* methods */
521         ( destructor ) Theme_dealloc,   /* tp_dealloc */
522         0,                      /* tp_print */
523         ( getattrfunc ) Theme_getAttr,  /* tp_getattr */
524         0,                      //(setattrfunc) Theme_setAttr,        /* tp_setattr */
525         ( cmpfunc ) Theme_compare,      /* tp_compare */
526         ( reprfunc ) Theme_repr,        /* tp_repr */
527         0,                      /* tp_as_number */
528         0,                      /* tp_as_sequence */
529         0,                      /* tp_as_mapping */
530         0,                      /* tp_as_hash */
531         0, 0, 0, 0, 0, 0,
532         0,                      /* tp_doc */
533         0, 0, 0, 0, 0, 0,
534         0,                      /*BPy_Theme_methods,*/ /* tp_methods */
535         0,                      /* tp_members */
536         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
537 };
538
539 static PyObject *M_Theme_New( PyObject * self, PyObject * args )
540 {
541         char *name = "New Theme";
542         BPy_Theme *pytheme = NULL, *base_pytheme = NULL;
543         bTheme *btheme = NULL, *newtheme = NULL;
544
545         if( !PyArg_ParseTuple
546             ( args, "|sO!", &name, &Theme_Type, &base_pytheme ) )
547                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
548                                               "expected nothing or a name and optional theme object as arguments" );
549
550         if( base_pytheme )
551                 btheme = base_pytheme->theme;
552         if( !btheme )
553                 btheme = U.themes.first;
554
555         newtheme = MEM_callocN( sizeof( bTheme ), "theme" );
556
557         if( newtheme )
558                 pytheme = PyObject_New( BPy_Theme, &Theme_Type );
559         if( !pytheme )
560                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
561                                               "couldn't create Theme Data in Blender" );
562
563         memcpy( newtheme, btheme, sizeof( bTheme ) );
564         BLI_addhead( &U.themes, newtheme );
565         BLI_strncpy( newtheme->name, name, 32 );
566
567         pytheme->theme = newtheme;
568
569         return ( PyObject * ) pytheme;
570 }
571
572 static PyObject *M_Theme_Get( PyObject * self, PyObject * args )
573 {
574         char *name = NULL;
575         bTheme *iter;
576         PyObject *ret;
577
578         if( !PyArg_ParseTuple( args, "|s", &name ) )
579                 return EXPP_ReturnPyObjError( PyExc_TypeError,
580                                               "expected string argument (or nothing)" );
581
582         iter = U.themes.first;
583
584         if( name ) {            /* (name) - return requested theme */
585                 BPy_Theme *wanted = NULL;
586
587                 while( iter ) {
588                         if( strcmp( name, iter->name ) == 0 ) {
589                                 wanted = PyObject_New( BPy_Theme,
590                                                        &Theme_Type );
591                                 wanted->theme = iter;
592                                 break;
593                         }
594                         iter = iter->next;
595                 }
596
597                 if( !wanted ) {
598                         char emsg[64];
599                         PyOS_snprintf( emsg, sizeof( emsg ),
600                                        "Theme \"%s\" not found", name );
601                         return EXPP_ReturnPyObjError( PyExc_NameError, emsg );
602                 }
603
604                 ret = ( PyObject * ) wanted;
605         }
606
607         else {                  /* () - return list with all themes */
608                 int index = 0;
609                 PyObject *list = NULL;
610                 BPy_Theme *pytheme = NULL;
611
612                 list = PyList_New( BLI_countlist( &( U.themes ) ) );
613
614                 if( !list )
615                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
616                                                       "couldn't create PyList" );
617
618                 while( iter ) {
619                         pytheme = PyObject_New( BPy_Theme, &Theme_Type );
620                         pytheme->theme = iter;
621
622                         if( !pytheme )
623                                 return EXPP_ReturnPyObjError
624                                         ( PyExc_MemoryError,
625                                           "couldn't create Theme PyObject" );
626
627                         PyList_SET_ITEM( list, index, ( PyObject * ) pytheme );
628
629                         iter = iter->next;
630                         index++;
631                 }
632
633                 ret = list;
634         }
635
636         return ret;
637 }
638
639 static PyObject *Theme_get( BPy_Theme * self, PyObject * args )
640 {
641         bTheme *btheme = self->theme;
642         ThemeUI *tui = NULL;
643         ThemeSpace *tsp = NULL;
644         PyObject *pyob = NULL;
645         BPy_ThemeUI *retUI = NULL;
646         BPy_ThemeSpace *retSpc = NULL;
647         int type;
648
649         if( !PyArg_ParseTuple( args, "|O", &pyob ) )
650                 return EXPP_ReturnPyObjError( PyExc_TypeError,
651                                               "expected string or int argument or nothing" );
652
653         if( !pyob ) {           /* (): return list with all names */
654                 PyObject *ret = PyList_New( EXPP_THEME_NUMBEROFTHEMES );
655
656                 if( !ret )
657                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
658                                                       "couldn't create pylist!" );
659
660                 type = 0;       /* using as a counter only */
661
662                 while( type < EXPP_THEME_NUMBEROFTHEMES ) {
663                         PyList_SET_ITEM( ret, type,
664                                          PyString_FromString( themes_map[type].
665                                                               sval ) );
666                         type++;
667                 }
668
669                 return ret;
670         }
671
672         else if( PyInt_Check( pyob ) )  /* (int) */
673                 type = ( int ) PyInt_AsLong( pyob );
674         else if( PyString_Check( pyob ) ) {     /* (str) */
675                 char *str = PyString_AsString( pyob );
676                 if( !EXPP_map_case_getIntVal( themes_map, str, &type ) )
677                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
678                                                       "unknown string argument" );
679         } else
680                 return EXPP_ReturnPyObjError( PyExc_TypeError,
681                                               "expected string or int argument or nothing" );
682
683         switch ( type ) {
684         case -1:                /* UI */
685                 tui = &btheme->tui;
686                 break;
687         case SPACE_BUTS:
688                 tsp = &btheme->tbuts;
689                 break;
690         case SPACE_VIEW3D:
691                 tsp = &btheme->tv3d;
692                 break;
693         case SPACE_FILE:
694                 tsp = &btheme->tfile;
695                 break;
696         case SPACE_IPO:
697                 tsp = &btheme->tipo;
698                 break;
699         case SPACE_INFO:
700                 tsp = &btheme->tinfo;
701                 break;
702         case SPACE_SOUND:
703                 tsp = &btheme->tsnd;
704                 break;
705         case SPACE_ACTION:
706                 tsp = &btheme->tact;
707                 break;
708         case SPACE_NLA:
709                 tsp = &btheme->tnla;
710                 break;
711         case SPACE_SEQ:
712                 tsp = &btheme->tseq;
713                 break;
714         case SPACE_IMAGE:
715                 tsp = &btheme->tima;
716                 break;
717         case SPACE_IMASEL:
718                 tsp = &btheme->timasel;
719                 break;
720         case SPACE_TEXT:
721                 tsp = &btheme->text;
722                 break;
723         case SPACE_OOPS:
724                 tsp = &btheme->toops;
725                 break;
726         case SPACE_TIME:
727                 tsp = &btheme->ttime;
728                 break;
729         }
730
731         if( tui ) {
732                 retUI = PyObject_New( BPy_ThemeUI, &ThemeUI_Type );
733                 retUI->theme = btheme;
734                 retUI->tui = tui;
735                 return ( PyObject * ) retUI;
736         } else if( tsp ) {
737                 retSpc = PyObject_New( BPy_ThemeSpace, &ThemeSpace_Type );
738                 retSpc->theme = btheme;
739                 retSpc->tsp = tsp;
740                 return ( PyObject * ) retSpc;
741         } else
742                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
743                                               "invalid parameter" );
744 }
745
746 static PyObject *Theme_getName( BPy_Theme * self )
747 {
748         return PyString_FromString( self->theme->name );
749 }
750
751 static PyObject *Theme_setName( BPy_Theme * self, PyObject * args )
752 {
753         char *name = NULL;
754
755         if( !PyArg_ParseTuple( args, "s", &name ) )
756                 return EXPP_ReturnPyObjError( PyExc_TypeError,
757                                               "expected string argument" );
758
759         BLI_strncpy( self->theme->name, name, 32 );
760
761         return EXPP_incr_ret( Py_None );
762 }
763
764 PyObject *Theme_Init( void )
765 {
766         PyObject *submodule;
767
768         Theme_Type.ob_type = &PyType_Type;
769
770         submodule = Py_InitModule3( "Blender.Window.Theme",
771                                     M_Theme_methods, M_Theme_doc );
772
773         return submodule;
774 }
775
776 static void Theme_dealloc( BPy_Theme * self )
777 {
778         PyObject_DEL( self );
779 }
780
781 static PyObject *Theme_getAttr( BPy_Theme * self, char *name )
782 {
783         PyObject *attr = Py_None;
784
785         if( !strcmp( name, "name" ) )
786                 attr = PyString_FromString( self->theme->name );
787         else if( !strcmp( name, "__members__" ) )
788                 attr = Py_BuildValue( "[s]", "name" );
789
790         if( attr != Py_None )
791                 return attr;
792
793         return Py_FindMethod( BPy_Theme_methods, ( PyObject * ) self, name );
794 }
795
796 static int Theme_compare( BPy_Theme * a, BPy_Theme * b )
797 {
798         bTheme *pa = a->theme, *pb = b->theme;
799         return ( pa == pb ) ? 0 : -1;
800 }
801
802 static PyObject *Theme_repr( BPy_Theme * self )
803 {
804         return PyString_FromFormat( "[Theme \"%s\"]", self->theme->name );
805 }