diff options
-rw-r--r-- | release/scripts/save_theme.py | 75 | ||||
-rw-r--r-- | source/blender/python/SConscript | 58 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Blender.c | 8 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Image.c | 36 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Object.c | 11 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Window.c | 5 | ||||
-rw-r--r-- | source/blender/python/api2_2x/charRGBA.c | 398 | ||||
-rw-r--r-- | source/blender/python/api2_2x/charRGBA.h | 60 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/API_intro.py | 6 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Blender.py | 11 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Object.py | 19 | ||||
-rw-r--r-- | source/blender/python/api2_2x/gen_utils.c | 25 | ||||
-rw-r--r-- | source/blender/python/api2_2x/gen_utils.h | 14 | ||||
-rw-r--r-- | source/blender/python/api2_2x/modules.h | 1 | ||||
-rw-r--r-- | source/blender/python/api2_2x/windowTheme.c | 706 | ||||
-rw-r--r-- | source/blender/python/api2_2x/windowTheme.h | 60 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 7 |
17 files changed, 1441 insertions, 59 deletions
diff --git a/release/scripts/save_theme.py b/release/scripts/save_theme.py new file mode 100644 index 00000000000..73c23087cec --- /dev/null +++ b/release/scripts/save_theme.py @@ -0,0 +1,75 @@ +#!BPY + +""" +Name: 'Save Current Theme' +Blender: 234 +Group: 'Help' +Tooltip: 'Save current theme as a bpython script' +""" + +# $Id$ +# +# -------------------------------------------------------------------------- +# save_theme version 2.34 Sep 20, 2004 +# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br +# -------------------------------------------------------------------------- +# Released under the Blender Artistic License (BAL): +# http://download.blender.org/documentation/html/x21254.html +# +# The scripts generated by this script are put under Public Domain by +# default, but you are free to edit the ones you generate with this script +# and change their license to another one of your choice. +# -------------------------------------------------------------------------- + +import Blender +from Blender.Window import Theme, FileSelector + +theme = Theme.Get()[0] # get current theme + +# default filename: theme's name + '_theme.py' in user's scripts dir: +default_fname = Blender.Get("scriptsdir") +default_fname = Blender.sys.join(default_fname, theme.name + '_theme.py') + +def write_theme(filename): + "Write the current theme as a bpython script" + + if filename.find('.py', -3) <= 0: filename += '.py' + + fout = file(filename, "w") + + fout.write("""#!BPY + +\"\"\" +Name: '%s' +Blender: 234 +Group: 'Theme' +Tooltip: 'Change current theme' +\"\"\" + +# This script was automatically generated by the save_theme.py bpython script. +# By default, these generated scripts are released as Public Domain, but you +# are free to change the license of the scripts you generate with +# save_theme.py before releasing them. + +import Blender +from Blender.Window import Theme + +theme = Theme.New('%s') +""" % (theme.name, theme.name)) + + for tsp in theme.get(): # + command = "\n%s = theme.get('%s')" % (tsp, tsp) + fout.write(command + "\n") + exec(command) + exec("vars = dir(%s)" % tsp) + vars.remove('theme') + + for var in vars: + v = "%s.%s" % (tsp, var) + exec("value = %s" % v) + fout.write("%s = %s\n" % (v, value)) + + fout.write('\nBlender.Redraw(-1)') + fout.close() + +FileSelector(write_theme, "Save Current Theme", default_fname) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 9e6d7a057fc..0b7a62d44c0 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -7,54 +7,56 @@ python_env = library_env.Copy () source_files = ['BPY_interface.c', 'BPY_menus.c', + 'api2_2x/Armature.c', + 'api2_2x/BezTriple.c', + 'api2_2x/BGL.c', 'api2_2x/Blender.c', - 'api2_2x/Sys.c', - 'api2_2x/Registry.c', - 'api2_2x/Scene.c', - 'api2_2x/Types.c', - 'api2_2x/Object.c', - 'api2_2x/NMesh.c', - 'api2_2x/Material.c', + 'api2_2x/Bone.c', + 'api2_2x/Build.c', 'api2_2x/Camera.c', - 'api2_2x/World.c', - 'api2_2x/Lamp.c', - 'api2_2x/Lattice.c', - 'api2_2x/Library.c', 'api2_2x/CurNurb.c', 'api2_2x/Curve.c', - 'api2_2x/Armature.c', - 'api2_2x/Bone.c', - 'api2_2x/Ipo.c', + 'api2_2x/Draw.c', + 'api2_2x/Effect.c', + 'api2_2x/EXPP_interface.c', 'api2_2x/Ipocurve.c', - 'api2_2x/BezTriple.c', + 'api2_2x/Ipo.c', + 'api2_2x/Lamp.c', + 'api2_2x/Lattice.c', + 'api2_2x/Library.c', + 'api2_2x/MTex.c', + 'api2_2x/Material.c', + 'api2_2x/Mathutils.c', 'api2_2x/Metaball.c', 'api2_2x/NLA.c', - 'api2_2x/Effect.c', + 'api2_2x/Noise.c', + 'api2_2x/NMesh.c', + 'api2_2x/Object.c', 'api2_2x/Particle.c', + 'api2_2x/Registry.c', + 'api2_2x/Scene.c', + 'api2_2x/Sound.c', + 'api2_2x/Sys.c', + 'api2_2x/Types.c', 'api2_2x/Wave.c', - 'api2_2x/Build.c', - 'api2_2x/Image.c', 'api2_2x/Window.c', - 'api2_2x/Draw.c', - 'api2_2x/BGL.c', + 'api2_2x/World.c', + 'api2_2x/Image.c', 'api2_2x/Text.c', 'api2_2x/Texture.c', - 'api2_2x/MTex.c', 'api2_2x/Noise.c', - 'api2_2x/vector.c', + 'api2_2x/charRGBA.c', 'api2_2x/constant.c', + 'api2_2x/euler.c', + 'api2_2x/gen_utils.c', 'api2_2x/logic.c', 'api2_2x/matrix.c', - 'api2_2x/euler.c', 'api2_2x/quat.c', - 'api2_2x/Mathutils.c', 'api2_2x/rgbTuple.c', - 'api2_2x/gen_utils.c', 'api2_2x/sceneRender.c', 'api2_2x/sceneRadio.c', - 'api2_2x/EXPP_interface.c', - 'api2_2x/Noise.c', - 'api2_2x/Sound.c'] + 'api2_2x/vector.c', + 'api2_2x/windowTheme.c'] python_env.Append (CPPPATH = ['api2_2x', '../blenkernel', diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index c4ca58ceed3..0cb848fc76b 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -99,6 +99,7 @@ static char Blender_Get_doc[] = 'endframe' - Returns the end frame of the animation\n\ 'filename' - Returns the name of the last file read or written\n\ 'datadir' - Returns the dir where scripts can save their data, if available\n\ + 'scriptsdir' - Returns the main dir where scripts are kept, if available\n\ 'version' - Returns the Blender version number"; static char Blender_Redraw_doc[] = "() - Redraw all 3D windows"; @@ -236,6 +237,13 @@ static PyObject *Blender_Get (PyObject *self, PyObject *args) if (BLI_exists(datadir)) return PyString_FromString(datadir); else return EXPP_incr_ret (Py_None); } + if (StringEqual (str, "scriptsdir")) + { + char scriptsdir[FILE_MAXDIR]; + BLI_make_file_string("/", scriptsdir, bpy_gethome(), "scripts/"); + if (BLI_exists(scriptsdir)) return PyString_FromString(scriptsdir); + else return EXPP_incr_ret (Py_None); + } /* According to the old file (opy_blender.c), the following if statement is a quick hack and needs some clean up. */ if (StringEqual (str, "vrmloptions")) diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c index 80ca8a38bd7..2ef745c8f9b 100644 --- a/source/blender/python/api2_2x/Image.c +++ b/source/blender/python/api2_2x/Image.c @@ -37,6 +37,7 @@ #include <BIF_drawimage.h> #include <BLI_blenlib.h> #include <IMB_imbuf_types.h> /* for the IB_rect define */ +#include <BIF_gl.h> #include "gen_utils.h" #include "Image.h" @@ -237,6 +238,7 @@ static PyObject *Image_setName(BPy_Image *self, PyObject *args); static PyObject *Image_setXRep(BPy_Image *self, PyObject *args); static PyObject *Image_setYRep(BPy_Image *self, PyObject *args); static PyObject *Image_reload(BPy_Image *self); /* by Campbell */ +static PyObject *Image_glLoad(BPy_Image *self); /*****************************************************************************/ /* Python BPy_Image methods table: */ @@ -259,6 +261,9 @@ static PyMethodDef BPy_Image_methods[] = { "() - Return Image object's bind code value"}, {"reload", (PyCFunction)Image_reload, METH_NOARGS, "() - Reload the image from the filesystem"}, + {"glLoad", (PyCFunction)Image_glLoad, METH_NOARGS, + "() - Load the image data in OpenGL texture memory.\n\ + The bindcode (int) is returned."}, {"setName", (PyCFunction)Image_setName, METH_VARARGS, "(str) - Change Image object name"}, {"setXRep", (PyCFunction)Image_setXRep, METH_VARARGS, @@ -460,6 +465,37 @@ static PyObject *Image_reload(BPy_Image *self) return Py_None; } +static PyObject *Image_glLoad(BPy_Image *self) +{ + Image *img = self->image; + unsigned int *bind = &img->bindcode; + + if (*bind == 0) { + + if (!img->ibuf) /* if no image data is available */ + load_image(img, IB_rect, "", 0); /* loading it */ + + if (!img->ibuf) /* didn't work */ + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't load image data in Blender"); + + glGenTextures(1, (GLuint *)bind); + glBindTexture(GL_TEXTURE_2D, *bind); + + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, img->ibuf->x, img->ibuf->y, + GL_RGBA, GL_UNSIGNED_BYTE, img->ibuf->rect); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->ibuf->x, img->ibuf->y, 0, + GL_RGBA, GL_UNSIGNED_BYTE, img->ibuf->rect); + } + + return PyLong_FromUnsignedLong (img->bindcode); +} + static PyObject *Image_setName(BPy_Image *self, PyObject *args) { char *name; diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 7ba96b91458..23153f51731 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -188,7 +188,9 @@ hierarchy (faster)"}, "(i = 0) - Returns list of materials assigned to the object.\n\ if i is nonzero, empty slots are not ignored: they are returned as None's."}, {"getMatrix", (PyCFunction)Object_getMatrix, METH_VARARGS, - "Returns the object matrix - worlspace or localspace (default)"}, + "(str = 'localspace') - Returns the object matrix.\n\ +(str = 'localspace') - the wanted matrix: worldspace, localspace (default)\n\ +or oldlocal (not updated, it was the only choice before Blender 2.34)."}, {"getName", (PyCFunction)Object_getName, METH_NOARGS, "Returns the name of the object"}, {"getParent", (PyCFunction)Object_getParent, METH_NOARGS, @@ -947,13 +949,18 @@ static PyObject *Object_getMatrix (BPy_Object *self, PyObject *args) matrix = newMatrixObject(NULL, 4, 4); if (BLI_streq(space, "worldspace")){ /* Worldspace matrix */ + disable_where_script(1); where_is_object(self->object); + disable_where_script(0); Mat4CpyMat4(*((MatrixObject*)matrix)->matrix, self->object->obmat); } else if (BLI_streq(space, "localspace")) { /* Localspace matrix*/ object_to_mat4(self->object, *((MatrixObject*)matrix)->matrix); + } else if (BLI_streq(space, "oldlocal")) { /* old behavior, prior to 2.34 */ + Mat4CpyMat4(*((MatrixObject *)matrix)->matrix, self->object->obmat); } else { return (EXPP_ReturnPyObjError (PyExc_RuntimeError, - "correct spaces are 'worldspace' and 'localspace', none defaults to 'localspace'")); + "wrong parameter, expected nothing or either 'localspace' (default),\n\ +'worldspace' or 'oldlocal'")); } return matrix; } diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c index 4dd0d2881e0..90ac7ecec41 100644 --- a/source/blender/python/api2_2x/Window.c +++ b/source/blender/python/api2_2x/Window.c @@ -1180,10 +1180,13 @@ static PyObject *M_Window_GetScreenInfo(PyObject *self, PyObject *args, /*****************************************************************************/ PyObject *Window_Init (void) { - PyObject *submodule, *Types, *Qual; + PyObject *submodule, *Types, *Qual, *dict; submodule = Py_InitModule3("Blender.Window", M_Window_methods, M_Window_doc); + dict = PyModule_GetDict(submodule); + if (dict) PyDict_SetItemString(dict, "Theme", Theme_Init()); + Types = M_constant_New(); Qual = M_constant_New(); diff --git a/source/blender/python/api2_2x/charRGBA.c b/source/blender/python/api2_2x/charRGBA.c new file mode 100644 index 00000000000..032df56920c --- /dev/null +++ b/source/blender/python/api2_2x/charRGBA.c @@ -0,0 +1,398 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include "charRGBA.h" + +/* This file is heavily based on the old bpython Constant object code in + Blender */ + +/*****************************************************************************/ +/* Python charRGBA_Type callback function prototypes: */ +/*****************************************************************************/ +static void charRGBA_dealloc (BPy_charRGBA *self); +static PyObject *charRGBA_getAttr (BPy_charRGBA *self, char *name); +static int charRGBA_setAttr (BPy_charRGBA *self, char *name, PyObject *v); +static PyObject *charRGBA_repr (BPy_charRGBA *self); + +static int charRGBALength(BPy_charRGBA *self); + +static PyObject *charRGBASubscript(BPy_charRGBA *self, PyObject *key); +static int charRGBAAssSubscript(BPy_charRGBA *self, PyObject *who, + PyObject *cares); + +static PyObject *charRGBAItem(BPy_charRGBA *self, int i); +static int charRGBAAssItem(BPy_charRGBA *self, int i, PyObject *ob); +static PyObject *charRGBASlice(BPy_charRGBA *self, int begin, int end); +static int charRGBAAssSlice(BPy_charRGBA *self, int begin, int end, + PyObject *seq); + +/*****************************************************************************/ +/* Python charRGBA_Type Mapping Methods table: */ +/*****************************************************************************/ +static PyMappingMethods charRGBAAsMapping = +{ + (inquiry)charRGBALength, /* mp_length */ + (binaryfunc)charRGBASubscript, /* mp_subscript */ + (objobjargproc)charRGBAAssSubscript, /* mp_ass_subscript */ +}; + +/*****************************************************************************/ +/* Python charRGBA_Type Sequence Methods table: */ +/*****************************************************************************/ +static PySequenceMethods charRGBAAsSequence = +{ + (inquiry) charRGBALength, /* sq_length */ + (binaryfunc) 0, /* sq_concat */ + (intargfunc) 0, /* sq_repeat */ + (intargfunc) charRGBAItem, /* sq_item */ + (intintargfunc) charRGBASlice, /* sq_slice */ + (intobjargproc) charRGBAAssItem, /* sq_ass_item */ + (intintobjargproc) charRGBAAssSlice, /* sq_ass_slice */ +}; + +/*****************************************************************************/ +/* Python charRGBA_Type structure definition: */ +/*****************************************************************************/ +PyTypeObject charRGBA_Type = +{ + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "charRGBA", /* tp_name */ + sizeof (BPy_charRGBA), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)charRGBA_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc)charRGBA_getAttr, /* tp_getattr */ + (setattrfunc)charRGBA_setAttr, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc)charRGBA_repr, /* tp_repr */ + 0, /* tp_as_number */ + &charRGBAAsSequence, /* tp_as_sequence */ + &charRGBAAsMapping, /* tp_as_mapping */ + 0, /* tp_as_hash */ + 0,0,0,0,0,0, + 0, /* tp_doc */ + 0,0,0,0,0,0, + 0, /* tp_methods */ + 0, /* tp_members */ +}; + +/*****************************************************************************/ +/* Function: charRGBA_New */ +/*****************************************************************************/ +PyObject *charRGBA_New(char *rgba) +{ + BPy_charRGBA *charRGBA; + + charRGBA_Type.ob_type = &PyType_Type; + + charRGBA = (BPy_charRGBA *)PyObject_NEW(BPy_charRGBA, &charRGBA_Type); + + if (charRGBA == NULL) + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create charRGBA object"); + + /* rgba is a pointer to the first item of a char[4] array */ + charRGBA->rgba[0] = &rgba[0]; + charRGBA->rgba[1] = &rgba[1]; + charRGBA->rgba[2] = &rgba[2]; + charRGBA->rgba[3] = &rgba[3]; + + return (PyObject *)charRGBA; +} + +/*****************************************************************************/ +/* Functions: charRGBA_getCol and charRGBA_setCol */ +/* Description: These functions get/set rgba color triplet values. The */ +/* get function returns a tuple, the set one accepts three */ +/* chars (separated or in a tuple) as arguments. */ +/*****************************************************************************/ +PyObject *charRGBA_getCol (BPy_charRGBA *self) +{ + PyObject *list = PyList_New (4); + + if (!list) return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create PyList"); + + PyList_SET_ITEM (list, 0, Py_BuildValue ("b", *(self->rgba[0]) )); + PyList_SET_ITEM (list, 1, Py_BuildValue ("b", *(self->rgba[1]) )); + PyList_SET_ITEM (list, 2, Py_BuildValue ("b", *(self->rgba[2]) )); + PyList_SET_ITEM (list, 3, Py_BuildValue ("b", *(self->rgba[3]) )); + + return list; +} + +PyObject *charRGBA_setCol (BPy_charRGBA *self, PyObject *args) +{ + int ok; + char r = 0, g = 0, b = 0, a = 0; + + if (PyObject_Length (args) == 4) + ok = PyArg_ParseTuple (args, "bbbb", &r, &g, &b, &a); + + else ok = PyArg_ParseTuple (args, "|(bbbb)", &r, &g, &b, &a); + + if (!ok) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected 1-byte ints [b,b,b,b] or b,b,b,b as arguments (or nothing)"); + + *(self->rgba[0]) = EXPP_ClampInt (r, 0, 255); + *(self->rgba[1]) = EXPP_ClampInt (g, 0, 255); + *(self->rgba[2]) = EXPP_ClampInt (b, 0, 255); + *(self->rgba[3]) = EXPP_ClampInt (a, 0, 255); + + return EXPP_incr_ret (Py_None); +} + +/*****************************************************************************/ +/* Function: charRGBA_dealloc */ +/* Description: This is a callback function for the BPy_charRGBA type. It is */ +/* the destructor function. */ +/*****************************************************************************/ +static void charRGBA_dealloc (BPy_charRGBA *self) +{ + PyObject_DEL (self); +} + +/*****************************************************************************/ +/* Function: charRGBA_getAttr */ +/* Description: This is a callback function for the BPy_charRGBA type. It is */ +/* the function that accesses BPy_charRGBA member variables and */ +/* methods. */ +/*****************************************************************************/ +static PyObject* charRGBA_getAttr (BPy_charRGBA *self, char *name) +{ + int i; + + if (strcmp(name, "__members__") == 0) + return Py_BuildValue("[s,s,s,s]", "R", "G", "B", "A"); + + else if (!strcmp(name, "R") || !strcmp(name, "r")) i = 0; + else if (!strcmp(name, "G") || !strcmp(name, "g")) i = 1; + else if (!strcmp(name, "B") || !strcmp(name, "b")) i = 2; + else if (!strcmp(name, "A") || !strcmp(name, "a")) i = 3; + else + return (EXPP_ReturnPyObjError (PyExc_AttributeError, + "attribute not found")); + + return Py_BuildValue("b", *(self->rgba[i])); +} + +/*****************************************************************************/ +/* Function: charRGBA_setAttr */ +/* Description: This is a callback function for the BPy_charRGBA type. It is */ +/* the function that changes BPy_charRGBA member variables. */ +/*****************************************************************************/ +static int charRGBA_setAttr (BPy_charRGBA *self, char *name, PyObject *v) +{ + char value; + + if (!PyArg_Parse (v, "b", &value)) + return EXPP_ReturnIntError (PyExc_TypeError, + "expected char argument"); + + value = EXPP_ClampInt(value, 0, 255); + + if (!strcmp(name, "R") || !strcmp(name, "r")) + *(self->rgba[0]) = value; + + else if (!strcmp(name, "G") || !strcmp(name, "g")) + *(self->rgba[1]) = value; + + else if (!strcmp(name, "B") || !strcmp(name, "b")) + *(self->rgba[2]) = value; + + else if (!strcmp(name, "A") || !strcmp(name, "a")) + *(self->rgba[3]) = value; + + else return (EXPP_ReturnIntError (PyExc_AttributeError, + "attribute not found")); + + return 0; +} + +/*****************************************************************************/ +/* Section: charRGBA as Mapping */ +/* These functions provide code to access charRGBA objects as */ +/* mappings. */ +/*****************************************************************************/ +static int charRGBALength(BPy_charRGBA *self) +{ + return 4; +} + +static PyObject *charRGBASubscript(BPy_charRGBA *self, PyObject *key) +{ + char *name = NULL; + int i; + + if (PyNumber_Check(key)) return charRGBAItem(self, (int)PyInt_AsLong(key)); + + if (!PyArg_ParseTuple(key, "s", &name)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int or string argument"); + + if (!strcmp(name, "R") || !strcmp(name, "r")) i = 0; + else if (!strcmp(name, "G") || !strcmp(name, "g")) i = 1; + else if (!strcmp(name, "B") || !strcmp(name, "b")) i = 2; + else if (!strcmp(name, "A") || !strcmp(name, "a")) i = 3; + else + return EXPP_ReturnPyObjError (PyExc_AttributeError, name); + + return Py_BuildValue("b", *(self->rgba[i])); +} + +static int charRGBAAssSubscript(BPy_charRGBA *self, PyObject *key, PyObject *v) +{ + char *name = NULL; + int i; + + if (!PyNumber_Check(v)) return EXPP_ReturnIntError(PyExc_TypeError, + "value to assign must be a number"); + + if (PyNumber_Check(key)) + return charRGBAAssItem(self, (int)PyInt_AsLong(key), v); + + if (!PyArg_Parse(key, "s", &name)) + return EXPP_ReturnIntError (PyExc_TypeError, + "expected int or string argument"); + + if (!strcmp(name, "R") || !strcmp(name, "r")) i = 0; + else if (!strcmp(name, "G") || !strcmp(name, "g")) i = 1; + else if (!strcmp(name, "B") || !strcmp(name, "b")) i = 2; + else if (!strcmp(name, "A") || !strcmp(name, "a")) i = 3; + else + return EXPP_ReturnIntError (PyExc_AttributeError, name); + + *(self->rgba[i]) = EXPP_ClampInt(PyInt_AsLong(v), 0, 255); + + return 0; +} + +/*****************************************************************************/ +/* Section: charRGBA as Sequence */ +/* These functions provide code to access charRGBA objects as */ +/* sequences. */ +/*****************************************************************************/ +static PyObject *charRGBAItem(BPy_charRGBA *self, int i) +{ + if (i < 0 || i >= 4) + return EXPP_ReturnPyObjError (PyExc_IndexError, + "array index out of range"); + + return Py_BuildValue("b", *(self->rgba[i])); +} + +static PyObject *charRGBASlice(BPy_charRGBA *self, int begin, int end) +{ + PyObject *list; + int count; + + if (begin < 0) begin = 0; + if (end > 4) end = 4; + if (begin > end) begin = end; + + list = PyList_New(end - begin); + + for (count = begin; count < end; count++) + PyList_SetItem(list, count - begin, + PyInt_FromLong(*(self->rgba[count]))); + + return list; +} + +static int charRGBAAssItem(BPy_charRGBA *self, int i, PyObject *ob) +{ + if (i < 0 || i >= 4) + return EXPP_ReturnIntError(PyExc_IndexError, + "array assignment index out of range"); + + if (!PyNumber_Check(ob)) + return EXPP_ReturnIntError(PyExc_IndexError, + "color component must be a number"); + + *(self->rgba[i]) = EXPP_ClampInt(PyInt_AsLong(ob), 0, 255); + + return 0; +} + +static int charRGBAAssSlice(BPy_charRGBA *self, int begin, int end, + PyObject *seq) +{ + int count; + + if (begin < 0) begin = 0; + if (end > 4) end = 4; + if (begin > end) begin = end; + + if (!PySequence_Check(seq)) + return EXPP_ReturnIntError(PyExc_TypeError, + "illegal argument type for built-in operation"); + + if (PySequence_Length(seq) != (end - begin)) + return EXPP_ReturnIntError(PyExc_TypeError, + "size mismatch in slice assignment"); + + for (count = begin; count < end; count++) { + char value; + PyObject *ob = PySequence_GetItem(seq, count); + + if (!PyArg_Parse(ob, "b", &value)) { + Py_DECREF(ob); + return -1; + } + + *(self->rgba[count]) = EXPP_ClampInt(value, 0, 255); + + Py_DECREF(ob); + } + + return 0; +} + +/*****************************************************************************/ +/* Function: charRGBA_repr */ +/* Description: This is a callback function for the BPy_charRGBA type. It */ +/* builds a meaninful string to represent charRGBA objects. */ +/*****************************************************************************/ +static PyObject *charRGBA_repr (BPy_charRGBA *self) +{ + char r, g, b, a; + + r = *(self->rgba[0]); + g = *(self->rgba[1]); + b = *(self->rgba[2]); + a = *(self->rgba[3]); + + return PyString_FromFormat("[%d, %d, %d, %d]", r, g, b, a); +} diff --git a/source/blender/python/api2_2x/charRGBA.h b/source/blender/python/api2_2x/charRGBA.h new file mode 100644 index 00000000000..d6d39439721 --- /dev/null +++ b/source/blender/python/api2_2x/charRGBA.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#ifndef EXPP_charRGBA_H +#define EXPP_charRGBA_H + +#include <Python.h> +#include <stdio.h> + +#include "gen_utils.h" + +/* Objects of <type 'charRGBA'> are used inside other Blender Python + * objects, so this header file must contain only 'public' declarations */ +/* there's also rgbTuple, for rgb floats and a color obj in NMesh, messy! */ + +/* Python BPy_charRGBA structure definition: */ + +typedef struct { + PyObject_HEAD + char *rgba[4]; /* array of four pointers to chars */ + +} BPy_charRGBA; + +/*****************************************************************************/ +/* Python API function prototypes for the charRGBA helper module. */ +/*****************************************************************************/ +PyObject *charRGBA_New (char *rgba); +PyObject *charRGBA_getCol (BPy_charRGBA *self); +PyObject *charRGBA_setCol (BPy_charRGBA *self, PyObject *args); + +#endif /* EXPP_charRGBA_H */ diff --git a/source/blender/python/api2_2x/doc/API_intro.py b/source/blender/python/api2_2x/doc/API_intro.py index 70ecd37b00d..94f583211fc 100644 --- a/source/blender/python/api2_2x/doc/API_intro.py +++ b/source/blender/python/api2_2x/doc/API_intro.py @@ -7,7 +7,7 @@ The Blender Python API Reference Top Module: ----------- - - L{Blender} + - L{Blender} (*) Submodules: ----------- @@ -29,9 +29,9 @@ The Blender Python API Reference - L{Metaball} - L{NMesh} - L{Noise} - - L{Object} + - L{Object} (*) - L{Registry} - - L{Scene} + - L{Scene} (*) - L{Radio} - L{Render} - L{Text} diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py index 73fe2baa288..c6bb41a3d6d 100644 --- a/source/blender/python/api2_2x/doc/Blender.py +++ b/source/blender/python/api2_2x/doc/Blender.py @@ -2,17 +2,16 @@ # The module files in this folder are used to create the API documentation. # Doc system used: epydoc - http://epydoc.sf.net -# command line: - +# pseudo command line (check the epy_docgen.sh file): # epydoc -o BPY_API_23x --url "http://www.blender.org" -t Blender.py \ # -n "Blender" --no-private --no-frames Blender.py \ -# Types.py Scene.py Object.py NMesh.py Material.py Camera.py Lamp.py \ -# Armature.py Metaball.py Effect.py Curve.py Ipo.py World.py BGL.py Window.py \ -# Draw.py Image.py Text.py Lattice.py Texture.py Registry.py Sys.py Mathutils.py +# Types.py Scene.py Object.py [ ... etc] """ The main Blender module. +B{New}: 'scriptsdir' parameter in L{Get}. + Blender ======= """ @@ -40,6 +39,8 @@ def Get (request): - 'datadir' : the path to the dir where scripts should store and retrieve their data files, including saved configuration (can be None, if not found). + - 'scriptsdir': the path to the main dir where scripts are stored + (can be None, if not found). - 'version' : the Blender version number @return: The requested data. """ diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 29b6cd79200..07c674b9dbe 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -3,7 +3,7 @@ """ The Blender.Object submodule -B{New}: L{Object.makeTrack}, scriptLink methods: L{Object.getScriptLinks}, ... +B{New}: 'oldlocal' parameter in L{Object.Object.getMatrix}. Object ====== @@ -290,16 +290,17 @@ class Object: def getMatrix(space = 'localspace'): """ Returns the object matrix. - Use getMatrix() or getMatrix('localspace') to get the matrix relative to the objects parent. - Somtimes the absolute matrix of the object is required (taking into account vertex parents, tracking and ipo's) - in this case use getMatrix('worldspace') - @type space: string. Values are: - @param space: possible values are: - - localspace (default) - - worldspace + @type space: string + @param space: The desired matrix: + - localspace (default): relative to the object's parent; + - worldspace: absolute, taking vertex parents, tracking and ipo's into + account; + - oldlocal: old behavior, prior to Blender 2.34, where eventual changes + made by the script itself were not taken into account until the + script finished executing. Returns the object matrix. @rtype: Py_Matrix - @return: a python matrix 4x4 + @return: a python 4x4 matrix object """ def getName(): diff --git a/source/blender/python/api2_2x/gen_utils.c b/source/blender/python/api2_2x/gen_utils.c index b10b6e1d0bb..4cbdbc90ea0 100644 --- a/source/blender/python/api2_2x/gen_utils.c +++ b/source/blender/python/api2_2x/gen_utils.c @@ -25,17 +25,18 @@ * * This is a new part of Blender. * - * Contributor(s): Michel Selten, Willian P. Germano + * Contributor(s): Michel Selten, Willian P. Germano, Alex Mole * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#include "gen_utils.h" -#include "constant.h" - +#include <strings.h> /*for strcasecmp */ #include <DNA_text_types.h> #include <MEM_guardedalloc.h> +#include "gen_utils.h" +#include "constant.h" + /*****************************************************************************/ /* Description: This function clamps an int to the given interval */ /* [min, max]. */ @@ -205,6 +206,22 @@ int EXPP_map_getIntVal (const EXPP_map_pair *map, const char *sval, int *ival) return 0; } +/* same as above, but string case is ignored */ +int EXPP_map_case_getIntVal (const EXPP_map_pair *map, const char *sval, + int *ival) +{ + while (map->sval) + { + if (!strcasecmp(sval, map->sval)) + { + *ival = map->ival; + return 1; + } + ++map; + } + return 0; +} + /****************************************************************************/ /* Description: searches through a map for a pair with a given name. If the */ /* pair is present, its ival is stored in *ival and nonzero is */ diff --git a/source/blender/python/api2_2x/gen_utils.h b/source/blender/python/api2_2x/gen_utils.h index cb17d4bb05e..8ef41114ffb 100644 --- a/source/blender/python/api2_2x/gen_utils.h +++ b/source/blender/python/api2_2x/gen_utils.h @@ -60,7 +60,7 @@ PyObject *PythonIncRef (PyObject *object); char * event_to_name (short event); float EXPP_ClampFloat (float value, float min, float max); -int EXPP_ClampInt (int value, int min, int max); +int EXPP_ClampInt (int value, int min, int max); PyObject *EXPP_incr_ret (PyObject *object); PyObject *EXPP_ReturnPyObjError (PyObject * type, char * error_msg); @@ -71,17 +71,19 @@ PyObject *EXPP_tuple_repr(PyObject *self, int size); /* mapping utilities - see Texture.c for an example of how to use these */ typedef struct { - const char *sval; - int ival; + const char *sval; + int ival; } EXPP_map_pair; /* maps must end with a pair that has NULL as sval */ int EXPP_map_getIntVal (const EXPP_map_pair *map, - const char *sval, int *ival); + const char *sval, int *ival); +int EXPP_map_case_getIntVal (const EXPP_map_pair *map, + const char *sval, int *ival); int EXPP_map_getShortVal (const EXPP_map_pair *map, - const char *sval, short *ival); + const char *sval, short *ival); int EXPP_map_getStrVal (const EXPP_map_pair *map, - int ival, const char **sval); + int ival, const char **sval); /* scriplinks-related: */ PyObject *EXPP_getScriptLinks (ScriptLink *slink, PyObject *args, int is_scene); diff --git a/source/blender/python/api2_2x/modules.h b/source/blender/python/api2_2x/modules.h index f6caf46eb16..08abd05d8e0 100644 --- a/source/blender/python/api2_2x/modules.h +++ b/source/blender/python/api2_2x/modules.h @@ -204,5 +204,6 @@ PyObject * Mathutils_Init (void); PyObject * NLA_Init (void); PyObject * Library_Init (void); PyObject * Sound_Init (void); +PyObject * Theme_Init (void); /* Window.Theme */ #endif /* EXPP_modules_h */ diff --git a/source/blender/python/api2_2x/windowTheme.c b/source/blender/python/api2_2x/windowTheme.c new file mode 100644 index 00000000000..56901520fb9 --- /dev/null +++ b/source/blender/python/api2_2x/windowTheme.c @@ -0,0 +1,706 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include <MEM_guardedalloc.h> +#include <BLI_blenlib.h> +#include <DNA_screen_types.h> +#include "windowTheme.h" +#include "charRGBA.h" +#include "gen_utils.h" + +#define EXPP_THEME_VTX_SIZE_MIN 1 +#define EXPP_THEME_VTX_SIZE_MAX 10 +#define EXPP_THEME_DRAWTYPE_MIN 1 +#define EXPP_THEME_DRAWTYPE_MAX 4 + +#define EXPP_THEME_NUMBEROFTHEMES 14 +static const EXPP_map_pair themes_map[] = { + {"ui", -1}, + {"buts", SPACE_BUTS}, + {"view3d", SPACE_VIEW3D}, + {"file", SPACE_FILE}, + {"ipo", SPACE_IPO}, + {"info", SPACE_INFO}, + {"sound", SPACE_SOUND}, + {"action", SPACE_ACTION}, + {"nla", SPACE_NLA}, + {"seq", SPACE_SEQ}, + {"image", SPACE_IMAGE}, + {"imasel", SPACE_IMASEL}, + {"text", SPACE_TEXT}, + {"oops", SPACE_OOPS}, + {NULL, 0} +}; + +static PyObject *M_Theme_New (PyObject *self, PyObject *args); +static PyObject *M_Theme_Get (PyObject *self, PyObject *args); + +static char M_Theme_doc[] = "The Blender Theme module\n\n\ +This module provides access to UI Theme data in Blender"; + +static char M_Theme_New_doc[] = +"Theme.New (name = 'New Theme'):\n\ + Return a new Theme Data object with the given type and name."; + +static char M_Theme_Get_doc[] = "Theme.Get (name = None):\n\ + Return the theme data with the given 'name', None if not found, or\n\ + Return a list with all Theme Data objects if no argument was given."; + +/*****************************************************************************/ +/* Python method structure definition for Blender.Theme module: */ +/*****************************************************************************/ +struct PyMethodDef M_Theme_methods[] = { + {"New", M_Theme_New, METH_VARARGS, M_Theme_New_doc}, + {"Get", M_Theme_Get, METH_VARARGS, M_Theme_Get_doc}, + {NULL, NULL, 0, NULL} +}; + +static void ThemeSpace_dealloc (BPy_ThemeSpace *self); +static int ThemeSpace_compare (BPy_ThemeSpace *a, BPy_ThemeSpace *b); +static PyObject *ThemeSpace_repr (BPy_ThemeSpace *self); +static PyObject *ThemeSpace_getAttr (BPy_ThemeSpace *self, char *name); +static int ThemeSpace_setAttr (BPy_ThemeSpace *self, char *name, PyObject *val); + +static PyMethodDef BPy_ThemeSpace_methods[] = { + {NULL, NULL, 0, NULL} +}; + +PyTypeObject ThemeSpace_Type = { + PyObject_HEAD_INIT (NULL) 0, /* ob_size */ + "Blender Space Theme", /* tp_name */ + sizeof (BPy_Theme), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor) ThemeSpace_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc) ThemeSpace_getAttr, /* tp_getattr */ + (setattrfunc) ThemeSpace_setAttr, /* tp_setattr */ + (cmpfunc) ThemeSpace_compare, /* tp_compare */ + (reprfunc) ThemeSpace_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_as_hash */ + 0, 0, 0, 0, 0, 0, + 0, /* tp_doc */ + 0, 0, 0, 0, 0, 0, + 0, //BPy_ThemeSpace_methods, /* tp_methods */ + 0, /* tp_members */ +}; + +static void ThemeSpace_dealloc (BPy_ThemeSpace *self) +{ + PyObject_DEL (self); +} + +#define ELSEIF_TSP_RGBA(attr)\ + else if (!strcmp(name, #attr))\ + attrib = charRGBA_New(&tsp->attr[0]); + +/* Example: ELSEIF_TSP_RGBA(outline) becomes: + * else if (!strcmp(name, "back") + * attr = charRGBA_New(&tsp->back[0]) + */ + +static PyObject *ThemeSpace_getAttr (BPy_ThemeSpace *self, char *name) +{ + PyObject *attrib = Py_None; + ThemeSpace *tsp = self->tsp; + + if (!strcmp (name, "theme")) + attrib = PyString_FromString (self->theme->name); + ELSEIF_TSP_RGBA(back) + ELSEIF_TSP_RGBA(text) + ELSEIF_TSP_RGBA(text_hi) + ELSEIF_TSP_RGBA(header) + ELSEIF_TSP_RGBA(panel) + ELSEIF_TSP_RGBA(shade1) + ELSEIF_TSP_RGBA(shade2) + ELSEIF_TSP_RGBA(hilite) + ELSEIF_TSP_RGBA(grid) + ELSEIF_TSP_RGBA(wire) + ELSEIF_TSP_RGBA(select) + ELSEIF_TSP_RGBA(active) + ELSEIF_TSP_RGBA(transform) + ELSEIF_TSP_RGBA(vertex) + ELSEIF_TSP_RGBA(vertex_select) + ELSEIF_TSP_RGBA(edge) + ELSEIF_TSP_RGBA(edge_select) + ELSEIF_TSP_RGBA(edge_seam) + ELSEIF_TSP_RGBA(edge_facesel) + ELSEIF_TSP_RGBA(face) + ELSEIF_TSP_RGBA(face_select) + ELSEIF_TSP_RGBA(normal) + else if (!strcmp (name, "vertex_size")) + attrib = Py_BuildValue("i", tsp->vertex_size); + else if (!strcmp (name, "__members__")) + attrib = Py_BuildValue("[ssssssssssssssssssssssss]", "theme", + "back", "text", "text_hi", "header", "panel", "shade1", "shade2", + "hilite", "grid", "wire", "select", "active", "transform", + "vertex", "vertex_select", "edge", "edge_select", "edge_seam", + "edge_facesel", "face", "face_select", "normal", "vertex_size"); + + if (attrib != Py_None) return attrib; + + return Py_FindMethod(BPy_ThemeSpace_methods, (PyObject *)self, name); +} + +static int ThemeSpace_setAttr (BPy_ThemeSpace *self, char *name, + PyObject *value) +{ + PyObject *attrib = NULL; + ThemeSpace *tsp = self->tsp; + int ret = -1; + + if (!strcmp (name, "back")) + attrib = charRGBA_New(&tsp->back[0]); + ELSEIF_TSP_RGBA(back) + ELSEIF_TSP_RGBA(text) + ELSEIF_TSP_RGBA(text_hi) + ELSEIF_TSP_RGBA(header) + ELSEIF_TSP_RGBA(panel) + ELSEIF_TSP_RGBA(shade1) + ELSEIF_TSP_RGBA(shade2) + ELSEIF_TSP_RGBA(hilite) + ELSEIF_TSP_RGBA(grid) + ELSEIF_TSP_RGBA(wire) + ELSEIF_TSP_RGBA(select) + ELSEIF_TSP_RGBA(active) + ELSEIF_TSP_RGBA(transform) + ELSEIF_TSP_RGBA(vertex) + ELSEIF_TSP_RGBA(vertex_select) + ELSEIF_TSP_RGBA(edge) + ELSEIF_TSP_RGBA(edge_select) + ELSEIF_TSP_RGBA(edge_seam) + ELSEIF_TSP_RGBA(edge_facesel) + ELSEIF_TSP_RGBA(face) + ELSEIF_TSP_RGBA(face_select) + ELSEIF_TSP_RGBA(normal) + else if (!strcmp (name, "vertex_size")) { + int val; + + if (!PyInt_Check(value)) + return EXPP_ReturnIntError (PyExc_TypeError, "expected integer value"); + + val = (int)PyInt_AsLong(value); + tsp->vertex_size = EXPP_ClampInt(val, + EXPP_THEME_VTX_SIZE_MIN, EXPP_THEME_VTX_SIZE_MAX); + ret = 0; + } + else + return EXPP_ReturnIntError (PyExc_AttributeError, "attribute not found"); + + if (attrib) { + PyObject *pyret = NULL; + PyObject *valtuple = Py_BuildValue("(O)", value); + + if (!valtuple) + return EXPP_ReturnIntError (PyExc_MemoryError, "couldn't create tuple!"); + + pyret = charRGBA_setCol((BPy_charRGBA *)attrib, valtuple); + Py_DECREF(valtuple); + + if (pyret == Py_None) { + Py_DECREF (Py_None); /* was increfed by charRGBA_setCol */ + ret = 0; + } + + Py_DECREF(attrib); /* we're done with it */ + } + + return ret; /* 0 if all went well */ +} + +static int ThemeSpace_compare (BPy_ThemeSpace *a, BPy_ThemeSpace *b) +{ + ThemeSpace *pa = a->tsp, *pb = b->tsp; + return (pa == pb) ? 0 : -1; +} + +static PyObject *ThemeSpace_repr (BPy_ThemeSpace *self) +{ + return PyString_FromFormat ("[Space theme from theme \"%s\"]", + self->theme->name); +} + +static void ThemeUI_dealloc (BPy_ThemeUI *self); +static int ThemeUI_compare (BPy_ThemeUI *a, BPy_ThemeUI *b); +static PyObject *ThemeUI_repr (BPy_ThemeUI *self); +static PyObject *ThemeUI_getAttr (BPy_ThemeUI *self, char *name); +static int ThemeUI_setAttr (BPy_ThemeUI *self, char *name, PyObject *val); + +static PyMethodDef BPy_ThemeUI_methods[] = { + {NULL, NULL, 0, NULL} +}; + +PyTypeObject ThemeUI_Type = { + PyObject_HEAD_INIT (NULL) 0, /* ob_size */ + "Blender UI Theme", /* tp_name */ + sizeof (BPy_Theme), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor) ThemeUI_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc) ThemeUI_getAttr, /* tp_getattr */ + (setattrfunc) ThemeUI_setAttr, /* tp_setattr */ + (cmpfunc) ThemeUI_compare, /* tp_compare */ + (reprfunc) ThemeUI_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_as_hash */ + 0, 0, 0, 0, 0, 0, + 0, /* tp_doc */ + 0, 0, 0, 0, 0, 0, + 0, //BPy_ThemeUI_methods, /* tp_methods */ + 0, /* tp_members */ +}; + +static void ThemeUI_dealloc (BPy_ThemeUI *self) +{ + PyObject_DEL (self); +} + +#define ELSEIF_TUI_RGBA(attr)\ + else if (!strcmp(name, #attr))\ + attrib = charRGBA_New(&tui->attr[0]); + +/* Example: ELSEIF_TUI_RGBA(outline) becomes: + * else if (!strcmp(name, "outline") + * attr = charRGBA_New(&tui->outline[0]) + */ + +static PyObject *ThemeUI_getAttr (BPy_ThemeUI *self, char *name) +{ + PyObject *attrib = Py_None; + ThemeUI *tui = self->tui; + + if (!strcmp (name, "theme")) + attrib = PyString_FromString (self->theme->name); + ELSEIF_TUI_RGBA(outline) + ELSEIF_TUI_RGBA(neutral) + ELSEIF_TUI_RGBA(action) + ELSEIF_TUI_RGBA(setting) + ELSEIF_TUI_RGBA(setting1) + ELSEIF_TUI_RGBA(setting2) + ELSEIF_TUI_RGBA(num) + ELSEIF_TUI_RGBA(textfield) + ELSEIF_TUI_RGBA(popup) + ELSEIF_TUI_RGBA(text) + ELSEIF_TUI_RGBA(text_hi) + ELSEIF_TUI_RGBA(menu_back) + ELSEIF_TUI_RGBA(menu_item) + ELSEIF_TUI_RGBA(menu_hilite) + ELSEIF_TUI_RGBA(menu_text) + ELSEIF_TUI_RGBA(menu_text_hi) + else if (!strcmp (name, "drawType")) + attrib = PyInt_FromLong((char)tui->but_drawtype); + else if (!strcmp (name, "__members__")) + attrib = Py_BuildValue("[ssssssssssssssssss]", "theme", + "outline", "neutral", "action", "setting", "setting1", "setting2", + "num", "textfield", "popup", "text", "text_hi", "menu_back", "menu_item", + "menu_hilite", "menu_text", "menu_text_hi", "drawType"); + + if (attrib != Py_None) return attrib; + + return Py_FindMethod(BPy_ThemeUI_methods, (PyObject *)self, name); +} + +static int ThemeUI_setAttr (BPy_ThemeUI *self, char *name, PyObject *value) +{ + PyObject *attrib = NULL; + ThemeUI *tui = self->tui; + int ret = -1; + + if (!strcmp (name, "outline")) + attrib = charRGBA_New(&tui->outline[0]); + ELSEIF_TUI_RGBA(neutral) + ELSEIF_TUI_RGBA(action) + ELSEIF_TUI_RGBA(setting) + ELSEIF_TUI_RGBA(setting1) + ELSEIF_TUI_RGBA(setting2) + ELSEIF_TUI_RGBA(num) + ELSEIF_TUI_RGBA(textfield) + ELSEIF_TUI_RGBA(popup) + ELSEIF_TUI_RGBA(text) + ELSEIF_TUI_RGBA(text_hi) + ELSEIF_TUI_RGBA(menu_back) + ELSEIF_TUI_RGBA(menu_item) + ELSEIF_TUI_RGBA(menu_hilite) + ELSEIF_TUI_RGBA(menu_text) + ELSEIF_TUI_RGBA(menu_text_hi) + else if (!strcmp (name, "drawType")) { + int val; + + if (!PyInt_Check(value)) + return EXPP_ReturnIntError (PyExc_TypeError, "expected integer value"); + + val = (int)PyInt_AsLong(value); + tui->but_drawtype = EXPP_ClampInt(val, + EXPP_THEME_DRAWTYPE_MIN, EXPP_THEME_DRAWTYPE_MAX); + ret = 0; + } + else + return EXPP_ReturnIntError (PyExc_AttributeError, "attribute not found"); + + if (attrib) { + PyObject *pyret = NULL; + PyObject *valtuple = Py_BuildValue("(O)", value); + + if (!valtuple) + return EXPP_ReturnIntError (PyExc_MemoryError, "couldn't create tuple!"); + + pyret = charRGBA_setCol((BPy_charRGBA *)attrib, valtuple); + Py_DECREF(valtuple); + + if (pyret == Py_None) { + Py_DECREF (Py_None); /* was increfed by charRGBA_setCol */ + ret = 0; + } + + Py_DECREF(attrib); /* we're done with it */ + } + + return ret; /* 0 if all went well */ +} + + +static int ThemeUI_compare (BPy_ThemeUI *a, BPy_ThemeUI *b) +{ + ThemeUI *pa = a->tui, *pb = b->tui; + return (pa == pb) ? 0 : -1; +} + +static PyObject *ThemeUI_repr (BPy_ThemeUI *self) +{ + return PyString_FromFormat("[UI theme from theme \"%s\"]", self->theme->name); +} + +static void Theme_dealloc (BPy_Theme *self); +static int Theme_compare (BPy_Theme *a, BPy_Theme *b); +static PyObject *Theme_getAttr (BPy_Theme *self, char *name); +static PyObject *Theme_repr (BPy_Theme *self); + +static PyObject *Theme_get(BPy_Theme *self, PyObject *args); +static PyObject *Theme_getName(BPy_Theme *self); +static PyObject *Theme_setName(BPy_Theme *self, PyObject *args); + +static PyMethodDef BPy_Theme_methods[] = { + {"get", (PyCFunction) Theme_get, METH_VARARGS, + "(param) - Return UI or Space theme object.\n\ +(param) - the chosen theme object as an int or a string:\n\ +- () - default: UI;\n\ +- (i) - int: an entry from the Blender.Window.Types dictionary;\n\ +- (s) - string: 'UI' or a space name, like 'VIEW3D', etc."}, + {"getName", (PyCFunction) Theme_getName, METH_NOARGS, + "() - Return Theme name"}, + {"setName", (PyCFunction) Theme_setName, METH_VARARGS, + "(s) - Set Theme name"}, + {NULL, NULL, 0, NULL} +}; + +PyTypeObject Theme_Type = { + PyObject_HEAD_INIT (NULL) 0, /* ob_size */ + "Blender Theme", /* tp_name */ + sizeof (BPy_Theme), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor) Theme_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc) Theme_getAttr, /* tp_getattr */ + 0,//(setattrfunc) Theme_setAttr, /* tp_setattr */ + (cmpfunc) Theme_compare, /* tp_compare */ + (reprfunc) Theme_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_as_hash */ + 0, 0, 0, 0, 0, 0, + 0, /* tp_doc */ + 0, 0, 0, 0, 0, 0, + 0, //BPy_Theme_methods, /* tp_methods */ + 0, /* tp_members */ +}; + +static PyObject *M_Theme_New (PyObject *self, PyObject *args) +{ + char *name = "New Theme"; + BPy_Theme *pytheme = NULL, *base_pytheme = NULL; + bTheme *btheme = NULL, *newtheme = NULL; + + if (!PyArg_ParseTuple (args, "|sO!", &name, &Theme_Type, &base_pytheme)) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected nothing or a name and optional theme object as arguments"); + + if (base_pytheme) btheme = base_pytheme->theme; + if (!btheme) btheme = U.themes.first; + + newtheme = MEM_callocN(sizeof(bTheme), "theme"); + + if (newtheme) pytheme = PyObject_New (BPy_Theme, &Theme_Type); + if (!pytheme) return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't create Theme Data in Blender"); + + memcpy(newtheme, btheme, sizeof(bTheme)); + BLI_addhead(&U.themes, newtheme); + BLI_strncpy(newtheme->name, name, 32); + + pytheme->theme = newtheme; + + return (PyObject *)pytheme; +} + +static PyObject *M_Theme_Get (PyObject *self, PyObject *args) +{ + char *name = NULL; + bTheme *iter; + PyObject *ret; + + if (!PyArg_ParseTuple (args, "|s", &name)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument (or nothing)"); + + iter = U.themes.first; + + if (name) { /* (name) - return requested theme */ + BPy_Theme *wanted = NULL; + + while (iter) { + if (strcmp (name, iter->name) == 0) { + wanted = PyObject_New(BPy_Theme, &Theme_Type); + wanted->theme = iter; + break; + } + iter = iter->next; + } + + if (!wanted) { + char emsg[64]; + PyOS_snprintf (emsg, sizeof (emsg), "Theme \"%s\" not found", name); + return EXPP_ReturnPyObjError (PyExc_NameError, emsg); + } + + ret = (PyObject *)wanted; + } + + else { /* () - return list with all themes */ + int index = 0; + PyObject *list = NULL; + BPy_Theme *pytheme = NULL; + + list = PyList_New (BLI_countlist (&(U.themes))); + + if (!list) + return EXPP_ReturnPyObjError(PyExc_MemoryError,"couldn't create PyList"); + + while (iter) { + pytheme = PyObject_New(BPy_Theme, &Theme_Type); + pytheme->theme = iter; + + if (!pytheme) + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create Theme PyObject"); + + PyList_SET_ITEM (list, index, (PyObject *)pytheme); + + iter = iter->next; + index++; + } + + ret = list; + } + + return ret; +} + +static PyObject *Theme_get(BPy_Theme *self, PyObject *args) +{ + bTheme *btheme = self->theme; + ThemeUI *tui = NULL; + ThemeSpace *tsp = NULL; + PyObject *pyob = NULL; + BPy_ThemeUI *retUI = NULL; + BPy_ThemeSpace *retSpc = NULL; + int type; + + if (!PyArg_ParseTuple(args, "|O", &pyob)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string or int argument or nothing"); + + if (!pyob) { /* (): return list with all names */ + PyObject *ret = PyList_New(EXPP_THEME_NUMBEROFTHEMES); + + if (!ret) + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create pylist!"); + + type = 0; /* using as a counter only */ + + while (type < EXPP_THEME_NUMBEROFTHEMES) { + PyList_SET_ITEM(ret, type, PyString_FromString(themes_map[type].sval)); + type++; + } + + return ret; + } + + else if (PyInt_Check(pyob)) /* (int) */ + type = (int)PyInt_AsLong(pyob); + else if (PyString_Check(pyob)) { /* (str) */ + char *str = PyString_AsString(pyob); + if (!EXPP_map_case_getIntVal(themes_map, str, &type)) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "unknown string argument"); + } + else return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string or int argument or nothing"); + + switch (type) { + case -1: /* UI */ + tui = &btheme->tui; + break; + case SPACE_BUTS: + tsp = &btheme->tbuts; + break; + case SPACE_VIEW3D: + tsp = &btheme->tv3d; + break; + case SPACE_FILE: + tsp = &btheme->tfile; + break; + case SPACE_IPO: + tsp = &btheme->tipo; + break; + case SPACE_INFO: + tsp = &btheme->tinfo; + break; + case SPACE_SOUND: + tsp = &btheme->tsnd; + break; + case SPACE_ACTION: + tsp = &btheme->tact; + break; + case SPACE_NLA: + tsp = &btheme->tnla; + break; + case SPACE_SEQ: + tsp = &btheme->tseq; + break; + case SPACE_IMAGE: + tsp = &btheme->tima; + break; + case SPACE_IMASEL: + tsp = &btheme->timasel; + break; + case SPACE_TEXT: + tsp = &btheme->text; + break; + case SPACE_OOPS: + tsp = &btheme->toops; + break; + } + + if (tui) { + retUI = PyObject_New(BPy_ThemeUI, &ThemeUI_Type); + retUI->theme = btheme; + retUI->tui = tui; + return (PyObject *)retUI; + } + else if (tsp) { + retSpc = PyObject_New(BPy_ThemeSpace, &ThemeSpace_Type); + retSpc->theme = btheme; + retSpc->tsp = tsp; + return (PyObject *)retSpc; + } + else return EXPP_ReturnPyObjError (PyExc_AttributeError, + "invalid parameter"); +} + +static PyObject *Theme_getName(BPy_Theme *self) +{ + return PyString_FromString (self->theme->name); +} + +static PyObject *Theme_setName(BPy_Theme *self, PyObject *args) +{ + char *name = NULL; + + if (!PyArg_ParseTuple(args, "s", &name)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument"); + + BLI_strncpy(self->theme->name, name, 32); + + return EXPP_incr_ret (Py_None); +} + +PyObject *Theme_Init (void) +{ + PyObject *submodule; + + Theme_Type.ob_type = &PyType_Type; + + submodule = Py_InitModule3 ("Blender.Window.Theme", + M_Theme_methods, M_Theme_doc); + + return submodule; +} + +static void Theme_dealloc (BPy_Theme *self) +{ + PyObject_DEL (self); +} + +static PyObject *Theme_getAttr (BPy_Theme *self, char *name) +{ + PyObject *attr = Py_None; + + if (!strcmp (name, "name")) + attr = PyString_FromString (self->theme->name); + else if (!strcmp (name, "__members__")) + attr = Py_BuildValue("[s]", "name"); + + if (attr != Py_None) return attr; + + return Py_FindMethod(BPy_Theme_methods, (PyObject *)self, name); +} + +static int Theme_compare (BPy_Theme *a, BPy_Theme *b) +{ + bTheme *pa = a->theme, *pb = b->theme; + return (pa == pb) ? 0 : -1; +} + +static PyObject *Theme_repr (BPy_Theme *self) +{ + return PyString_FromFormat ("[Theme \"%s\"]", self->theme->name); +} diff --git a/source/blender/python/api2_2x/windowTheme.h b/source/blender/python/api2_2x/windowTheme.h new file mode 100644 index 00000000000..b3a654c9fb7 --- /dev/null +++ b/source/blender/python/api2_2x/windowTheme.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#ifndef EXPP_WINDOWTHEME_H +#define EXPP_WINDOWTHEME_H + +#include <Python.h> +#include <DNA_listBase.h> +#include <DNA_userdef_types.h> + +typedef struct { + PyObject_HEAD + struct bTheme *theme; + struct ThemeUI *tui; + +} BPy_ThemeUI; + +typedef struct { + PyObject_HEAD + struct bTheme *theme; + struct ThemeSpace *tsp; + +} BPy_ThemeSpace; + +typedef struct { + PyObject_HEAD + struct bTheme *theme; + +} BPy_Theme; + +#endif /* EXPP_WINDOWTHEME_H */ diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 02dbd8565a9..330c32330e5 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -1933,7 +1933,12 @@ void drawview3dspace(ScrArea *sa, void *spacedata) G.vd->flag |= V3D_NEEDBACKBUFDRAW; addafterqueue(curarea->win, BACKBUFDRAW, 1); } - + + /* scene redraw script link */ + if(G.scene->scriptlink.totscript && !during_script()) { + BPY_do_pyscript((ID *)G.scene, SCRIPT_REDRAW); + } + } |