- Made Blender.event var (previously only used by script links) hold ascii value -- where it applies -- of current event during events callback registered with Draw.Register(gui, events, button_events).  Useful for gui scripts like Campbell's Python console. No problem using this var to hold the value, since in gui scripts it was not used (always None).

- Updated Window and Window.Theme with new theme vars and the Time space.

- Script links:

-- Added "Render" event for script links (runs twice, second time as "PostEvent", for clean-up actions). Now FrameChanged links don't run when a single pic is rendered.

-- Added "Enable Script Links" button in the script buttons tab.  Now this bit gets saved in .blends along with the rest of G.f, so users can define per .blend if they are on or off by default.  "blender -y" also disables all slinks as happened before with OnLoad ones only.

-- Other small changes in the script buttons tab:
  When a link is added (button "new"), it becomes the active one for the window, no need to press a button to reach it.
  Also, a pupmenu showing all available texts is shown when "new" is pressed, so users can choose a text w/o having to type.  Cancel the popup to leave the string button empty (link exists, but has no script assigned).  A pulldown would be better UI-wise, but it's kinda weird to show both scripts and normal texts (Blender doesn't differentiate them) in a script links pulldown.  With a popup we can show only texts ending in ".py" (not done in this commit, need opinions) and if the script has no or another extension, case of many in old and current .blend's, there's still the string box for writing its name.

-- Implemented Ton's space handler script links:

Right now only for the 3d View,  but it's trivial to add for others.  There are two types: EVENT, to receive 3d View events from a chosen window and DRAW, to draw on the window.  Ton's idea was to give scripts a controlled way to integrate better within Blender.

Here's how it works:

- scripts must have a proper header, like:
# SPACEHANDLER.VIEW3D.EVENT

and then they are shown in 3d View's View menu, "Space Handler Scripts" submenu.  Check (mark, click on it) a script to make it active.

EVENT handlers should consult the Blender.event var to get the current event, which can be compared with values from the Draw module:

import Blender
from Blender import Draw

evt = Blender.event
if evt == Draw.AKEY:
  print "a"
elif evt == Draw.LEFTMOUSE:
  print "left mouse button"
else:
  return # ignore, pass event back to Blender

Blender.event = None # tell Blender not to process itself the event

DRAW handlers are free to draw to their owner 3D View. OpenGL attributes and modelview and projection matrices are pushed before running the handler and poped when it finishes.

To communicate between EVENT and DRAW handler scripts we have the Blender.Registry module, as always.

Still need to code some nice example, which should also serve to test properly space handlers.  Simple tests went fine.

- doc updates about the additions.

=======

Note: the UI part of the space handlers and script links is of course open for changes, I just tried to make it understandable.  Probably we won't use the scriptlinks icon for "None Available" (check 3d View -> View -> Space Handler Scripts), though it hints at what space handlers are.  The tooltips may not be accepted either, since other menus don't use them.  Opinions welcomed.
This commit is contained in:
Willian Padovani Germano 2005-05-08 21:20:34 +00:00
parent 8077caa96e
commit 09fb5d6b8d
36 changed files with 821 additions and 132 deletions

View File

