BPython:
authorWillian Padovani Germano <wpgermano@gmail.com>
Sun, 8 May 2005 21:20:34 +0000 (21:20 +0000)
committerWillian Padovani Germano <wpgermano@gmail.com>
Sun, 8 May 2005 21:20:34 +0000 (21:20 +0000)
- 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.

36 files changed:
source/blender/blenkernel/BKE_bad_level_calls.h
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/screen.c
source/blender/blenkernel/intern/text.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_screen_types.h
source/blender/makesdna/DNA_scriptlink_types.h
source/blender/makesdna/DNA_text_types.h
source/blender/python/BPY_extern.h
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Draw.c
source/blender/python/api2_2x/Draw.h
source/blender/python/api2_2x/Window.c
source/blender/python/api2_2x/doc/API_intro.py
source/blender/python/api2_2x/doc/API_related.py
source/blender/python/api2_2x/doc/Blender.py
source/blender/python/api2_2x/doc/Draw.py
source/blender/python/api2_2x/doc/Theme.py
source/blender/python/api2_2x/gen_utils.c
source/blender/python/api2_2x/windowTheme.c
source/blender/renderconverter/intern/convertBlenderScene.c
source/blender/src/buttons_script.c
source/blender/src/drawscript.c
source/blender/src/drawview.c
source/blender/src/header_view3d.c
source/blender/src/headerbuttons.c
source/blender/src/renderwin.c
source/blender/src/space.c
source/blender/src/usiblender.c
source/creator/creator.c

