- Blender: added option 'scriptsdir' to Blender.Get();

- small updates to the docs;
- Object: small fix to getMatrix: check during_script() to avoid undesired loops; added old behavior (pre 2.34) as option: .getMatrix('oldlocal');
- tentative fix for bug #1275: scene REDRAW scriptlinks were not being executed (the call to do so was missing):
http://projects.blender.org/tracker/index.php?func=detail&aid=1275&group_id=9&atid=125
    added the call in drawview.c, in drawview3dspace().  This causes the scriptlink to be called for each visible view3d, but that's what happens with object redraw scriptlinks, too.  Anyway, this is still a test.  The place was chosen based on the idea that a scene redraw scriptlink is like an object redraw one, but for all objs in the scene at once.

- Window.Theme: new submodule, to get/set theme options in Blender;
- Added the script save_theme.py (Help menu for now), to save the current theme in Blender as an executable script (currently shown in the Scripts->Misc menu).

There's more work to do for themes, like defining a proper place for them in the interface, adding documentation (for now the added script and the ones it generates can give a pretty good idea of how to use the new module), probably extending themes to support SpaceScript and so on.
This commit is contained in:
2004-09-21 05:28:17 +00:00
parent e5e621ad24
commit e7d3039d12
17 changed files with 1441 additions and 59 deletions

View File

@@ -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)

View File