@ -58,8 +58,11 @@ void build_seqar(struct ListBase *seqbase, struct Sequence ***seqar, int *totse
struct ID;
struct Script;
struct Text;
void BPY_do_pyscript (struct ID *id, short int event);
void BPY_clear_script (struct Script *script);
void BPY_free_compiled_text (struct Text *text);
void BPY_free_screen_spacehandlers (struct bScreen *sc);
/* writefile.c */
struct Oops;

View File

@ -164,7 +164,7 @@ typedef struct Global {
#define G_VERTEXPAINT 1024
#define G_ALLEDGES 2048
#define G_DEBUG 4096
#define G_SCENESCRIPT 8192
#define G_DOSCRIPTLINKS (1 << 13)
/* #define G_PROPORTIONAL 16384 removed! so can be used later for other stuff */
#define G_WEIGHTPAINT 32768
#define G_TEXTUREPAINT 65536

View File

@ -78,6 +78,7 @@ void mainqenter (unsigned short event, short val){}
void BPY_do_pyscript(ID *id, short int event){}
void BPY_clear_script(Script *script){}
void BPY_free_compiled_text(struct Text *text){}
void BPY_free_screen_spacehandlers (struct bScreen *sc){}
/* writefile.c */
/* struct Oops; */

View File

@ -326,15 +326,14 @@ static void setup_app_data(BlendFileData *bfd, char *filename)
G.scene= G.main->scene.first;
G.curscreen->scene= G.scene;
}
/* special cases, override loaded flags: */
if (G.f & G_DEBUG) bfd->globalf |= G_DEBUG;
else bfd->globalf &= ~G_DEBUG;
if (G.f & G_SCENESCRIPT) bfd->globalf |= G_SCENESCRIPT;
else bfd->globalf &= ~G_SCENESCRIPT;
if (!(G.f & G_DOSCRIPTLINKS)) bfd->globalf &= ~G_DOSCRIPTLINKS;
G.f= bfd->globalf;
/* check posemode */
for(base= G.scene->base.first; base; base=base->next) {
ob= base->object;
@ -358,7 +357,7 @@ static void setup_app_data(BlendFileData *bfd, char *filename)
/* baseflags */
set_scene_bg(G.scene);
if (G.f & G_SCENESCRIPT) {
if (G.f & G_DOSCRIPTLINKS) {
/* there's an onload scriptlink to execute in screenmain */
mainqenter(ONLOAD_SCRIPT, 1);
}

View File

@ -1365,7 +1365,7 @@ void where_is_object_time(Object *ob, float ctime)
solve_constraints (ob, TARGET_OBJECT, NULL, ctime);
if(ob->scriptlink.totscript && !during_script()) {
BPY_do_pyscript((ID *)ob, SCRIPT_REDRAW);
if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript((ID *)ob, SCRIPT_REDRAW);
}
/* set negative scale flag in object */

View File

@ -361,7 +361,9 @@ void set_scene_bg(Scene *sce)
do_all_ipos(); /* layers/materials */
BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
/* do we need FRAMECHANGED in set_scene? */
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
do_all_keys();
#ifdef __NLA
do_all_actions(NULL);

View File

@ -50,7 +50,8 @@
void free_screen(bScreen *sc)
{
unlink_screen(sc);
BPY_free_screen_spacehandlers(sc);
BLI_freelistN(&sc->vertbase);
BLI_freelistN(&sc->edgebase);
BLI_freelistN(&sc->areabase);

View File

@ -73,7 +73,8 @@ A text should relate to a file as follows -
TXT_ISEXT - should always be set if the Text is not to be written into
the .blend
TXT_ISSCRIPT - should be set if the user has designated the text
as a script.
as a script. (NEW: this was unused, but now it is needed by
space handler script links (see header_view3d.c, for example)
->>> see also: /makesdna/DNA_text_types.h

View File

@ -2623,6 +2623,9 @@ static void lib_link_screen(FileData *fd, Main *main)
sa->full= newlibadr(fd, sc->id.lib, sa->full);
/* space handler scriptlinks */
lib_link_scriptlink(fd, &sc->id, &sa->scriptlink);
for (sl= sa->spacedata.first; sl; sl= sl->next) {
if(sl->spacetype==SPACE_VIEW3D) {
View3D *v3d= (View3D*) sl;
@ -2955,6 +2958,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sa->uiblocks.first= sa->uiblocks.last= NULL;
/* space handler scriptlinks */
direct_link_scriptlink(fd, &sa->scriptlink);
sa= sa->next;
}
}
@ -3132,7 +3138,6 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
case ID_SEQ: str= "ID_SEQ"; break;
case ID_AR: str= "ID_AR"; break;
case ID_AC: str= "ID_AC"; break;
case ID_SCRIPT: str= "ID_SCRIPT"; break;
}
/* read all data */
while(bhead && bhead->code==DATA) {

View File

@ -1208,6 +1208,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
pa= pa->next;
}
/* space handler scriptlinks */
write_scriptlink(wd, &sa->scriptlink);
sl= sa->spacedata.first;
while(sl) {
if(sl->spacetype==SPACE_VIEW3D) {

View File

@ -108,6 +108,8 @@ typedef struct ScrArea {
short headbutlen, headbutofs;
short cursor, flag;
ScriptLink scriptlink;
ListBase spacedata;
ListBase uiblocks;
ListBase panels;

View File

@ -56,10 +56,22 @@ typedef struct ScriptLink {
#define SCRIPT_ONLOAD 2
#define SCRIPT_REDRAW 4
#define SCRIPT_ONSAVE 8
#define SCRIPT_RENDER 16
/* POSTRENDER is not meant for the UI, it simply calls the
* RENDER script links for clean-up actions */
#define SCRIPT_POSTRENDER 32
/* **************** SPACE HANDLERS ********************* */
/* these are special scriptlinks that can be assigned to
* a given space in a given ScrArea to:
* - (EVENT type) handle events sent to that space;
* - (DRAW type) draw on the space after its own drawing function finishes
*/
#define SPACEHANDLER_VIEW3D_EVENT 1
#define SPACEHANDLER_VIEW3D_DRAW 2
#ifdef __cplusplus
}
#endif
#endif

View File

@ -72,8 +72,8 @@ typedef struct Text {
#define TXT_ISTMP 0x0002
#define TXT_ISMEM 0x0004
#define TXT_ISEXT 0x0008
#define TXT_ISSCRIPT 0x0010
#define TXT_ISSCRIPT 0x0010 /* used by space handler scriptlinks */
#define TXT_READONLY 0x0100
#define TXT_FOLLOW 0x0200 // always follow cursor (console)
#define TXT_FOLLOW 0x0200 /* always follow cursor (console) */
#endif

View File

@ -23,7 +23,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: source/blender/bpyton/include/BPY_extern.h
* The Original Code was in: source/blender/bpython/include/BPY_extern.h
*
* Contributor(s): Michel Selten, Willian P. Germano, Chris Keith
*
@ -32,16 +32,16 @@
extern char bprogname[]; /* holds a copy of argv[0], from creator.c */
struct Text; /* defined in DNA_text_types.h */
struct ID; /* defined in DNA_ID.h */
struct ScriptLink; /* defined in DNA_scriptlink_types.h */
struct ListBase; /* defined in DNA_listBase.h */
struct SpaceText; /* defined in DNA_space_types.h */
struct SpaceScript; /* defined in DNA_space_types.h */
struct Script; /* defined in BPI_script.h */
/*
struct _object; // forward declaration for PyObject !
*/
struct Text; /* defined in DNA_text_types.h */
struct ID; /* DNA_ID.h */
struct ScriptLink; /* DNA_scriptlink_types.h */
struct ListBase; /* DNA_listBase.h */
struct SpaceText; /* DNA_space_types.h */
struct SpaceScript; /* DNA_space_types.h */
struct Script; /* BPI_script.h */
struct ScrArea; /* DNA_screen_types.h */
struct bScreen; /* DNA_screen_types.h */
#ifdef __cplusplus
extern "C" {
#endif
@ -49,16 +49,18 @@ extern "C" {
void BPY_start_python( int argc, char **argv );
void BPY_end_python( void );
void BPY_post_start_python( void );
void init_syspath( int first_time );
void syspath_append( char *dir );
int BPY_Err_getLinenumber( void );
const char *BPY_Err_getFilename( void );
/* void BPY_Err_Handle(struct Text *text); */
int BPY_txt_do_python_Text( struct Text *text );
int BPY_menu_do_python( short menutype, int event );
void BPY_run_python_script( char *filename );
void BPY_free_compiled_text( struct Text *text );
/*void BPY_clear_bad_scriptlink(struct ID *id, struct Text *byebye); */
void BPY_clear_bad_scriptlinks( struct Text *byebye );
/*void BPY_clear_bad_scriptlist(struct ListBase *, struct Text *byebye); */
int BPY_has_onload_script( void );
void BPY_do_all_scripts( short event );
int BPY_check_all_scriptlinks( struct Text *text );
@ -66,18 +68,27 @@ extern "C" {
void BPY_free_scriptlink( struct ScriptLink *slink );
void BPY_copy_scriptlink( struct ScriptLink *scriptlink );
int BPY_is_spacehandler(struct Text *text, char spacetype);
int BPY_del_spacehandler(struct Text *text, struct ScrArea *sa);
int BPY_add_spacehandler(struct Text *txt, struct ScrArea *sa,char spacetype);
int BPY_has_spacehandler(struct Text *text, struct ScrArea *sa);
void BPY_screen_free_spacehandlers(struct bScreen *sc);
int BPY_do_spacehandlers(struct ScrArea *sa, unsigned short event,
unsigned short space_event);
/* format importer hook */
int BPY_call_importloader( char *name );
//int BPY_spacetext_is_pywin(struct SpaceText *st);
void BPY_spacescript_do_pywin_draw( struct SpaceScript *sc );
void BPY_spacescript_do_pywin_event( struct SpaceScript *sc,
unsigned short event, short val );
unsigned short event, short val, char ascii );
void BPY_clear_script( struct Script *script );
void BPY_free_finished_script( struct Script *script );
void init_syspath( int first_time );
void syspath_append( char *dir );
/* void BPY_Err_Handle(struct Text *text); */
/* void BPY_clear_bad_scriptlink(struct ID *id, struct Text *byebye); */
/* void BPY_clear_bad_scriptlist(struct ListBase *, struct Text *byebye); */
/* int BPY_spacetext_is_pywin(struct SpaceText *st); */
#ifdef __cplusplus
} /* extern "C" */

View File

@ -43,6 +43,7 @@
#include <MEM_guardedalloc.h>
#include <BLI_blenlib.h> /* for BLI_last_slash() */
#include "BIF_gl.h" /* glPushAttrib, glPopAttrib for DRAW space handlers */
#include <BIF_interface.h> /* for pupmenu() */
#include <BIF_space.h>
#include <BIF_screen.h>
@ -1062,6 +1063,8 @@ void BPY_do_pyscript( ID * id, short event )
PyString_FromString( event_to_name
( event ) ) );
if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
for( index = 0; index < scriptlink->totscript; index++ ) {
if( ( scriptlink->flag[index] == event ) &&
( scriptlink->scripts[index] != NULL ) ) {
@ -1103,6 +1106,249 @@ void BPY_do_pyscript( ID * id, short event )
}
}
/* SPACE HANDLERS */
/* These are special script links that can be assigned to ScrArea's to
* (EVENT type) receive events sent to a given space (and use or ignore them) or
* (DRAW type) be called after the space is drawn, to draw anything on top of
* the space area. */
/* How to add space handlers to other spaces:
* - add the space event defines to DNA_scriptlink_types.h, as done for
* 3d view: SPACEHANDLER_VIEW3D_EVENT, for example;
* - add the new defines to Blender.SpaceHandler dictionary in Blender.c;
* - check space.c for how to call the event handlers;
* - check drawview.c for how to call the draw handlers;
* - check header_view3d.c for how to add the "Space Handler Scripts" menu.
* Note: DRAW handlers should be called with 'event = 0', chech drawview.c */
int BPY_has_spacehandler(Text *text, ScrArea *sa)
{
ScriptLink *slink;
int index;
if (!sa || !text) return 0;
slink = &sa->scriptlink;
for (index = 0; index < slink->totscript; index++) {
if (slink->scripts[index] && (slink->scripts[index] == (ID *)text))
return 1;
}
return 0;
}
int BPY_is_spacehandler(Text *text, char spacetype)
{
TextLine *tline = text->lines.first;
unsigned short type = 0;
if (tline && (tline->len > 10)) {
char *line = tline->line;
/* Expected format: # SPACEHANDLER.SPACE.TYPE
* Ex: # SPACEHANDLER.VIEW3D.DRAW
* The actual checks are forgiving, so slight variations also work. */
if (line && line[0] == '#' && strstr(line, "HANDLER")) {
line++; /* skip '#' */
/* only done for 3D View right now, trivial to add for others: */
switch (spacetype) {
case SPACE_VIEW3D:
if (strstr(line, "3D")) { /* VIEW3D, 3DVIEW */
if (strstr(line, "DRAW")) type = SPACEHANDLER_VIEW3D_DRAW;
else if (strstr(line, "EVENT")) type = SPACEHANDLER_VIEW3D_EVENT;
}
break;
}
}
}
return type; /* 0 if not a space handler */
}
int BPY_del_spacehandler(Text *text, ScrArea *sa)
{
ScriptLink *slink;
int i, j;
if (!sa || !text) return -1;
slink = &sa->scriptlink;
if (slink->totscript < 1) return -1;
for (i = 0; i < slink->totscript; i++) {
if (text == (Text *)slink->scripts[i]) {
for (j = i; j < slink->totscript - 1; j++) {
slink->flag[j] = slink->flag[j+1];
slink->scripts[j] = slink->scripts[j+1];
}
slink->totscript--;
/* like done in buttons_script.c we just free memory
* if all slinks have been removed -- less fragmentation,
* these should be quite small arrays */
if (slink->totscript == 0) {
if (slink->scripts) MEM_freeN(slink->scripts);
if (slink->flag) MEM_freeN(slink->flag);
break;
}
}
}
return 0;
}
int BPY_add_spacehandler(Text *text, ScrArea *sa, char spacetype)
{
unsigned short handlertype;
if (!sa || !text) return -1;
handlertype = BPY_is_spacehandler(text, spacetype);
if (handlertype) {
ScriptLink *slink = &sa->scriptlink;
void *stmp, *ftmp;
unsigned short space_event = SPACEHANDLER_VIEW3D_EVENT;
/* extend slink */
stmp= slink->scripts;
slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1),
"spacehandlerscripts");
ftmp= slink->flag;
slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1),
"spacehandlerflags");
if (slink->totscript) {
memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
MEM_freeN(stmp);
memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
MEM_freeN(ftmp);
}
switch (spacetype) {
case SPACE_VIEW3D:
if (handlertype == 1) space_event = SPACEHANDLER_VIEW3D_EVENT;
else space_event = SPACEHANDLER_VIEW3D_DRAW;
break;
default:
break;
}
slink->scripts[slink->totscript] = (ID *)text;
slink->flag[slink->totscript]= space_event;
slink->totscript++;
slink->actscript = slink->totscript;
}
return 0;
}
int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
unsigned short space_event )
{
ScriptLink *scriptlink;
int retval = 0;
if (!sa) return 0;
scriptlink = &sa->scriptlink;
if (scriptlink->totscript > 0) {
PyObject *dict;
PyObject *ret;
int index, during_slink = during_scriptlink();
/* invalid scriptlinks (new .blend was just loaded), return */
if (during_slink < 0) return 0;
/* tell we're running a scriptlink. The sum also tells if this script
* is running nested inside another. Blender.Load needs this info to
* avoid trouble with invalid slink pointers. */
during_slink++;
disable_where_scriptlink( during_slink );
/* set globals in Blender module to identify space handler scriptlink */
PyDict_SetItemString(g_blenderdict, "bylink", EXPP_incr_ret_True());
/* unlike normal scriptlinks, here Blender.link is int (space event type) */
PyDict_SetItemString(g_blenderdict, "link", PyInt_FromLong(space_event));
/* note: DRAW space_events set event to 0 */
PyDict_SetItemString(g_blenderdict, "event", PyInt_FromLong(event));
/* now run all assigned space handlers for this space and space_event */
for( index = 0; index < scriptlink->totscript; index++ ) {
/* for DRAW handlers: */
if (event == 0) {
glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
}
if( ( scriptlink->flag[index] == space_event ) &&
( scriptlink->scripts[index] != NULL ) ) {
dict = CreateGlobalDictionary();
ret = RunPython( ( Text * ) scriptlink->scripts[index], dict );
ReleaseGlobalDictionary( dict );
if (!ret) { /* Failed execution of the script */
BPY_Err_Handle( scriptlink->scripts[index]->name+2 );
} else {
Py_DECREF(ret);
/* an EVENT type (event != 0) script can either accept an event or
* ignore it:
* if the script sets Blender.event to None it accepted it;
* otherwise the space's event handling callback that called us
* can go on processing the event */
if (event && (PyDict_GetItemString(g_blenderdict,"event") == Py_None))
retval = 1; /* event was swallowed */
}
/* If a scriptlink has just loaded a new .blend file, the
* scriptlink pointer became invalid (see api2_2x/Blender.c),
* so we stop here. */
if( during_scriptlink( ) == -1 ) {
during_slink = 1;
if (event == 0) glPopAttrib();
break;
}
}
/* for DRAW handlers: */
if (event == 0) {
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
}
disable_where_scriptlink( during_slink - 1 );
PyDict_SetItemString(g_blenderdict, "bylink", EXPP_incr_ret_False());
PyDict_SetItemString(g_blenderdict, "link", EXPP_incr_ret(Py_None));
PyDict_SetItemString(g_blenderdict, "event", PyString_FromString(""));
}
/* retval:
* space_event is of type EVENT:
* 0 - event was returned,
* 1 - event was processed;
* space_event is of type DRAW:
* 0 always */
return retval;
}
/*****************************************************************************
* Description:
* Notes:
@ -1119,6 +1365,31 @@ void BPY_free_scriptlink( struct ScriptLink *slink )
return;
}
void BPY_free_screen_spacehandlers(struct bScreen *sc)
{
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next)
BPY_free_scriptlink(&sa->scriptlink);
}
static int CheckAllSpaceHandlers(Text *text)
{
bScreen *screen;
ScrArea *sa;
ScriptLink *slink;
int fixed = 0;
for (screen = G.main->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
slink = &sa->scriptlink;
if (!slink->totscript) continue;
if (BPY_del_spacehandler(text, sa) == 0) fixed++;
}
}
return fixed;
}
static int CheckAllScriptsFromList( ListBase * list, Text * text )
{
ID *id;
@ -1154,11 +1425,11 @@ int BPY_check_all_scriptlinks( Text * text )
fixed += CheckAllScriptsFromList( &( G.main->mat ), text );
fixed += CheckAllScriptsFromList( &( G.main->world ), text );
fixed += CheckAllScriptsFromList( &( G.main->scene ), text );
fixed += CheckAllSpaceHandlers(text);
return fixed;
}
/*****************************************************************************
* Description:
* Notes:

View File

@ -57,6 +57,7 @@
#include <DNA_scene_types.h>
#include <DNA_screen_types.h> /* for SPACE_VIEW3D */
#include <DNA_space_types.h> /* for SPACE_VIEW3D */
#include <DNA_scriptlink_types.h>
#include <DNA_userdef_types.h>
#include <BKE_ipo.h>
#include <blendef.h>
@ -64,6 +65,7 @@
#include "EXPP_interface.h" /* for bpy_gethome() */
#include "gen_utils.h"
#include "modules.h"
#include "constant.h"
#include "../BPY_extern.h" /* BPY_txt_do_python_Text */
#include "../BPY_menus.h" /* to update menus */
@ -737,7 +739,7 @@ static PyObject * Blender_UpdateMenus( PyObject * self )
void M_Blender_Init( void )
{
PyObject *module;
PyObject *dict, *smode;
PyObject *dict, *smode, *SpaceHandlers;
g_blenderdict = NULL;
@ -746,6 +748,16 @@ void M_Blender_Init( void )
types_InitAll( ); /* set all our pytypes to &PyType_Type */
SpaceHandlers = M_constant_New();
if (SpaceHandlers) {
BPy_constant *d = (BPy_constant *)SpaceHandlers;
constant_insert(d,"VIEW3D_EVENT",PyInt_FromLong(SPACEHANDLER_VIEW3D_EVENT));
constant_insert(d,"VIEW3D_DRAW", PyInt_FromLong(SPACEHANDLER_VIEW3D_DRAW));
PyModule_AddObject(module, "SpaceHandlers", SpaceHandlers);
}
if (G.background)
smode = PyString_FromString("background");
else

View File

@ -70,6 +70,9 @@
#include "interface.h"
#include "mydevice.h" /*@ for all the event constants */
/* pointer to main dictionary defined in Blender.c */
extern PyObject *g_blenderdict;
/*@ hack to flag that window redraw has happened inside slider callback: */
int EXPP_disable_force_draw = 0;
@ -505,7 +508,7 @@ static void spacescript_do_pywin_buttons( SpaceScript * sc,
}
void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
short val )
short val, char ascii )
{
static int menu_hack = 0;
@ -546,9 +549,20 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
}
}
if( sc->script->py_event )
/* Using the "event" main module var, used by scriptlinks, to pass the ascii
* value to event callbacks (gui/event/button callbacks are not allowed
* inside scriptlinks, so this is ok) */
if( sc->script->py_event ) {
int pass_ascii = 0;
if (ascii > 31 && ascii != 127) {
pass_ascii = 1;
PyDict_SetItemString(g_blenderdict, "event", PyInt_FromLong((long)ascii));
}
exec_callback( sc, sc->script->py_event,
Py_BuildValue( "(ii)", event, val ) );
Py_BuildValue( "(ii)", event, val ) );
if (pass_ascii)
PyDict_SetItemString(g_blenderdict, "event", PyString_FromString(""));
}
}
static PyObject *Method_Exit( PyObject * self, PyObject * args )
@ -635,7 +649,7 @@ static PyObject *Method_Register( PyObject * self, PyObject * args )
script = sc->script;
if( !script ) {
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Draw.Register: couldn't get pointer to script struct" );
"Draw.Register can't be used inside script links" );
}
}
else sc->script = script;