index c500af345d9186ed22e4b70660ca38dac255c006..561634335c0ed293bf67bb4d8228801a9152c562 100644 (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;
index b0904385a332da33e8240aa24f77d716b85e4b86..ae9929b9a2a17f3f845b05c37a2738631b43bf3e 100644 (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
index 894ac8fc6fb01a02dbc143fb579581063b531920..1ced9b6430a6493193c0da5d309676c5665a4f5c 100644 (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; */
index 3d91636cda51310a2f4dca006c0df5863a424546..cc47169a7a2faf47e444206f6cb8245c18416543 100644 (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);
        }
index 69f21018562bcdb82d2f1852984c27c954493cf6..21544b73f7f63577fadc5b15d76faf8c904c44c1 100644 (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 */
index 857fbc7586a8cbbfdd15518e0b373c1ab0f8b34e..671b2887ab5fc46cddf1a0ae1901a4c7f77c443e 100644 (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);
index 06b7d1713089499c82307a9a4afc6c0874783578..59bfa17472ea72cd3afee9367dba1ed5a23b2fd4 100644 (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);
index d46742a6328c617bd03ee84b5d2f4361775606d9..2455ebb98d5b96d10f161fb821e52124653ae21a 100644 (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
 
index bea8e21e146c4df69c8065b8e3fd0ed7a35f611d..d9f6251722c7027da3153553408a6001fd3e8067 100644 (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) {
index 504e96ac78babe39cb66e49d1099f0bd02a3f8cc..8ade6df7b4cb49f2f09129a9bef0193548fae638 100644 (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) {
index 739bf7870ff39647e5d98bbbf2e8ae21824ea026..cd90c24b882dc5161c702e67275e9c3798607593 100644 (file)
@@ -108,6 +108,8 @@ typedef struct ScrArea {
        short headbutlen, headbutofs;
        short cursor, flag;
 
+       ScriptLink scriptlink;
+
        ListBase spacedata;
        ListBase uiblocks;
        ListBase panels;
index 4983fa1d9ddef1dfdf31af2b7b0956c1ab73ee05..8a08d3f12c17f78430252f9ab4033e681ff6eb9b 100644 (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
-
index 391142db30243a413b8f772cf16abbcea6f5fe80..ea3ce2379090ae4787e317b6e9e020abab1caf02 100644 (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
index dbf464de019ba462e4d4f94b44d91dadd37d4ef6..97e8819c77af968f8e9cd0e9cbb2a7752ef9672e 100644 (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
  *
 
 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" */
index f0741ace86c25643ff00740a86451ed909fa357e..3306f68ccf825b67cdd5ef3545554be844d3c761 100644 (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:
index e2f68a9a6f98572cd5ce1eab3196c38f2b89f1e7..705b31e6ebc93cd4892657ec30c47835d914e3d9 100644 (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
index 4426c76218e0311d008451c1b2fe1f7810db2536..d122ed93ac5d8745edcac35549cfb2f33f63f1bc 100644 (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;
index 9f1d7eb19fe78dc330fe4dd976e90d4f7a44916d..27a80c2333460ee770e39d6b6c2c1257e9bf920c 100644 (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 );
index 64ce039d063d60231b77c4e480a1885f5626c836..3858647e179a91407ec9b2bb5c9da0f1b20a2dbb 100644 (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 );
        }
index 9d54eac9d8a9dfaca04ca56ef917cbf23d553326..91c00ce43b4e7ff79ab8b8f538bdc2c1958aec37 100644 (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:
 =============
index 8326ee72279bba3564c228206bb27e10ae4bc39d..e9d071ffb018f2a0ffc395fe9bdf382bbbfd5f6e 100644 (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>}
+ ===============================
 """
index b68d9a40d605728060001c181d9b6a4385ef3d77..f4e02a354595a16c8e11c5a0f597f960efce89ba 100644 (file)
 """
 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):
index a3c42c7cdc21d8a483d2baaca9ffe5ee31922ebe..fab404152c1493ae52b5c648e69fafa7021b68ed 100644 (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):
index facfee068c232c2b74d71e1db14f103c99a3780b..e2e9c74c8ed6ddbf4e0761b26b984f5a32adf05a 100644 (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].
     """
 
index e909de1184c32925bb2aa6fc2f812f60ab79c567..ba6878b0a5db51999c7e65172733e04e66afc6c7 100644 (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" ) )
index 69ba451f2f57a6aebfc9e41bf7b295b09b7e4b7f..5f2e06024dac1fc17c5a0bad7825c7b9b3b0394a 100644 (file)
 
 #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 ) {
index 744b568aaac31efedd3f97f4b9c1caf8abffdf54..29782be905c24acdd285676521f3e16b5b8cd70f 100644 (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);
index 3088486322f771beeca3bcadad5cb54a776fa7f0..54cbe328a4e8826c58ed7c9fe3a99dd341954050 100644 (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"
 
 /* ************************ 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.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 && 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(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.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,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_CA, 0, 0, "Displays Camera 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,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_LA, 0, 0, "Displays Lamp 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 (G.buts->scriptblock==ID_WO) {
-               if (G.scene->world)
-                       script= &(G.scene->world->scriptlink);
-       }
-
-       if (script) draw_scriptlink(block, script, 10, 140, 0);                 
+               } else if (ob && G.buts->scriptblock==ID_LA) {
+                       if (ob->type==OB_LAMP)
+                               script= &((Lamp *)ob->data)->scriptlink;
 
-       draw_scriptlink(block, &G.scene->scriptlink, 10, 80, 1);
+               } 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);
+       }
 }
 
 
index 2c52c20ee959b6ee0156fb67db066c18aeceac9e..c4ec1a4db3a4eed3c36bf2023fbaa38154317874 100644 (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)
index dadb1c2acf5d3b6399daf243bf731897790f806a..9b96db9309b16e54acf9cf4a816d834d8e6dcc32 100644 (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();
index 82c842ec737206f4b9172251fe79c276d71fc61f..39a5f09eaffef3632e37acec8235639fdab8c145 100644 (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);
        }
index c800f9c24ef8e9242505453579675853cb04a47f..b66d7991549bda19c0ba86cc19dadd2ad145d385 100644 (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();
 
index ffa917530b0f898875fc36778eda15ac1956e8d7..6d5ab76657f21c53d2c12b16fad470199e0d8773 100644 (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 */
index 30dc39c6a2e9d5478d0fb7a9b747e798bfbf4cbc..f613cb6a055839263d5e366b0dbea2b3fffcf154 100644 (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) {
index 241dc8cd45f70e778b4b5e6eb4dcee396bb5ae04..895bd90f84053d2a1ce46919cdd617d0a5d1c54e 100644 (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)) {
index 62d638d167b4073990a5db85309ff0c52a58d7fa..1c8cab55cb53a439117c0a9472fe75726210687f 100644 (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");