@@ -7,54 +7,56 @@ python_env = library_env.Copy ()
source_files = ['BPY_interface.c', source_files = ['BPY_interface.c',
'BPY_menus.c', 'BPY_menus.c',
'api2_2x/Armature.c',
'api2_2x/BezTriple.c',
'api2_2x/BGL.c',
'api2_2x/Blender.c', 'api2_2x/Blender.c',
'api2_2x/Sys.c', 'api2_2x/Bone.c',
'api2_2x/Registry.c', 'api2_2x/Build.c',
'api2_2x/Scene.c',
'api2_2x/Types.c',
'api2_2x/Object.c',
'api2_2x/NMesh.c',
'api2_2x/Material.c',
'api2_2x/Camera.c', 'api2_2x/Camera.c',
'api2_2x/World.c', 'api2_2x/CurNurb.c',
'api2_2x/Curve.c',
'api2_2x/Draw.c',
'api2_2x/Effect.c',
'api2_2x/EXPP_interface.c',
'api2_2x/Ipocurve.c',
'api2_2x/Ipo.c',
'api2_2x/Lamp.c', 'api2_2x/Lamp.c',
'api2_2x/Lattice.c', 'api2_2x/Lattice.c',
'api2_2x/Library.c', 'api2_2x/Library.c',
'api2_2x/CurNurb.c', 'api2_2x/MTex.c',
'api2_2x/Curve.c', 'api2_2x/Material.c',
'api2_2x/Armature.c', 'api2_2x/Mathutils.c',
'api2_2x/Bone.c',
'api2_2x/Ipo.c',
'api2_2x/Ipocurve.c',
'api2_2x/BezTriple.c',
'api2_2x/Metaball.c', 'api2_2x/Metaball.c',
'api2_2x/NLA.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/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/Wave.c',
'api2_2x/Build.c',
'api2_2x/Image.c',
'api2_2x/Window.c', 'api2_2x/Window.c',
'api2_2x/Draw.c', 'api2_2x/World.c',
'api2_2x/BGL.c', 'api2_2x/Image.c',
'api2_2x/Text.c', 'api2_2x/Text.c',
'api2_2x/Texture.c', 'api2_2x/Texture.c',
'api2_2x/MTex.c',
'api2_2x/Noise.c', 'api2_2x/Noise.c',
'api2_2x/vector.c', 'api2_2x/charRGBA.c',
'api2_2x/constant.c', 'api2_2x/constant.c',
'api2_2x/euler.c',
'api2_2x/gen_utils.c',
'api2_2x/logic.c', 'api2_2x/logic.c',
'api2_2x/matrix.c', 'api2_2x/matrix.c',
'api2_2x/euler.c',
'api2_2x/quat.c', 'api2_2x/quat.c',
'api2_2x/Mathutils.c',
'api2_2x/rgbTuple.c', 'api2_2x/rgbTuple.c',
'api2_2x/gen_utils.c',
'api2_2x/sceneRender.c', 'api2_2x/sceneRender.c',
'api2_2x/sceneRadio.c', 'api2_2x/sceneRadio.c',
'api2_2x/EXPP_interface.c', 'api2_2x/vector.c',
'api2_2x/Noise.c', 'api2_2x/windowTheme.c']
'api2_2x/Sound.c']
python_env.Append (CPPPATH = ['api2_2x', python_env.Append (CPPPATH = ['api2_2x',
'../blenkernel', '../blenkernel',

View File

@@ -99,6 +99,7 @@ static char Blender_Get_doc[] =
'endframe' - Returns the end frame of the animation\n\ 'endframe' - Returns the end frame of the animation\n\
'filename' - Returns the name of the last file read or written\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\ '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"; 'version' - Returns the Blender version number";
static char Blender_Redraw_doc[] = "() - Redraw all 3D windows"; 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); if (BLI_exists(datadir)) return PyString_FromString(datadir);
else return EXPP_incr_ret (Py_None); 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 /* According to the old file (opy_blender.c), the following if
statement is a quick hack and needs some clean up. */ statement is a quick hack and needs some clean up. */
if (StringEqual (str, "vrmloptions")) if (StringEqual (str, "vrmloptions"))

View File

@@ -37,6 +37,7 @@
#include <BIF_drawimage.h> #include <BIF_drawimage.h>
#include <BLI_blenlib.h> #include <BLI_blenlib.h>
#include <IMB_imbuf_types.h> /* for the IB_rect define */ #include <IMB_imbuf_types.h> /* for the IB_rect define */
#include <BIF_gl.h>
#include "gen_utils.h" #include "gen_utils.h"
#include "Image.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_setXRep(BPy_Image *self, PyObject *args);
static PyObject *Image_setYRep(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_reload(BPy_Image *self); /* by Campbell */
static PyObject *Image_glLoad(BPy_Image *self);
/*****************************************************************************/ /*****************************************************************************/
/* Python BPy_Image methods table: */ /* Python BPy_Image methods table: */
@@ -259,6 +261,9 @@ static PyMethodDef BPy_Image_methods[] = {
"() - Return Image object's bind code value"}, "() - Return Image object's bind code value"},
{"reload", (PyCFunction)Image_reload, METH_NOARGS, {"reload", (PyCFunction)Image_reload, METH_NOARGS,
"() - Reload the image from the filesystem"}, "() - 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, {"setName", (PyCFunction)Image_setName, METH_VARARGS,
"(str) - Change Image object name"}, "(str) - Change Image object name"},
{"setXRep", (PyCFunction)Image_setXRep, METH_VARARGS, {"setXRep", (PyCFunction)Image_setXRep, METH_VARARGS,
@@ -460,6 +465,37 @@ static PyObject *Image_reload(BPy_Image *self)
return Py_None; 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) static PyObject *Image_setName(BPy_Image *self, PyObject *args)
{ {
char *name; char *name;

View File

@@ -188,7 +188,9 @@ hierarchy (faster)"},
"(i = 0) - Returns list of materials assigned to the object.\n\ "(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."}, if i is nonzero, empty slots are not ignored: they are returned as None's."},
{"getMatrix", (PyCFunction)Object_getMatrix, METH_VARARGS, {"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, {"getName", (PyCFunction)Object_getName, METH_NOARGS,
"Returns the name of the object"}, "Returns the name of the object"},
{"getParent", (PyCFunction)Object_getParent, METH_NOARGS, {"getParent", (PyCFunction)Object_getParent, METH_NOARGS,
@@ -947,13 +949,18 @@ static PyObject *Object_getMatrix (BPy_Object *self, PyObject *args)
matrix = newMatrixObject(NULL, 4, 4); matrix = newMatrixObject(NULL, 4, 4);
if (BLI_streq(space, "worldspace")){ /* Worldspace matrix */ if (BLI_streq(space, "worldspace")){ /* Worldspace matrix */
disable_where_script(1);
where_is_object(self->object); where_is_object(self->object);
disable_where_script(0);
Mat4CpyMat4(*((MatrixObject*)matrix)->matrix, self->object->obmat); Mat4CpyMat4(*((MatrixObject*)matrix)->matrix, self->object->obmat);
} else if (BLI_streq(space, "localspace")) { /* Localspace matrix*/ } else if (BLI_streq(space, "localspace")) { /* Localspace matrix*/
object_to_mat4(self->object, *((MatrixObject*)matrix)->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 { } else {
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, 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; return matrix;
} }

View File

@@ -1180,10 +1180,13 @@ static PyObject *M_Window_GetScreenInfo(PyObject *self, PyObject *args,
/*****************************************************************************/ /*****************************************************************************/
PyObject *Window_Init (void) PyObject *Window_Init (void)
{ {
PyObject *submodule, *Types, *Qual; PyObject *submodule, *Types, *Qual, *dict;
submodule = Py_InitModule3("Blender.Window", M_Window_methods, M_Window_doc); 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(); Types = M_constant_New();
Qual = M_constant_New(); Qual = M_constant_New();

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -7,7 +7,7 @@ The Blender Python API Reference
Top Module: Top Module:
----------- -----------
- L{Blender} - L{Blender} (*)
Submodules: Submodules:
----------- -----------
@@ -29,9 +29,9 @@ The Blender Python API Reference
- L{Metaball} - L{Metaball}
- L{NMesh} - L{NMesh}
- L{Noise} - L{Noise}
- L{Object} - L{Object} (*)
- L{Registry} - L{Registry}
- L{Scene} - L{Scene} (*)
- L{Radio} - L{Radio}
- L{Render} - L{Render}
- L{Text} - L{Text}

View File

@@ -2,17 +2,16 @@
# The module files in this folder are used to create the API documentation. # The module files in this folder are used to create the API documentation.
# Doc system used: epydoc - http://epydoc.sf.net # 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 \ # epydoc -o BPY_API_23x --url "http://www.blender.org" -t Blender.py \
# -n "Blender" --no-private --no-frames Blender.py \ # -n "Blender" --no-private --no-frames Blender.py \
# Types.py Scene.py Object.py NMesh.py Material.py Camera.py Lamp.py \ # Types.py Scene.py Object.py [ ... etc]
# 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
""" """
The main Blender module. The main Blender module.
B{New}: 'scriptsdir' parameter in L{Get}.
Blender Blender
======= =======
""" """
@@ -40,6 +39,8 @@ def Get (request):
- 'datadir' : the path to the dir where scripts should store and - 'datadir' : the path to the dir where scripts should store and
retrieve their data files, including saved configuration (can retrieve their data files, including saved configuration (can
be None, if not found). 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 - 'version' : the Blender version number
@return: The requested data. @return: The requested data.
""" """

View File

@@ -3,7 +3,7 @@
""" """
The Blender.Object submodule The Blender.Object submodule
B{New}: L{Object.makeTrack}, scriptLink methods: L{Object.getScriptLinks}, ... B{New}: 'oldlocal' parameter in L{Object.Object.getMatrix}.
Object Object
====== ======
@@ -290,16 +290,17 @@ class Object:
def getMatrix(space = 'localspace'): def getMatrix(space = 'localspace'):
""" """
Returns the object matrix. Returns the object matrix.
Use getMatrix() or getMatrix('localspace') to get the matrix relative to the objects parent. @type space: string
Somtimes the absolute matrix of the object is required (taking into account vertex parents, tracking and ipo's) @param space: The desired matrix:
in this case use getMatrix('worldspace') - localspace (default): relative to the object's parent;
@type space: string. Values are: - worldspace: absolute, taking vertex parents, tracking and ipo's into
@param space: possible values are: account;
- localspace (default) - oldlocal: old behavior, prior to Blender 2.34, where eventual changes
- worldspace made by the script itself were not taken into account until the
script finished executing.
Returns the object matrix. Returns the object matrix.
@rtype: Py_Matrix @rtype: Py_Matrix
@return: a python matrix 4x4 @return: a python 4x4 matrix object
""" """
def getName(): def getName():

View File

@@ -25,17 +25,18 @@
* *
* This is a new part of Blender. * 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 ***** * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/ */
#include "gen_utils.h" #include <strings.h> /*for strcasecmp */
#include "constant.h"
#include <DNA_text_types.h> #include <DNA_text_types.h>
#include <MEM_guardedalloc.h> #include <MEM_guardedalloc.h>
#include "gen_utils.h"
#include "constant.h"
/*****************************************************************************/ /*****************************************************************************/
/* Description: This function clamps an int to the given interval */ /* Description: This function clamps an int to the given interval */
/* [min, max]. */ /* [min, max]. */
@@ -205,6 +206,22 @@ int EXPP_map_getIntVal (const EXPP_map_pair *map, const char *sval, int *ival)
return 0; 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 */ /* 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 */ /* pair is present, its ival is stored in *ival and nonzero is */

View File

@@ -60,7 +60,7 @@ PyObject *PythonIncRef (PyObject *object);
char * event_to_name (short event); char * event_to_name (short event);
float EXPP_ClampFloat (float value, float min, float max); 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_incr_ret (PyObject *object);
PyObject *EXPP_ReturnPyObjError (PyObject * type, char * error_msg); 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 */ /* mapping utilities - see Texture.c for an example of how to use these */
typedef struct { typedef struct {
const char *sval; const char *sval;
int ival; int ival;
} EXPP_map_pair; } EXPP_map_pair;
/* maps must end with a pair that has NULL as sval */ /* maps must end with a pair that has NULL as sval */
int EXPP_map_getIntVal (const EXPP_map_pair *map, 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, 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 EXPP_map_getStrVal (const EXPP_map_pair *map,
int ival, const char **sval); int ival, const char **sval);
/* scriplinks-related: */ /* scriplinks-related: */
PyObject *EXPP_getScriptLinks (ScriptLink *slink, PyObject *args, int is_scene); PyObject *EXPP_getScriptLinks (ScriptLink *slink, PyObject *args, int is_scene);

View File

@@ -204,5 +204,6 @@ PyObject * Mathutils_Init (void);
PyObject * NLA_Init (void); PyObject * NLA_Init (void);
PyObject * Library_Init (void); PyObject * Library_Init (void);
PyObject * Sound_Init (void); PyObject * Sound_Init (void);
PyObject * Theme_Init (void); /* Window.Theme */
#endif /* EXPP_modules_h */ #endif /* EXPP_modules_h */

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -1933,7 +1933,12 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
G.vd->flag |= V3D_NEEDBACKBUFDRAW; G.vd->flag |= V3D_NEEDBACKBUFDRAW;
addafterqueue(curarea->win, BACKBUFDRAW, 1); addafterqueue(curarea->win, BACKBUFDRAW, 1);
} }
/* scene redraw script link */
if(G.scene->scriptlink.totscript && !during_script()) {
BPY_do_pyscript((ID *)G.scene, SCRIPT_REDRAW);
}
} }