View File

@ -69,7 +69,7 @@ typedef struct _Button {
*/
void BPY_spacescript_do_pywin_draw( SpaceScript * sc );
void BPY_spacescript_do_pywin_event( SpaceScript * sc,
unsigned short event, short val );
unsigned short event, short val, char ascii );
void BPY_free_compiled_text( Text * text );
PyObject *M_Draw_Init( void );

View File

@ -1346,6 +1346,7 @@ PyObject *Window_Init( void )
constant_insert( d, "TEXT", PyInt_FromLong( SPACE_TEXT ) );
constant_insert( d, "NLA", PyInt_FromLong( SPACE_NLA ) );
constant_insert( d, "SCRIPT", PyInt_FromLong( SPACE_SCRIPT ) );
constant_insert( d, "TIME", PyInt_FromLong( SPACE_TIME ) );
PyModule_AddObject( submodule, "Types", Types );
}

View File

@ -4,6 +4,8 @@
The Blender Python API Reference
================================
An asterisk (*) means the module has been updated.
Top Module:
-----------
@ -17,7 +19,7 @@ The Blender Python API Reference
- L{BGL}
- L{Camera} (*)
- L{Curve} (*)
- L{Draw}
- L{Draw} (*)
- L{Effect}
- L{Image} (*)
- L{Ipo}
@ -47,11 +49,10 @@ The Blender Python API Reference
Additional information:
-----------------------
- L{Misc facilities<API_related>}:
- L{Special features<API_related>}:
- scripts: registering in menus, documenting, configuring (new);
- command line examples (new).
(*) - marks updated.
- command line examples (new);
- script links (*), space handler script links (new).
Introduction:
=============

View File

@ -15,6 +15,10 @@ Introduction:
- Command line mode is accessible with the '-P' and '-b' Blender options.
- Registration allows scripts to become available from some pre-defined menus
in Blender, like Import, Export, Wizards and so on.
- Script links are Blender Texts (scripts) executed when a particular event
(redraws, .blend file loading, saving, frame changed, etc.) occurs. Now
there are also "Space Handlers" to draw onto or get events from a given
space (only 3D View now) in some window.
- Proper documentation data is used by the 'Scripts Help Browser' script to
show help information for any registered script. Your own GUI can use
this facility with the L{Blender.ShowHelp} function.
@ -25,9 +29,10 @@ Introduction:
Command line usage:
-------------------
===================
B{Specifying scripts}:
Specifying scripts:
-------------------
The '-P' option followed either by:
- a script filename (full pathname if not in the same folder where you run
@ -40,7 +45,8 @@ Introduction:
# open Blender and execute the given script:
blender -P script.py
B{Passing parameters}:
Passing parameters:
-------------------
To pass parameters to the script you can:
- write them to a file before running Blender, then make your script parse that file;
@ -64,7 +70,8 @@ Introduction:
myvar1=value1 myvar2=value2 mystr="some string data" blender -P script.py
B{Background mode}:
Background mode:
----------------
In '-b' mode no windows will be opened: the program will run as a command
line tool able to render stills and animations and execute any working Python
@ -108,9 +115,141 @@ Introduction:
- an animation from frame 1 to 10: blender -b myfile.blend -s 1 -e 10 -a
Registering scripts:
Script links:
=============
Object script links:
--------------------
Users can link Blender Text scripts to some kinds of objects to have the script
code executed when specific events occur. For example, if a Camera has an
script link set to "FrameChanged", the script will be executed whenever the
current frame is changed. Links can either be manually added by users on the
Buttons window -> Scripts tab or created by another script (see, for example,
L{Object.addScriptLink<Object.Object.addScriptLink>}).
These are the types which can be linked to scripts:
- Camera Data;
- Lamp Data;
- Materials;
- Objects;
- Scenes;
- Worlds.
And these are the available event choices:
- Redraw;
- FrameChanged;
- Render;
- OnLoad (*);
- OnSave (*).
(*) only available for scenes
There are three L{Blender} module variables that script link authors should
be aware of:
- B{bylink}: True if the script is running as a script link;
- B{link}: the object the running script was linked to (None if this is
not a script link);
- B{event}: the event type, if the running script is being executed as a
script link.
B{Important note about "Render" events}:
Each "Render" script link is executed twice: before rendering and after, for
reverting changes and for possible clean up actions. Before rendering,
'Blender.event' will be "Render" and after rendering it will be "PostRender".
This is specially useful for script links that need to generate data only
useful while rendering, or in case they need to switch between two mesh data
objects, one meant for realtime display and the other, more detailed, for
renders. This pseudo-code is an example of how such scripts could be written::
import Blender
if Blender.event == "Render":
# prepare for rendering
elif Blender.event == "PostRender":
# revert changes / clean up for realtime display
Space Handler script links:
---------------------------
This is a new kind of script linked to spaces in a given window. Right now
only the 3D View has the necessary hooks, but the plan is to add access to
other types, too. Just to clarify: in Blender, a screen is partitioned in
windows and each window can show any space. Spaces are: 3D View, Text Editor,
Scripts, Buttons, User Preferences, Oops, etc.
Space handlers are texts in the Text Editor, like other script links, but they
need to have a special header to be recognized -- B{I{the first line in the
text file}} must inform 1) that they are space handlers; 2) the space they
belong to; 3) whether they are EVENT or DRAW handlers.
Example header for a 3D View EVENT handler::
# SPACEHANDLER.VIEW3D.EVENT
Example header for a 3D View DRAW handler::
# SPACEHANDLER.VIEW3D.DRAW
EVENT space handler scripts are called by that space's event handling callback
in Blender. The script receives the event B{before} it is further processed
by the program. An EVENT handler script should check Blender.event (compare
it against L{Draw} events) and either:
- process it (then set Blender.event to None);
- ignore it.
Setting C{Blender.event = None} tells Blender not to go on processing itself
the event, because it was grabbed by the script.
Example::
# SPACEHANDLER.VIEW3D.EVENT
import Blender
from Blender import DRAW
evt = Blender.event
if evt == DRAW.LEFTMOUSE:
print "Swallowing the left mouse button press"
elif evt == DRAW.AKEY:
print "Swallowing an 'a' character"
else:
print "Let the 3D View itself process this event:", evt
return
# if Blender should not process itself the passed event:
Blender.event = None
DRAW space handlers are called by that space's drawing callback in Blender.
The script is called B{after} the space has been drawn.
Two of the L{Blender} module variables related to script links assume
different roles for space handlers:
- B{bylink} is the same: True if the script is running as a script link;
- B{link}: integer from the L{Blender}.SpaceHandlers constant dictionary,
tells what space this handler belongs to and the handler's type
(EVENT, DRAW);
- B{event}:
- EVENT handlers: an input event (check keys and mouse events in L{Draw})
to be processed or ignored.
- DRAW handlers: 0 always.
B{Guidelines}:
- EVENT handlers can access and change Blender objects just like any other
script, but they should not draw (images, polygons, etc.) to the screen,
use a DRAW handler to do that and if both scripts need to pass information
to each other, use the L{Registry} module.
- DRAW handlers should leave the space in the same state it was before they
executed. OpenGL attributes are automatically saved (pushed) before a DRAW
handler runs and restored (poped) after it finishes, no need to worry about
that.
Registering scripts:
====================
To be registered a script needs two things:
- to be either in the default scripts dir or in the user defined scripts
path (see User Preferences window -> File Paths tab -> Python path);
@ -163,7 +302,7 @@ Introduction:
Documenting scripts:
--------------------
====================
The "Scripts Help Browser" script in the Help menu can parse special variables
from registered scripts and display help information for users. For that,
@ -236,7 +375,7 @@ Introduction:
help browser with the L{Blender.ShowHelp} function.
Configuring scripts:
--------------------
====================
The L{Blender.Registry<Registry>} module provides a simplified way to keep
scripts configuration options in memory and also saved in config files.
@ -328,7 +467,8 @@ Introduction:
itself is limited to 60.
B{Scripts Configuration Editor}:
Scripts Configuration Editor:
-----------------------------
This script should be available from the System menu in the Scripts window.
It provides a GUI to view and edit saved configuration data, both from the
@ -398,4 +538,5 @@ Introduction:
in your script's help info, as done in the ac3d ones.
L{Back to Main Page<API_intro>}
===============================
"""

View File

@ -10,20 +10,30 @@
"""
The main Blender module.
B{New}: L{Run}, L{UpdateMenus}, new options to L{Get}, L{ShowHelp}.
B{New}: L{Run}, L{UpdateMenus}, new options to L{Get}, L{ShowHelp},
L{SpaceHandlers} dictionary.
Blender
=======
@type bylink: bool
@var bylink: True if the current script is being executed as a script link.
@type link: Blender Object or None
@var link: if this script is a running script link, 'link' points to the
linked Object (can be a scene, object (mesh, camera, lamp), material or
world). If this is not a script link, 'link' is None.
@type event: string
@var event: if this script is a running script link, 'event' tells what
kind of link triggered it (ex: OnLoad, FrameChanged, Redraw, etc.).
@type link: Blender Object or None; integer (space handlers)
@var link: for normal script links, 'link' points to the linked Object (can be
a scene, object (mesh, camera, lamp), material or
world). For space handler script links, 'link' is an integer from the
Blender.L{SpaceHandlers} dictionary. For script not running as script
links, 'link' is None.
@type event: string or int
@var event: this has three possible uses: script link type or events callback
ascii value:
- for normal script links it is a string representing the link type
(OnLoad, FrameChanged, Redraw, etc.).
- for EVENT space handler script links it is the passed event.
- for normal L{GUI<Draw.Register>} scripts I{during the events callback},
it holds the ascii value of the current event, if it is a valid one.
Users interested in this should also check the builtin 'ord' and 'chr'
Python functions.
@type mode: string
@var mode: Blender's current mode:
- 'interactive': normal mode, with an open window answering to user input;
@ -31,6 +41,10 @@ Blender
will exit as soon as it finishes rendering or executing a script
(ex: 'C{blender -b <blender file> -P <script>}'). Try 'C{blender -h}'
for more detailed informations.
@type SpaceHandlers: constant dictionary
@var SpaceHandlers: dictionary with space handler types.
- VIEW3D_EVENT;
- VIEW3D_DRAW.
"""
def Set (request, data):

View File

@ -6,7 +6,7 @@ The Blender.Draw submodule.
Draw
====
B{New}: L{PupIntInput}, L{PupFloatInput}, L{PupStrInput}, mouse wheel events.
B{New}: access to ascii values in L{events<Register>} callbacks.
This module provides access to a B{windowing interface} in Blender. Its widgets
include many kinds of buttons: push, toggle, menu, number, string, slider,
@ -240,6 +240,8 @@ def Register(draw = None, event = None, button = None):
is called only once. It's not necessary to re-register the callbacks,
they will stay until Draw.Exit is called. It's enough to redraw the
screen, when a relevant event is caught.
@note: only during the B{event} callback: the L{Blender}.ascii variable holds
the ascii integer value (if it exists and is valid) of the current event.
"""
def Redraw(after = 0):

View File

@ -181,8 +181,11 @@ class Theme:
@cvar edge_facesel: theme rgba var.
@cvar face: theme rgba var.
@cvar face_select: theme rgba var.
@cvar face_dot: theme rgba var.
@cvar normal: theme rgba var.
@type vertex_size: int
@cvar vertex_size: size of the vertices dots on screen in the range [1, 10].
@type facedot_size: int
@cvar facedot_size: size of the face dots on screen in the range [1, 10].
"""

View File

@ -155,6 +155,10 @@ char *event_to_name( short event )
return "OnSave";
case SCRIPT_REDRAW:
return "Redraw";
case SCRIPT_RENDER:
return "Render";
case SCRIPT_POSTRENDER:
return "PostRender";
default:
return "Unknown";
}
@ -314,6 +318,8 @@ PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * args,
event = SCRIPT_FRAMECHANGED;
else if( !strcmp( eventname, "Redraw" ) )
event = SCRIPT_REDRAW;
else if( !strcmp( eventname, "Render" ) )
event = SCRIPT_RENDER;
else if( is_scene && !strcmp( eventname, "OnLoad" ) )
event = SCRIPT_ONLOAD;
else if( is_scene && !strcmp( eventname, "OnSave" ) )
@ -465,6 +471,8 @@ PyObject *EXPP_addScriptLink(ScriptLink *slink, PyObject *args, int is_scene)
event = SCRIPT_FRAMECHANGED;
else if( !strcmp( eventname, "Redraw" ) )
event = SCRIPT_REDRAW;
else if( !strcmp( eventname, "Render" ) )
event = SCRIPT_RENDER;
else if( is_scene && !strcmp( eventname, "OnLoad" ) )
event = SCRIPT_ONLOAD;
else if( is_scene && !strcmp( eventname, "OnSave" ) )

View File

@ -39,10 +39,12 @@
#define EXPP_THEME_VTX_SIZE_MIN 1
#define EXPP_THEME_VTX_SIZE_MAX 10
#define EXPP_THEME_FDOT_SIZE_MIN 1
#define EXPP_THEME_FDOT_SIZE_MAX 10
#define EXPP_THEME_DRAWTYPE_MIN 1
#define EXPP_THEME_DRAWTYPE_MAX 4
#define EXPP_THEME_NUMBEROFTHEMES 14
#define EXPP_THEME_NUMBEROFTHEMES 15
static const EXPP_map_pair themes_map[] = {
{"ui", -1},
{"buts", SPACE_BUTS},
@ -58,6 +60,7 @@ static const EXPP_map_pair themes_map[] = {
{"imasel", SPACE_IMASEL},
{"text", SPACE_TEXT},
{"oops", SPACE_OOPS},
{"time", SPACE_TIME},
{NULL, 0}
};
@ -164,18 +167,21 @@ static PyObject *ThemeSpace_getAttr( BPy_ThemeSpace * self, char *name )
ELSEIF_TSP_RGBA( edge_facesel )
ELSEIF_TSP_RGBA( face )
ELSEIF_TSP_RGBA( face_select )
ELSEIF_TSP_RGBA( face_dot )
ELSEIF_TSP_RGBA( normal )
else if( !strcmp( name, "vertex_size" ) )
attrib = Py_BuildValue( "i", tsp->vertex_size );
else if( !strcmp( name, "facedot_size" ) )
attrib = Py_BuildValue( "i", tsp->facedot_size );
else if( !strcmp( name, "__members__" ) )
attrib = Py_BuildValue( "[ssssssssssssssssssssssss]", "theme",
attrib = Py_BuildValue( "[ssssssssssssssssssssssssss]", "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" );
"face_dot", "normal", "vertex_size", "facedot_size" );
if( attrib != Py_None )
return attrib;
@ -214,6 +220,7 @@ static int ThemeSpace_setAttr( BPy_ThemeSpace * self, char *name,
ELSEIF_TSP_RGBA( edge_facesel )
ELSEIF_TSP_RGBA( face )
ELSEIF_TSP_RGBA( face_select )
ELSEIF_TSP_RGBA( face_dot )
ELSEIF_TSP_RGBA( normal )
else if( !strcmp( name, "vertex_size" ) ) {
int val;
@ -227,6 +234,19 @@ static int ThemeSpace_setAttr( BPy_ThemeSpace * self, char *name,
EXPP_THEME_VTX_SIZE_MIN,
EXPP_THEME_VTX_SIZE_MAX );
ret = 0;
}
else if( !strcmp( name, "facedot_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_FDOT_SIZE_MIN,
EXPP_THEME_FDOT_SIZE_MAX );
ret = 0;
} else
return EXPP_ReturnIntError( PyExc_AttributeError,
"attribute not found" );
@ -662,6 +682,9 @@ static PyObject *Theme_get( BPy_Theme * self, PyObject * args )
case SPACE_OOPS:
tsp = &btheme->toops;
break;
case SPACE_TIME:
tsp = &btheme->ttime;
break;
}
if( tui ) {

View File

@ -2941,7 +2941,7 @@ void RE_rotateBlenderScene(void)
R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
do_all_ipos();
BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
do_all_keys();
#ifdef __NLA
do_all_actions(NULL);

View File

@ -47,6 +47,7 @@
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_group_types.h"
#include "DNA_ID.h"
#include "DNA_ika_types.h"
#include "DNA_image_types.h"
#include "DNA_key_types.h"
@ -59,6 +60,7 @@
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_sound_types.h"
#include "DNA_text_types.h"
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
#include "DNA_vfont_types.h"
@ -77,6 +79,7 @@
#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
@ -87,6 +90,7 @@
#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BSE_filesel.h"
@ -111,10 +115,6 @@
/* ************************ function prototypes ********************** */
void draw_scriptlink(uiBlock *, ScriptLink *, int , int , int ) ;
/* *************************** SCRIPT ******************************** */
static void extend_scriptlink(ScriptLink *slink)
@ -141,8 +141,7 @@ static void extend_scriptlink(ScriptLink *slink)
slink->flag[slink->totscript]= SCRIPT_FRAMECHANGED;
slink->totscript++;
if(slink->actscript<1) slink->actscript=1;
slink->actscript = slink->totscript;
}
static void delete_scriptlink(ScriptLink *slink)
@ -172,16 +171,55 @@ static void delete_scriptlink(ScriptLink *slink)
}
}
static char *scriptlinks_menu_string(void)
{
char *menu = NULL;
DynStr *ds = BLI_dynstr_new();
Text *text = G.main->text.first;
int txtcounter = 0;
if (text) {
BLI_dynstr_append(ds, "Select Script Link%t");
while (text) {
BLI_dynstr_append(ds, "|");
BLI_dynstr_append(ds, text->id.name+2);
txtcounter += 1;
text = text->id.next;
}
if (txtcounter) menu = BLI_dynstr_get_cstring(ds);
}
BLI_dynstr_free(ds);
return menu;
}
static void scriptlinks_pupmenu(ScriptLink *slink)
{
short menuitem;
char *menustr = scriptlinks_menu_string();
if (menustr) {
menuitem = pupmenu_col(menustr, 20);
MEM_freeN(menustr);
if (menuitem > 0) {
Text *text = G.main->text.first;
while (--menuitem) text = text->id.next;
if (text) slink->scripts[slink->totscript - 1]= (ID *)text;
}
}
}
void do_scriptbuts(unsigned short event)
{
Object *ob=NULL;
ScriptLink *script=NULL;
ScriptLink *slink=NULL;
Material *ma;
switch (event) {
case B_SSCRIPT_ADD:
extend_scriptlink(&G.scene->scriptlink);
slink = &G.scene->scriptlink;
extend_scriptlink(slink);
BIF_undo_push("Add scriptlink");
scriptlinks_pupmenu(slink);
break;
case B_SSCRIPT_DEL:
BIF_undo_push("Delete scriptlink");
@ -193,31 +231,32 @@ void do_scriptbuts(unsigned short event)
ob= OBACT;
if (ob && G.buts->scriptblock==ID_OB) {
script= &ob->scriptlink;
slink= &ob->scriptlink;
} else if (ob && G.buts->scriptblock==ID_MA) {
ma= give_current_material(ob, ob->actcol);
if (ma) script= &ma->scriptlink;
if (ma) slink= &ma->scriptlink;
} else if (ob && G.buts->scriptblock==ID_CA) {
if (ob->type==OB_CAMERA)
script= &((Camera *)ob->data)->scriptlink;
slink= &((Camera *)ob->data)->scriptlink;
} else if (ob && G.buts->scriptblock==ID_LA) {
if (ob->type==OB_LAMP)
script= &((Lamp *)ob->data)->scriptlink;
slink= &((Lamp *)ob->data)->scriptlink;
} else if (G.buts->scriptblock==ID_WO) {
if (G.scene->world)
script= &(G.scene->world->scriptlink);
slink= &(G.scene->world->scriptlink);
}
if (event==B_SCRIPT_ADD) {
extend_scriptlink(script);
extend_scriptlink(slink);
BIF_undo_push("Add scriptlink");
scriptlinks_pupmenu(slink);
}
else {
delete_scriptlink(script);
delete_scriptlink(slink);
BIF_undo_push("Delete scriptlink");
}
break;
@ -235,6 +274,7 @@ void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int sce
if (script->totscript) {
strcpy(str, "FrameChanged%x 1|");
strcat(str, "Redraw%x 4|");
strcat(str, "Render%x 16|");
if (scene) {
strcat(str, "OnLoad%x 2|");
strcat(str, "OnSave%x 8");
@ -254,7 +294,7 @@ void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int sce
if (script->totscript)
uiDefBut(block, BUT, B_SSCRIPT_DEL, "Del", (short)(sx+200), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Delete the current Script link");
uiDefBut(block, LABEL, 0, "Scene scriptlink", sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Scene Script link", sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
}
else {
@ -263,7 +303,7 @@ void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int sce
if (script->totscript)
uiDefBut(block, BUT, B_SCRIPT_DEL, "Del", (short)(sx+200), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Delete the current Script link");
uiDefBut(block, LABEL, 0, "Selected scriptlink", sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Selected Script link", sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
}
}
@ -276,53 +316,58 @@ static void script_panel_scriptlink(void)
ScriptLink *script=NULL;
Material *ma;
int xco = 10;
block= uiNewBlock(&curarea->uiblocks, "script_panel_scriptlink", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Scriptlinks", "Script", 0, 0, 318, 204)==0) return;
ob= OBACT;
if(ob)
uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_OB, 0, 0, "Displays Object script links");
if(ob && give_current_material(ob, ob->actcol))
uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL, xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_MA, 0, 0, "Displays Material script links ");
uiDefButI(block, TOG|BIT|13, REDRAWBUTSSCRIPT,
"Enable Script Links", xco, 200, 150, 20, &G.f, 0, 0, 0, 0,
"Enable execution of all assigned Script links");
/* for proper alignment: */
uiDefBut(block, LABEL, 0, "", 160, 200,150,20, NULL, 0.0, 0.0, 0, 0, "");
if(G.scene->world)
uiDefIconButS(block, ROW, B_REDR, ICON_WORLD, xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_WO, 0, 0, "Displays World script links");
if (G.f & G_DOSCRIPTLINKS) {
ob= OBACT;
if(ob)
uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_OB, 0, 0, "Displays Object script links");
if(ob && ob->type==OB_CAMERA)
uiDefIconButS(block, ROW, B_REDR, ICON_CAMERA, xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_CA, 0, 0, "Displays Camera script links");
if(ob && give_current_material(ob, ob->actcol))
uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL, xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_MA, 0, 0, "Displays Material script links ");
if(ob && ob->type==OB_LAMP)
uiDefIconButS(block, ROW, B_REDR, ICON_LAMP, xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_LA, 0, 0, "Displays Lamp script links");
if(G.scene->world)
uiDefIconButS(block, ROW, B_REDR, ICON_WORLD, xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_WO, 0, 0, "Displays World script links");
if(ob && ob->type==OB_CAMERA)
uiDefIconButS(block, ROW, B_REDR, ICON_CAMERA, xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_CA, 0, 0, "Displays Camera script links");
if(ob && ob->type==OB_LAMP)
uiDefIconButS(block, ROW, B_REDR, ICON_LAMP, xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_LA, 0, 0, "Displays Lamp script links");
if (ob && G.buts->scriptblock==ID_OB) {
script= &ob->scriptlink;
if (ob && G.buts->scriptblock==ID_OB) {
script= &ob->scriptlink;
} else if (ob && G.buts->scriptblock==ID_MA) {
ma= give_current_material(ob, ob->actcol);
if (ma) script= &ma->scriptlink;
} else if (ob && G.buts->scriptblock==ID_MA) {
ma= give_current_material(ob, ob->actcol);
if (ma) script= &ma->scriptlink;
} else if (ob && G.buts->scriptblock==ID_CA) {
if (ob->type==OB_CAMERA)
script= &((Camera *)ob->data)->scriptlink;
} else if (ob && G.buts->scriptblock==ID_CA) {
if (ob->type==OB_CAMERA)
script= &((Camera *)ob->data)->scriptlink;
} else if (ob && G.buts->scriptblock==ID_LA) {
if (ob->type==OB_LAMP)
script= &((Lamp *)ob->data)->scriptlink;
} else if (ob && G.buts->scriptblock==ID_LA) {
if (ob->type==OB_LAMP)
script= &((Lamp *)ob->data)->scriptlink;
} else if (G.buts->scriptblock==ID_WO) {
if (G.scene->world)
script= &(G.scene->world->scriptlink);
} else if (G.buts->scriptblock==ID_WO) {
if (G.scene->world)
script= &(G.scene->world->scriptlink);
}
if (script) draw_scriptlink(block, script, 10, 140, 0);
draw_scriptlink(block, &G.scene->scriptlink, 10, 80, 1);
}
if (script) draw_scriptlink(block, script, 10, 140, 0);
draw_scriptlink(block, &G.scene->scriptlink, 10, 80, 1);
}

View File

@ -112,11 +112,12 @@ void winqreadscriptspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *
{
unsigned short event = evt->event;
short val = evt->val;
char ascii = evt->ascii;
SpaceScript *sc = curarea->spacedata.first;
Script *script = sc->script;
if (script) {
BPY_spacescript_do_pywin_event(sc, event, val);
BPY_spacescript_do_pywin_event(sc, event, val, ascii);
if (!script->flags) {/* finished with this script, let's free it */
if (script->lastspace != SPACE_SCRIPT)

View File

@ -2030,9 +2030,13 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
}
/* run any view3d draw handler script links */
if (sa->scriptlink.totscript)
BPY_do_spacehandlers(sa, 0, SPACEHANDLER_VIEW3D_DRAW);
/* scene redraw script link */
if(G.scene->scriptlink.totscript && !during_script()) {
/* run scene redraw script links */
if((G.f & G_DOSCRIPTLINKS) && G.scene->scriptlink.totscript &&
!during_script()) {
BPY_do_pyscript((ID *)G.scene, SCRIPT_REDRAW);
}
@ -2084,7 +2088,7 @@ void drawview3d_render(struct View3D *v3d)
clear_all_constraints();
do_all_ipos();
BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
do_all_keys();
do_all_actions(NULL);
do_all_ikas();

View File

@ -55,6 +55,7 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_image_types.h"
#include "DNA_text_types.h" /* for space handlers */
#include "DNA_texture_types.h"
#include "BKE_library.h"
@ -335,6 +336,94 @@ static uiBlock *view3d_view_alignviewmenu(void *arg_unused)
return block;
}
static void do_view3d_view_spacehandlers(void *arg, int event)
{
Text *text = G.main->text.first;
unsigned short menu_evt_num = 0;
if (event > 0) {
while (text) {
if (++menu_evt_num == event) {
if (BPY_has_spacehandler(text, curarea))
BPY_del_spacehandler(text, curarea);
else
BPY_add_spacehandler(text, curarea, SPACE_VIEW3D);
break;
}
text = text->id.next;
}
}
allqueue(REDRAWVIEW3D, 1);
}
static uiBlock *view3d_view_spacehandlers(void *arg_unused)
{
uiBlock *block;
short yco= 0, menuwidth=120;
Text *text = G.main->text.first;
ScrArea *sa = curarea;
unsigned short handlertype;
int icontype, slinks_num = 0;
unsigned short menu_evt_num = 0;
char menustr[64];
static char msg_tog_on[] = "Click to enable";
static char msg_tog_off[]= "Click to disable";
char *tip = NULL;
block= uiNewBlock(&curarea->uiblocks, "view3d_view_spacehandlers", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_view_spacehandlers, NULL);
while (text) {
menu_evt_num++;
handlertype = BPY_is_spacehandler(text, SPACE_VIEW3D);
if (handlertype) {
slinks_num++;
/* mark text as script, so we can remove its link if its header
* becomes corrupt and it's not recognized anymore */
if (!(text->flags & TXT_ISSCRIPT)) text->flags |= TXT_ISSCRIPT;
if (handlertype == SPACEHANDLER_VIEW3D_EVENT)
BLI_strncpy(menustr, "Event: ", 8);
else
BLI_strncpy(menustr, "Draw: ", 8);
BLI_strncpy(menustr+7, text->id.name+2, 22);
if (BPY_has_spacehandler(text, sa)) {
icontype = ICON_CHECKBOX_HLT;
tip = msg_tog_off;
}
else {
icontype = ICON_CHECKBOX_DEHLT;
tip = msg_tog_on;
}
uiDefIconTextBut(block, BUTM, 1, icontype, menustr, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, menu_evt_num, tip);
}
else if (text->flags & TXT_ISSCRIPT) {
/* if bit set, text was a space handler, but its header got corrupted,
* so we need to remove the link here */
BPY_del_spacehandler(text, sa);
text->flags &=~TXT_ISSCRIPT;
}
text = text->id.next;
}
if (slinks_num == 0) {
uiDefIconTextBut(block, BUTM, 1, ICON_SCRIPT, "None Available", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, -1, "None of the texts in the Text Editor is a 3D View space handler");
}
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 50);
return block;
}
static void do_view3d_viewmenu(void *arg, int event)
{
extern int play_anim(int mode);
@ -444,6 +533,9 @@ static uiBlock *view3d_viewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation|Alt A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBlockBut(block, view3d_view_spacehandlers, NULL, ICON_RIGHTARROW_THIN, "Space Handler Scripts", 0, yco-=20, 120, 19, "");
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}

View File

@ -507,7 +507,7 @@ static void do_update_for_newframe(int mute)
/* layers/materials, object ipos are calculted in where_is_object (too) */
do_all_ipos();
BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED);
clear_all_constraints();
do_all_keys();

View File

@ -80,6 +80,7 @@
#include "BIF_toets.h"
#include "BDR_editobject.h"
#include "BPY_extern.h" /* for BPY_do_all_scripts */
#include "BSE_view.h"
#include "BSE_drawview.h"
@ -1143,6 +1144,16 @@ void BIF_renderwin_make_active(void)
/* set up display, render an image or scene */
void BIF_do_render(int anim)
{
int slink_flag = 0;
if (G.f & G_DOSCRIPTLINKS) {
BPY_do_all_scripts(SCRIPT_RENDER);
if (!anim) { /* avoid FRAMECHANGED slink in render callback */
G.f &= ~G_DOSCRIPTLINKS;
slink_flag = 1;
}
}
/* if start render in 3d win, use layer from window (e.g also local view) */
if(curarea && curarea->spacetype==SPACE_VIEW3D) {
int lay= G.scene->lay;
@ -1155,6 +1166,9 @@ void BIF_do_render(int anim)
G.scene->lay= lay;
}
else do_render(NULL, anim, 0);
if (slink_flag) G.f |= G_DOSCRIPTLINKS;
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER);
}
/* set up display, render the current area view in an image */

View File

@ -732,7 +732,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(event==UI_BUT_EVENT) do_butspace(val); // temporal, view3d deserves own queue?
/* we consider manupilator a button, defaulting to leftmouse */
/* we consider manipulator a button, defaulting to leftmouse */
if(event==LEFTMOUSE) if(BIF_do_manipulator(sa)) return;
/* swap mouse buttons based on user preference */
@ -740,7 +740,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (event==LEFTMOUSE) event = RIGHTMOUSE;
else if (event==RIGHTMOUSE) event = LEFTMOUSE;
}
/* run any view3d event handler script links */
if (event && sa->scriptlink.totscript)
if (BPY_do_spacehandlers(sa, event, SPACEHANDLER_VIEW3D_EVENT))
return; /* return if event was processed (swallowed) by handler(s) */
/* TEXTEDITING?? */
if((G.obedit) && G.obedit->type==OB_FONT) {
switch(event) {

View File

@ -460,10 +460,8 @@ void BIF_write_file(char *target)
if (BLI_streq(target, "")) return;
/*Send the OnSave event*/
if (G.f & G_SCENESCRIPT) {
BPY_do_pyscript(&G.scene->id, SCRIPT_ONSAVE);
}
/* send the OnSave event */
if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript(&G.scene->id, SCRIPT_ONSAVE);
for (li= G.main->library.first; li; li= li->id.next) {
if (BLI_streq(li->name, target)) {

View File

@ -188,7 +188,7 @@ static void print_help(void)
printf (" -d\t\tTurn debugging on\n");
printf (" -noaudio\tDisable audio on systems that support audio\n");
printf (" -h\t\tPrint this help text\n");
printf (" -y\t\tDisable OnLoad scene scripts, use -Y to find out why its -y\n");
printf (" -y\t\tDisable script links, use -Y to find out why its -y\n");
printf (" -P <filename>\tRun the given Python script (filename or Blender Text)\n");
#ifdef WIN32
printf (" -R\t\tRegister .blend extension\n");
@ -276,7 +276,7 @@ int main(int argc, char **argv)
/* first test for background */
G.f |= G_SCENESCRIPT; /* scenescript always set! */
G.f |= G_DOSCRIPTLINKS; /* script links enabled by default */
for(a=1; a<argc; a++) {
@ -306,11 +306,11 @@ int main(int argc, char **argv)
break;
case 'y':
G.f &= ~G_SCENESCRIPT;
G.f &= ~G_DOSCRIPTLINKS;
break;
case 'Y':
printf ("-y was used to disable scene scripts because,\n");
printf ("-y was used to disable script links because,\n");
printf ("\t-p being taken, Ton was of the opinion that Y\n");
printf ("\tlooked like a split (disabled) snake, and also\n");
printf ("\twas similar to a python's tongue (unproven).\n\n");