2.5 Branch
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 11 Jun 2008 10:10:31 +0000 (10:10 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 11 Jun 2008 10:10:31 +0000 (10:10 +0000)
==========

* Changed wmOperatorType, removing init/exit callbacks and adding cancel
  callback, removed default storage in favor of properties. Defined return
  values for exec/invoke/modal/cancel.
* Don't allocate operator on the stack, and removed operator copy for
  handlers. Now it frees based on return values from callbacks, and just
  keeps a wmOperator on the heap. Also it now registers after the operator
  is fully finished, to get the correct final properties.
* Changed OP_get_* functions to return 1 if the property is found and 0
  otherwise, gives more readable code in my opinion. Added OP_verify_*
  functions to quickly check if the property is available and set if it's
  not, that's common for exec/invoke.
* Removed WM_operatortypelist_append in favor of WM_operatortype_append
  which takes a function pointer instead of a list, avoids macro's and
  duplicating code.
* Fix a crash where the handler would still be used while it was freed by
  the operator.

* Spacetypes now have operatortypes() and keymap() callbacks to abstract
  them a bit more.
* Renamed C->curarea to C->area for consistency. Removed View3D/View2D/
  SpaceIpo from bContext, seems bad to keep these.
* Set context variables like window/screen/area/region to NULL again when
  leaving that context, instead of leaving the pointers there.

* Added if(G.f & G_DEBUG) for many of the prints, makes output a bit
  cleaner and easier to debug.
* Fixed priority of the editors/interface module in scons, would otherwise
  give link errors.

* Added start of generic view2d api.
* Added space_time with some basic drawing and a single operator to change
  the frame.

31 files changed:
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/BKE_screen.h
source/blender/blenkernel/intern/screen.c
source/blender/editors/Makefile
source/blender/editors/SConscript
source/blender/editors/include/BIF_view2d.h [new file with mode: 0644]
source/blender/editors/include/ED_area.h
source/blender/editors/include/ED_screen.h
source/blender/editors/interface/SConscript
source/blender/editors/interface/view2d.c [new file with mode: 0644]
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/screen/spacetypes.c
source/blender/editors/space_time/Makefile [new file with mode: 0644]
source/blender/editors/space_time/SConscript [new file with mode: 0644]
source/blender/editors/space_time/space_time.c [new file with mode: 0644]
source/blender/editors/space_time/time_intern.h [new file with mode: 0644]
source/blender/editors/space_time/time_ops.c [new file with mode: 0644]
source/blender/editors/space_view3d/space_view3d.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_subwindow.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm.h
source/blender/windowmanager/wm_subwindow.h

index a78625fe662006233d9187cb4f2b9bb01c9afc3f..f2929bd8d61a0f8be3db96f7aa8ed677df1c67e0 100644 (file)
@@ -69,20 +69,9 @@ typedef struct bContext {
        struct wmWindowManager *wm;
        struct wmWindow *window;
        struct bScreen *screen;
-       struct ScrArea *curarea;
+       struct ScrArea *area;
        struct ARegion *region;
        
-       /* fast spacedata lookups */
-       struct View3D *vd;
-       struct View2D *v2d;
-       struct SpaceIpo *sipo;
-       struct SpaceButs *buts;
-       struct SpaceImage *sima;
-       struct SpaceOops *soops;
-       struct SpaceSound *ssound;
-       struct SpaceAction *saction;
-       struct SpaceNla *snla;
-       
        /* data context */
        struct Scene *scene;
        struct Object *obact;
@@ -90,11 +79,10 @@ typedef struct bContext {
        
        /* edit data context */
        struct EditMesh *editMesh;
-       struct  ListBase edbo;                  /* Armature Editmode bones */
+       struct ListBase edbo;                   /* Armature Editmode bones */
        
 } bContext;
 
-
 typedef struct Global {
 
        /* active pointers */
index 4c968eb0450809908342d6f0dd371d4f201f4c32..14090719de62f6f7c25e26c360f6400091f19dd2 100644 (file)
@@ -8,11 +8,7 @@
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
-<<<<<<< .mine
- * of the License, or (at your option) any later version.
-=======
  * of the License, or (at your option) any later version. 
->>>>>>> .r13159
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -40,6 +36,8 @@ struct ScrArea;
 struct bScreen;
 struct ARegion;
 struct wmNotifier;
+struct wmWindowManager;
+struct ListBase;
 
 /* spacetype has everything stored to get an editor working, it gets initialized via 
 spacetypes_init() in editors/area/spacetypes.c   */
@@ -52,14 +50,25 @@ typedef struct SpaceType {
        int                             spaceid;                                        /* unique space identifier */
        int                             iconid;                                         /* icon lookup for menus */
        
-       struct SpaceLink        *(*new)(void);                                                  /* calls init too */
-       void            (*free)(struct SpaceLink *sl);                                  /* not free sl itself */
+       /* calls init too */
+       struct SpaceLink        *(*new)(void);
+       /* not free spacelink itself */
+       void            (*free)(struct SpaceLink *);
        
-       void            (*init)(struct ScrArea *);                                              /* init is to cope with internal contextual changes, adds handlers, sets screarea regions */
-       void            (*refresh)(struct bContext *, struct ScrArea *);        /* refresh is for external bContext changes */
-       
-       struct SpaceLink        *(*duplicate)(struct SpaceLink *sl);            /* after a spacedata copy, an init should result in exact same situation */
+       /* init is to cope with internal contextual changes, adds handlers,
+        * sets screarea regions */
+       void            (*init)(struct wmWindowManager *, struct ScrArea *);
+       /* refresh is for external bContext changes */
+       void            (*refresh)(struct bContext *, struct ScrArea *);
        
+       /* after a spacedata copy, an init should result in exact same situation */
+       struct SpaceLink        *(*duplicate)(struct SpaceLink *);
+
+       /* register operator types on startup */
+       void            (*operatortypes)(void);
+       /* add default items to keymap */
+       void            (*keymap)(struct wmWindowManager *);
+
        /* read and write... */
        
 } SpaceType;
@@ -80,6 +89,7 @@ void BKE_screen_area_free(struct ScrArea *sa);
 void free_screen(struct bScreen *sc); 
 
 struct SpaceType *BKE_spacetype_from_id(int spaceid);
+const struct ListBase *BKE_spacetypes_list(void);
 void BKE_spacetype_register(struct SpaceType *st);
 void BKE_spacedata_freelist(ListBase *lb);
 void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2);
index c5b30b26f7436250c59fab8f8739f2a407f2b106..b259138ee42c8c57940f94e189084e3c85714946 100644 (file)
@@ -51,6 +51,11 @@ SpaceType *BKE_spacetype_from_id(int spaceid)
        return NULL;
 }
 
+const ListBase *BKE_spacetypes_list()
+{
+       return &spacetypes;
+}
+
 void BKE_spacetype_register(SpaceType *st)
 {
        BLI_addtail(&spacetypes, st);
index dcd183688bf4432cb158f55d4641d90c8a5ba1c9..3ea82ebe3b41b7365ee1444b4db46e66d5abf958 100644 (file)
@@ -29,6 +29,6 @@
 # Bounces make to subdirectories.
 
 SOURCEDIR = source/blender/editors
-DIRS = datafiles screen space_view3d interface
+DIRS = datafiles screen space_time space_view3d interface
 
 include nan_subdirs.mk
index 46c63c4900b84a855af657720fe0afed77cd0a0e..113cc7a2d7b9f25844e4343bace4e334ec128eac 100644 (file)
@@ -6,6 +6,7 @@ SConscript(['datafiles/SConscript',
                        'interface/SConscript',
                        'mesh/SConscript',
                        'object/SConscript',
+                       'space_time/SConscript',
                        'space_view3d/SConscript',
                        'transform/SConscript',
                        'screen/SConscript'])
diff --git a/source/blender/editors/include/BIF_view2d.h b/source/blender/editors/include/BIF_view2d.h
new file mode 100644 (file)
index 0000000..191826b
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_VIEW2D_H
+#define BIF_VIEW2D_H
+
+/* start of a generic 2d view with should allow drawing grids,
+ * panning, zooming, scrolling, .. */
+
+#define V2D_UNIT_SECONDS       0
+#define V2D_UNIT_FRAMES                1
+
+#define V2D_GRID_CLAMP         0
+#define V2D_GRID_NOCLAMP       1
+
+#define V2D_IS_CLIPPED 12000
+
+#define V2D_HORIZONTAL_LINES   1
+#define V2D_VERTICAL_LINES             2
+#define V2D_HORIZONTAL_AXIS            4
+#define V2D_VERTICAL_AXIS              8
+
+struct View2D;
+struct bContext;
+
+void BIF_view2d_ortho(const struct bContext *C, struct View2D *v2d);
+
+/* grid drawing */
+void BIF_view2d_calc_grid(const struct bContext *C, struct View2D *v2d, int unit, int type, int winx, int winy);
+void BIF_view2d_draw_grid(const struct bContext *C, struct View2D *v2d, int flag);
+
+/* coordinate conversion */
+void BIF_view2d_region_to_view(struct View2D *v2d, short x, short y, float *viewx, float *viewy);
+void BIF_view2d_view_to_region(struct View2D *v2d, float x, float y, short *regionx, short *regiony);
+void BIF_view2d_to_region_no_clip(struct View2D *v2d, float x, float y, short *regionx, short *region_y);
+
+#endif /* BIF_VIEW2D_H */
+
index 2cb5b42e2cb6c67459e8bc9b1a15fb6bfd1269a9..6666907c63da740350d37dfa810c02a2f59f9c29 100644 (file)
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+
 #ifndef ED_AREA_H
 #define ED_AREA_H
 
 /* the pluginnable API for export to editors */
 
-
 /* calls for registering default spaces */
+void ED_spacetype_time(void);
 void ED_spacetype_view3d(void);
 
-/* calls for registering operator types */
-void ED_operatortypes_screen(void);
-
-
 #endif /* ED_AREA_H */
 
-
-
index f9450e3717b4efd4017103de4b3c04545e667e5b..0adac2c9657622785c7831ea02bf6d9b2adc401c 100644 (file)
@@ -44,6 +44,7 @@ void  ED_region_do_refresh(struct bContext *C, ARegion *ar);
 
 /* spaces */
 void   ED_spacetypes_init(void);
+void   ED_spacetypes_keymap(struct wmWindowManager *wm);
 
 /* areas */
 void   ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa);
@@ -57,7 +58,8 @@ void  ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, bScreen *sc);
 void   ED_screen_set_subwinactive(struct wmWindow *win);
 
-void   ed_screen_keymap(struct wmWindowManager *wm);
+void   ED_operatortypes_screen(void);
+void   ED_keymap_screen(struct wmWindowManager *wm);
 
 /* operators; context poll callbacks */
 int            ED_operator_screenactive(bContext *C);
index 5743674bfb27c9225cea6d959c43aa21123432b6..6602bba014fb54d4a575f7db0d4a37af5c0b7768 100644 (file)
@@ -4,6 +4,6 @@ Import ('env')
 sources = env.Glob('*.c')
 
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
-incs += ' #/intern/guardedalloc'
+incs += ' ../../windowmanager #/intern/guardedalloc'
 
-env.BlenderLib ( 'bf_editors_interface', sources, Split(incs), [], libtype=['core','intern'], priority=[15, 30] )
+env.BlenderLib ( 'bf_editors_interface', sources, Split(incs), [], libtype=['core','intern'], priority=[40, 45] )
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
new file mode 100644 (file)
index 0000000..139ba03
--- /dev/null
@@ -0,0 +1,252 @@
+
+#include <math.h>
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view2d_types.h"
+
+#include "BKE_global.h"
+
+#include "WM_api.h"
+
+#include "BIF_gl.h"
+#include "BIF_resources.h"
+#include "BIF_view2d.h"
+
+/* minimum pixels per gridstep */
+#define IPOSTEP 35
+
+static float ipogrid_dx, ipogrid_dy, ipogrid_startx, ipogrid_starty;
+static int ipomachtx, ipomachty;
+
+static int vertymin, vertymax, horxmin, horxmax;    /* globals to test LEFTMOUSE for scrollbar */
+
+void BIF_view2d_ortho(const bContext *C, View2D *v2d)
+{
+       wmOrtho2(C->window, v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);
+}
+
+static void step_to_grid(float *step, int *macht, int unit)
+{
+       float loga, rem;
+       
+       /* try to write step as a power of 10 */
+       
+       loga= log10(*step);
+       *macht= (int)(loga);
+
+       rem= loga- *macht;
+       rem= pow(10.0, rem);
+       
+       if(loga<0.0) {
+               if(rem < 0.2) rem= 0.2;
+               else if(rem < 0.5) rem= 0.5;
+               else rem= 1.0;
+
+               *step= rem*pow(10.0, (float)*macht);
+
+               if(unit == V2D_UNIT_FRAMES) {
+                       rem = 1.0;
+                       *step = 1.0;
+               }
+
+               if(rem==1.0) (*macht)++;        // prevents printing 1.0 2.0 3.0 etc
+       }
+       else {
+               if(rem < 2.0) rem= 2.0;
+               else if(rem < 5.0) rem= 5.0;
+               else rem= 10.0;
+               
+               *step= rem*pow(10.0, (float)*macht);
+               
+               (*macht)++;
+               if(rem==10.0) (*macht)++;       // prevents printing 1.0 2.0 3.0 etc
+       }
+}
+
+void BIF_view2d_calc_grid(const bContext *C, View2D *v2d, int unit, int clamp, int winx, int winy)
+{
+       float space, pixels, seconddiv;
+       int secondgrid;
+
+       /* rule: gridstep is minimal IPOSTEP pixels */
+       /* how large is IPOSTEP pixels? */
+       
+       if(unit == V2D_UNIT_FRAMES) {
+               secondgrid= 0;
+               seconddiv= 0.01f * FPS;
+       }
+       else {
+               secondgrid= 1;
+               seconddiv= 1.0f;
+       }
+
+       space= v2d->cur.xmax - v2d->cur.xmin;
+       pixels= v2d->mask.xmax - v2d->mask.xmin;
+       
+       ipogrid_dx= IPOSTEP*space/(seconddiv*pixels);
+       step_to_grid(&ipogrid_dx, &ipomachtx, unit);
+       ipogrid_dx*= seconddiv;
+       
+       if(clamp == V2D_GRID_CLAMP) {
+               if(ipogrid_dx < 0.1) ipogrid_dx= 0.1;
+               ipomachtx-= 2;
+               if(ipomachtx<-2) ipomachtx= -2;
+       }
+       
+       space= (v2d->cur.ymax - v2d->cur.ymin);
+       pixels= winy;
+       ipogrid_dy= IPOSTEP*space/pixels;
+       step_to_grid(&ipogrid_dy, &ipomachty, unit);
+       
+       if(clamp == V2D_GRID_CLAMP) {
+               if(ipogrid_dy < 1.0) ipogrid_dy= 1.0;
+               if(ipomachty<1) ipomachty= 1;
+       }
+       
+       ipogrid_startx= seconddiv*(v2d->cur.xmin/seconddiv - fmod(v2d->cur.xmin/seconddiv, ipogrid_dx/seconddiv));
+       if(v2d->cur.xmin<0.0) ipogrid_startx-= ipogrid_dx;
+       
+       ipogrid_starty= (v2d->cur.ymin-fmod(v2d->cur.ymin, ipogrid_dy));
+       if(v2d->cur.ymin<0.0) ipogrid_starty-= ipogrid_dy;
+}
+
+void BIF_view2d_draw_grid(const bContext *C, View2D *v2d, int flag)
+{
+       float vec1[2], vec2[2];
+       int a, step;
+       
+       if(flag & V2D_VERTICAL_LINES) {
+               /* vertical lines */
+               vec1[0]= vec2[0]= ipogrid_startx;
+               vec1[1]= ipogrid_starty;
+               vec2[1]= v2d->cur.ymax;
+               
+               step= (v2d->mask.xmax - v2d->mask.xmin+1)/IPOSTEP;
+               
+               BIF_ThemeColor(TH_GRID);
+               
+               for(a=0; a<step; a++) {
+                       glBegin(GL_LINE_STRIP);
+                       glVertex2fv(vec1); glVertex2fv(vec2);
+                       glEnd();
+                       vec2[0]= vec1[0]+= ipogrid_dx;
+               }
+               
+               vec2[0]= vec1[0]-= 0.5*ipogrid_dx;
+               
+               BIF_ThemeColorShade(TH_GRID, 16);
+               
+               step++;
+               for(a=0; a<=step; a++) {
+                       glBegin(GL_LINE_STRIP);
+                       glVertex2fv(vec1); glVertex2fv(vec2);
+                       glEnd();
+                       vec2[0]= vec1[0]-= ipogrid_dx;
+               }
+       }
+       
+       if(flag & V2D_HORIZONTAL_LINES) {
+               /* horizontal lines */
+               vec1[0]= ipogrid_startx;
+               vec1[1]= vec2[1]= ipogrid_starty;
+               vec2[0]= v2d->cur.xmax;
+               
+               step= (C->area->winy+1)/IPOSTEP;
+               
+               BIF_ThemeColor(TH_GRID);
+               for(a=0; a<=step; a++) {
+                       glBegin(GL_LINE_STRIP);
+                       glVertex2fv(vec1); glVertex2fv(vec2);
+                       glEnd();
+                       vec2[1]= vec1[1]+= ipogrid_dy;
+               }
+               vec2[1]= vec1[1]-= 0.5*ipogrid_dy;
+               step++;
+       }
+       
+       BIF_ThemeColorShade(TH_GRID, -50);
+       
+       if(flag & V2D_HORIZONTAL_AXIS) {
+               /* horizontal axis */
+               vec1[0]= v2d->cur.xmin;
+               vec2[0]= v2d->cur.xmax;
+               vec1[1]= vec2[1]= 0.0;
+               glBegin(GL_LINE_STRIP);
+               
+               glVertex2fv(vec1);
+               glVertex2fv(vec2);
+               
+               glEnd();
+       }
+       
+       if(flag & V2D_VERTICAL_AXIS) {
+               /* vertical axis */
+               vec1[1]= v2d->cur.ymin;
+               vec2[1]= v2d->cur.ymax;
+               vec1[0]= vec2[0]= 0.0;
+               glBegin(GL_LINE_STRIP);
+               glVertex2fv(vec1); glVertex2fv(vec2);
+               glEnd();
+       }
+}
+
+void BIF_view2d_region_to_view(View2D *v2d, short x, short y, float *viewx, float *viewy)
+{
+       float div, ofs;
+
+       if(viewx) {
+               div= v2d->mask.xmax-v2d->mask.xmin;
+               ofs= v2d->mask.xmin;
+
+               *viewx= v2d->cur.xmin+ (v2d->cur.xmax-v2d->cur.xmin)*(x-ofs)/div;
+       }
+
+       if(viewy) {
+               div= v2d->mask.ymax-v2d->mask.ymin;
+               ofs= v2d->mask.ymin;
+
+               *viewy= v2d->cur.ymin+ (v2d->cur.ymax-v2d->cur.ymin)*(y-ofs)/div;
+       }
+}
+
+void BIF_view2d_view_to_region(View2D *v2d, float x, float y, short *regionx, short *regiony)
+{
+       *regionx= V2D_IS_CLIPPED;
+       *regiony= V2D_IS_CLIPPED;
+
+       x= (x - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin);
+       y= (x - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin);
+
+       if(x>=0.0 && x<=1.0) {
+               if(y>=0.0 && y<=1.0) {
+                       if(regionx)
+                               *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin);
+                       if(regiony)
+                               *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin);
+               }
+       }
+}
+
+void BIF_view2d_to_region_no_clip(View2D *v2d, float x, float y, short *regionx, short *regiony)
+{
+       x= (x - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin);
+       y= (x - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin);
+
+       x= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin);
+       y= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin);
+
+       if(regionx) {
+               if(x<-32760) *regionx= -32760;
+               else if(x>32760) *regionx= 32760;
+               else *regionx= x;
+       }
+
+       if(regiony) {
+               if(y<-32760) *regiony= -32760;
+               else if(y>32760) *regiony= 32760;
+               else *regiony= y;
+       }
+}
+
index f67769fdd3d3bcc545572ad3360659e27cfb2411..fb72f47e7bf044f4c8fbc921612743918dfc4056 100644 (file)
@@ -264,7 +264,6 @@ static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
 void area_azone_initialize(ScrArea *sa) {
        AZone *az;
        if(sa->actionzones.first==NULL) {
-               printf("area_azone_initialize\n");
                /* set action zones - should these actually be ARegions? With these we can easier check area hotzones */
                az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
                BLI_addtail(&(sa->actionzones), az);
@@ -367,7 +366,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
        
        /* regiontype callback, it should create/verify the amount of subregions with minsizes etc */
        if(sa->type->init)
-               sa->type->init(sa);
+               sa->type->init(wm, sa);
        
        /* region rect sizes */
        rect= sa->totrct;
index c20c5944665310f780b81d42a782d7f28ed4d052..b1ec306ba6994b59f53c50b33422d4c548146415 100644 (file)
@@ -1018,13 +1018,13 @@ void ED_screen_draw(wmWindow *win)
                scrarea_draw_shape_dark(sa2, dir);
                scrarea_draw_shape_light(sa1, dira);
        }
-       printf("draw screen\n");
+       if(G.f & G_DEBUG) printf("draw screen\n");
        win->screen->do_draw= 0;
 }
 
 void ED_screen_gesture(wmWindow *win)
 {
-       printf("gesture draw screen\n");
+       if(G.f & G_DEBUG) printf("gesture draw screen\n");
 
        if(win->gesture.first) {
                ed_gesture_update(win);
@@ -1052,7 +1052,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
                ED_area_initialize(wm, win, sa);
        }
        
-       printf("set screen\n");
+       if(G.f & G_DEBUG) printf("set screen\n");
        win->screen->do_refresh= 0;
 
 }
@@ -1126,108 +1126,125 @@ int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
                else WM_set_cursor(C, CURSOR_STD);
        }
        
-       return 1;
+       return OPERATOR_PASS_THROUGH;
 }
 
-/* ************** move area edge operator ********************************************** */
+/* ************** move area edge operator *********************************** */
 
 /* operator state vars used:  
-           op->veci   mouse coord near edge
-           op->delta  movement of edge
+           x, y                        mouse coord near edge
+           delta            movement of edge
+
+   internal:
+
+   init()   set default property values, find edge based on mouse coords, test
+            if the edge can be moved, select edges, calculate min and max movement
+
+   apply()     apply delta on selection
+
+   exit()      cleanup, send notifier
 
    callbacks:
 
-   init()   find edge based on op->veci, test if the edge can be moved, select edges,
-            clear delta, calculate min and max movement
+   exec()   execute without any user interaction, based on properties
+            call init(), apply(), exit()
 
-   exec()      apply op->delta on selection
-   
-   invoke() handler gets called on a mouse click near edge
-            call init()
-            add handler
+   invoke() gets called on mouse click near edge
+            call init(), add handler
 
-   modal()     accept modal events while doing it
-                       call exec() with delta motion
+   modal()  accept modal events while doing it
+                       call apply() with delta motion
             call exit() and remove handler
 
-   exit()      cleanup, send notifier
+   cancel() cancel moving
 
 */
 
+typedef struct sAreaMoveData {
+       int bigger, smaller, origval;
+       char dir;
+} sAreaMoveData;
+
 /* validate selection inside screen, set variables OK */
 /* return 0: init failed */
 static int move_areas_init (bContext *C, wmOperator *op)
 {
-       ScrEdge *actedge= screen_find_active_scredge(C->screen, op->veci.x, op->veci.y);
+       ScrEdge *actedge;
        ScrArea *sa;
-       int bigger, smaller, dir, origval;
-       
+       sAreaMoveData *md;
+       int x, y;
+
+       /* required properties */
+       if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
+               return 0;
+
+       /* default properties */
+       OP_verify_int(op, "delta", 0, NULL);
+
+       /* setup */
+       actedge= screen_find_active_scredge(C->screen, x, y);
        if(actedge==NULL) return 0;
-       
-       dir= scredge_is_horizontal(actedge)?'h':'v';
-       if(dir=='h') origval= actedge->v1->vec.y;
-       else origval= actedge->v1->vec.x;
+
+       md= MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
+       op->customdata= md;
+
+       md->dir= scredge_is_horizontal(actedge)?'h':'v';
+       if(md->dir=='h') md->origval= actedge->v1->vec.y;
+       else md->origval= actedge->v1->vec.x;
        
        select_connected_scredge(C->screen, actedge);
 
        /* now all verices with 'flag==1' are the ones that can be moved. */
        /* we check all areas and test for free space with MINSIZE */
-       bigger= smaller= 10000;
+       md->bigger= md->smaller= 10000;
        for(sa= C->screen->areabase.first; sa; sa= sa->next) {
-               if(dir=='h') {  /* if top or down edge selected, test height */
+               if(md->dir=='h') {      /* if top or down edge selected, test height */
                   
                   if(sa->v1->flag && sa->v4->flag) {
                           int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
-                          bigger= MIN2(bigger, y1);
+                          md->bigger= MIN2(md->bigger, y1);
                   }
                   else if(sa->v2->flag && sa->v3->flag) {
                           int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
-                          smaller= MIN2(smaller, y1);
+                          md->smaller= MIN2(md->smaller, y1);
                   }
                }
                else {  /* if left or right edge selected, test width */
                        if(sa->v1->flag && sa->v2->flag) {
                                int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
-                               bigger= MIN2(bigger, x1);
+                               md->bigger= MIN2(md->bigger, x1);
                        }
                        else if(sa->v3->flag && sa->v4->flag) {
                                int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
-                               smaller= MIN2(smaller, x1);
+                               md->smaller= MIN2(md->smaller, x1);
                        }
                }
        }
 
-       OP_set_int(op, "bigger", bigger);
-       OP_set_int(op, "smaller", smaller);
-       OP_set_int(op, "dir", dir);
-       OP_set_int(op, "origval", origval);
-
        return 1;
 }
 
 /* moves selected screen edge amount of delta */
 /* needs init call to work */
-static int move_areas_exec(bContext *C, wmOperator *op)
+static void move_areas_apply(bContext *C, wmOperator *op)
 {
        ScrVert *v1;
-       int bigger, smaller, dir, origval;
+       int delta;
+       sAreaMoveData *md= op->customdata;
 
-       OP_get_int(op, "bigger", &bigger);
-       OP_get_int(op, "smaller", &smaller);
-       OP_get_int(op, "dir", &dir);
-       OP_get_int(op, "origval", &origval);
+       OP_get_int(op, "delta", &delta);
        
-       op->delta= CLAMPIS(op->delta, -smaller, bigger);
+       delta= CLAMPIS(delta, -md->smaller, md->bigger);
        
        for (v1= C->screen->vertbase.first; v1; v1= v1->next) {
                if (v1->flag) {
                        /* that way a nice AREAGRID  */
-                       if((dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) {
-                               v1->vec.x= origval + op->delta;
-                               if(op->delta != bigger && op->delta != -smaller) v1->vec.x-= (v1->vec.x % AREAGRID);
+                       if((md->dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) {
+                               v1->vec.x= md->origval + delta;
+                               if(delta != md->bigger && delta != -md->smaller) v1->vec.x-= (v1->vec.x % AREAGRID);
                        }
-                       if((dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) {
-                               v1->vec.y= origval + op->delta;
+                       if((md->dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) {
+                               v1->vec.y= md->origval + delta;
 
                                v1->vec.y+= AREAGRID-1;
                                v1->vec.y-= (v1->vec.y % AREAGRID);
@@ -1238,93 +1255,102 @@ static int move_areas_exec(bContext *C, wmOperator *op)
                        }
                }
        }
-       return 1;
+
+       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
 }
 
-static int move_areas_exit(bContext *C, wmOperator *op)
+static void move_areas_exit(bContext *C, wmOperator *op)
 {
-       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+       if(op->customdata)
+               MEM_freeN(op->customdata);
 
        /* this makes sure aligned edges will result in aligned grabbing */
        removedouble_scrverts(C->screen);
        removedouble_scredges(C->screen);
-
-       OP_free_property(op);   
-       return 1;
 }
 
-/* interaction callback */
-/* return 0 = stop evaluating for next handlers */
-static int move_areas_invoke (bContext *C, wmOperator *op, wmEvent *event)
+static int move_areas_exec(bContext *C, wmOperator *op)
 {
+       if(!move_areas_init(C, op))
+               return OPERATOR_CANCELLED;
        
-       /* operator arguments and storage */
-       op->properties = NULL;
-       op->delta= 0;
-       op->veci.x= event->x;
-       op->veci.y= event->y;
+       move_areas_apply(C, op);
+       move_areas_exit(C, op);
        
-       if(0==move_areas_init(C, op)) 
-               return 1;
+       return OPERATOR_FINISHED;
+}
+
+/* interaction callback */
+static int move_areas_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       OP_verify_int(op, "x", event->x, NULL);
+       OP_verify_int(op, "y", event->y, NULL);
+
+       if(!move_areas_init(C, op)) 
+               return OPERATOR_PASS_THROUGH;
        
        /* add temp handler */
        WM_event_add_modal_handler(&C->window->handlers, op);
        
-       return 0;
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int move_areas_cancel(bContext *C, wmOperator *op)
+{
+       WM_event_remove_modal_handler(&C->window->handlers, op);                                
+
+       OP_set_int(op, "delta", 0);
+       move_areas_apply(C, op);
+       move_areas_exit(C, op);
+
+       return OPERATOR_CANCELLED;
 }
 
 /* modal callback for while moving edges */
-/* return 0 = stop evaluating for next handlers */
-static int move_areas_modal (bContext *C, wmOperator *op, wmEvent *event)
+static int move_areas_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
-       int dir;
+       sAreaMoveData *md;
+       int delta, x, y;
 
-       OP_get_int(op, "dir", &dir);
+       md= op->customdata;
+
+       OP_get_int(op, "x", &x);
+       OP_get_int(op, "y", &y);
 
        /* execute the events */
        switch(event->type) {
                case MOUSEMOVE:
-                       
-                       if(dir=='v')
-                               op->delta= event->x - op->veci.x;
-                       else
-                               op->delta= event->y - op->veci.y;
-                       
-                       move_areas_exec(C, op);
-                       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+                       delta= (md->dir == 'v')? event->x - x: event->y - y;
+                       OP_set_int(op, "delta", delta);
+
+                       move_areas_apply(C, op);
                        break;
                        
                case LEFTMOUSE:
                        if(event->val==0) {
                                move_areas_exit(C, op);
                                WM_event_remove_modal_handler(&C->window->handlers, op);                                
+                               return OPERATOR_FINISHED;
                        }
                        break;
                        
                case ESCKEY:
-                       op->delta= 0;
-                       move_areas_exec(C, op);
-                       
-                       WM_event_remove_modal_handler(&C->window->handlers, op);
-                       move_areas_exit(C, op);
-                       break;
+                       return move_areas_cancel(C, op);
        }
        
-       return 1;
+       return OPERATOR_RUNNING_MODAL;
 }
 
 void ED_SCR_OT_move_areas(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Move area edges";
        ot->idname= "ED_SCR_OT_move_areas";
 
-       ot->init= move_areas_init;
+       ot->exec= move_areas_exec;
        ot->invoke= move_areas_invoke;
+       ot->cancel= move_areas_cancel;
        ot->modal= move_areas_modal;
-       ot->exec= move_areas_exec;
-       ot->exit= move_areas_exit;
 
        ot->poll= ED_operator_screen_mainwinactive;
 }
@@ -1353,26 +1379,60 @@ typedef struct sAreaSplitData
        ScrArea *narea; /* new area */
 } sAreaSplitData;
 
+static int split_area_init(bContext *C, wmOperator *op)
+{
+       AZone *az= NULL;
+       ScrArea *sa= NULL;
+       sAreaSplitData *sd= NULL;
+       int x, y;
+
+       /* required properties */
+       if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
+               return 0;
+       
+       OP_verify_int(op, "delta", 0, NULL);
+       OP_verify_int(op, "dir", 0, NULL);
+       
+       for(sa= C->screen->areabase.first; sa; sa= sa->next) {
+               az= is_in_area_actionzone(sa, x, y);
+               if(az!=NULL) break;
+       }
+       
+       if(az==NULL) return 0;
+       
+       sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_split_area");
+       op->customdata= sd;
+       
+       sd->state= SPLIT_STARTED;
+       sd->deltax= 0;
+       sd->deltay= 0;
+       
+       return 1;
+}
+
 /* the moving of the new egde */
-static int split_area_exec(bContext *C, wmOperator *op)
+static void split_area_apply(bContext *C, wmOperator *op)
 {
        sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
-       int newval= sd->origval + op->delta;
-       
+       int newval, delta, dir;
+
+       OP_get_int(op, "delta", &delta);
+       OP_get_int(op, "dir", &dir);
+
+       newval= sd->origval + delta;
        newval= CLAMPIS(newval, -sd->min, sd->max);
        
-       if((sd->dir=='v') && (newval > sd->min && newval < sd->max-1)) {
+       if((dir=='v') && (newval > sd->min && newval < sd->max-1)) {
                sd->nedge->v1->vec.x= newval;
                sd->nedge->v2->vec.x= newval;
        }
-       if((sd->dir=='h') && (newval > sd->min+HEADERY && newval < sd->max-HEADERY)) {
+       if((dir=='h') && (newval > sd->min+HEADERY && newval < sd->max-HEADERY)) {
                sd->nedge->v1->vec.y= newval;           
                sd->nedge->v2->vec.y= newval;
        }
-       return 1;
 }
 
-static int split_area_exit(bContext *C, wmOperator *op)
+static void split_area_exit(bContext *C, wmOperator *op)
 {
        if (op->customdata) {
                MEM_freeN(op->customdata);
@@ -1384,27 +1444,29 @@ static int split_area_exit(bContext *C, wmOperator *op)
        /* this makes sure aligned edges will result in aligned grabbing */
        removedouble_scrverts(C->screen);
        removedouble_scredges(C->screen);
-       
-       return 1;
 }
 
-static int split_initintern(bContext *C, wmOperator *op, sAreaSplitData *sd)
+static int split_area_init_intern(bContext *C, wmOperator *op, sAreaSplitData *sd)
 {
        float fac= 0.0;
-       if(sd->dir=='h') {
-               sd->origval= op->veci.y;
-               fac= 1.0 - ((float)(sd->sarea->v3->vec.y - op->veci.y)) / (float)sd->sarea->winy;
+       int dir;
+
+       OP_get_int(op, "dir", &dir);
+
+       if(dir=='h') {
+               OP_get_int(op, "y", &sd->origval);
+               fac= 1.0 - ((float)(sd->sarea->v3->vec.y - sd->origval)) / (float)sd->sarea->winy;
                sd->min= sd->aedge->v1->vec.y;
                sd->max= sd->aedge->v2->vec.y;
        }
        else {
-               sd->origval= op->veci.x;
-               fac= 1.0 - ((float)(sd->sarea->v4->vec.x - op->veci.x)) / (float)sd->sarea->winx;
+               OP_get_int(op, "x", &sd->origval);
+               fac= 1.0 - ((float)(sd->sarea->v4->vec.x - sd->origval)) / (float)sd->sarea->winx;
                sd->min= sd->aedge->v1->vec.x;
                sd->max= sd->aedge->v2->vec.x;
        }
        
-       sd->narea= splitarea(C->window, C->screen, sd->sarea, sd->dir, fac);
+       sd->narea= splitarea(C->window, C->screen, sd->sarea, dir, fac);
        
        if(sd->narea==NULL) return 0;
        
@@ -1418,46 +1480,32 @@ static int split_initintern(bContext *C, wmOperator *op, sAreaSplitData *sd)
        return 1;
 }
 
-static int split_area_init (bContext *C, wmOperator *op)
+static int split_area_exec(bContext *C, wmOperator *op)
 {
-       AZone *az= NULL;
-       ScrArea *sa= NULL;
-       sAreaSplitData *sd= NULL;
-       
-       for(sa= C->screen->areabase.first; sa; sa= sa->next) {
-               az= is_in_area_actionzone(sa, op->veci.x, op->veci.y);
-               if(az!=NULL) break;
-       }
+       /* XXX: this does nothing, part of the code should be moved
+        * out of modal() */
        
-       if(az==NULL) return 0;
+       if(!split_area_init(C, op))
+               return OPERATOR_CANCELLED;
        
-       sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_split_area");
-       op->customdata= sd;
+       split_area_apply(C, op);
+       split_area_exit(C, op);
        
-       sd->state= SPLIT_STARTED;
-       sd->deltax= 0;
-       sd->deltay= 0;
-       
-       return 1;
+       return OPERATOR_FINISHED;
 }
 
 static int split_area_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       /* operator arguments and storage */
-       op->customdata= NULL;
-       op->delta= 0;
-       op->veci.x= event->x;
-       op->veci.y= event->y;
+       OP_verify_int(op, "x", event->x, NULL);
+       OP_verify_int(op, "y", event->y, NULL);
 
-       op->customdata= NULL;
-       
-       if(0==split_area_init(C, op)) 
-               return 1;
+       if(!split_area_init(C, op))
+               return OPERATOR_PASS_THROUGH;
        
        /* add temp handler */
        WM_event_add_modal_handler(&C->window->handlers, op);
        
-       return 0;
+       return OPERATOR_RUNNING_MODAL;
 }
 
 /* join areas */
@@ -1490,8 +1538,8 @@ static void split_joincurrent(bContext *C, sAreaSplitData *sd)
                        screen_addedge(C->screen, sd->sarea->v3, sd->sarea->v4);
                }
 
-               if (C->curarea == sd->narea) {
-                       C->curarea = NULL;
+               if (C->area == sd->narea) {
+                       C->area = NULL;
                }
                screen_delarea(C->screen, sd->narea);
                sd->narea = NULL;
@@ -1500,10 +1548,28 @@ static void split_joincurrent(bContext *C, sAreaSplitData *sd)
        }
 }
 
+static int split_area_cancel(bContext *C, wmOperator *op)
+{
+       sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
+
+       WM_event_remove_modal_handler(&C->window->handlers, op);
+
+       OP_set_int(op, "delta", 0);
+       split_joincurrent(C, sd);
+       split_area_exit(C, op);
+
+       return OPERATOR_CANCELLED;
+}
+
 static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
        ScrArea *sa= NULL, *sold=NULL;
        sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
+       int x, y, dir;
+
+       OP_get_int(op, "x", &x);
+       OP_get_int(op, "y", &y);
+       OP_get_int(op, "dir", &dir);
 
        /* execute the events */
        switch(event->type) {
@@ -1515,19 +1581,19 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
                                        If one dir is delta threshold, and other dir is within "grey area" -> vert/hor split.
                                        If we get both over threshold -> subdiv.
                                */
-                               sd->deltax= event->x - op->veci.x;
-                               sd->deltay= event->y - op->veci.y;
+                               sd->deltax= event->x - x;
+                               sd->deltay= event->y - y;
                                
                                if(sd->deltax>10 && sd->deltay<4) {
                                        printf("split on v\n");
-                                       sd->dir='v';
                                        sd->state= SPLIT_PROGRESS;
-                                       op->delta= sd->deltax;
+                                       OP_set_int(op, "dir", 'v');
+                                       OP_set_int(op, "delta", sd->deltax);
                                } else if(sd->deltay>10 && sd->deltax<4) {
                                        printf("split on h\n");
-                                       sd->dir='h';
                                        sd->state= SPLIT_PROGRESS;
-                                       op->delta= sd->deltay;
+                                       OP_set_int(op, "dir", 'h');
+                                       OP_set_int(op, "delta", sd->deltay);
                                }
                                
                        } else if(sd->state==SPLIT_PROGRESS) {
@@ -1539,7 +1605,7 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
                                        split_joincurrent(C, sd);
 
                                        /* now find aedge with same orientation as sd->dir (inverted) */
-                                       if(sd->dir=='v') {
+                                       if(dir=='v') {
                                                sd->aedge= screen_findedge(C->screen, sa->v1, sa->v4);
                                                if(sd->aedge==NULL) sd->aedge= screen_findedge(C->screen, sa->v2, sa->v3);
                                        }
@@ -1550,19 +1616,19 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
 
                                        /* set sd and op to new init state */
                                        sd->sarea= sa;
-                                       op->delta= 0;
-                                       op->veci.x= event->x;
-                                       op->veci.y= event->y;
-                                       split_initintern(C, op, sd);
+                                       OP_set_int(op, "delta", 0);
+                                       OP_set_int(op, "x", event->x);
+                                       OP_set_int(op, "y", event->y);
+                                       split_area_init_intern(C, op, sd);
                                }
                                else {
                                        /* all is cool, update delta according complicated formula */
-                                       if(sd->dir=='v')
-                                               op->delta= event->x - op->veci.x;
+                                       if(dir=='v')
+                                               OP_set_int(op, "delta", event->x - y);
                                        else
-                                               op->delta= event->y - op->veci.y;
+                                               OP_set_int(op, "delta", event->x - y);
                                        
-                                       split_area_exec(C, op);
+                                       split_area_apply(C, op);
                                }
                        } else if (sd->state==SPLIT_DONE) {
                                /* shouldn't get here anymore */
@@ -1573,18 +1639,15 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
                        if(event->val==0) { /* mouse up => confirm if not near/on starting edge */
                                split_area_exit(C, op);
                                WM_event_remove_modal_handler(&C->window->handlers, op);
+                               return OPERATOR_FINISHED;
                        }
                        break;
                case RIGHTMOUSE: /* cancel operation */
                case ESCKEY:
-                       op->delta= 0;
-                       split_joincurrent(C, sd);
-                       WM_event_remove_modal_handler(&C->window->handlers, op);
-                       split_area_exit(C, op);
-                       break;
+                       return split_area_cancel(C, op);
        }
        
-       return 1;
+       return OPERATOR_RUNNING_MODAL;
 }
 
 void ED_SCR_OT_split_area(wmOperatorType *ot)
@@ -1592,11 +1655,9 @@ void ED_SCR_OT_split_area(wmOperatorType *ot)
        ot->name = "Split area";
        ot->idname = "ED_SCR_OT_split_area";
        
-       ot->init= split_area_init;
+       ot->exec= split_area_exec;
        ot->invoke= split_area_invoke;
        ot->modal= split_area_modal;
-       ot->exec= split_area_exec;
-       ot->exit= split_area_exit;
        
        ot->poll= ED_operator_screenactive;
 }
@@ -1604,8 +1665,8 @@ void ED_SCR_OT_split_area(wmOperatorType *ot)
 /* ************** join area operator ********************************************** */
 
 /* operator state vars used:  
-           op->veci   mouse coord near edge
-           op->delta  movement of edge
+           x, y       mouse coord near edge
+           delta      movement of edge
 
    callbacks:
 
@@ -1613,6 +1674,9 @@ void ED_SCR_OT_split_area(wmOperatorType *ot)
                        test if the edge divides two areas, 
                        store active and nonactive area,
             
+   apply()
+
+   exit()      cleanup, send notifier
 
    exec()      remove active window, 
                        recalc size,
@@ -1624,11 +1688,9 @@ void ED_SCR_OT_split_area(wmOperatorType *ot)
             add handler
 
    modal()     accept modal events while doing it
-                       call exec() with active window and nonactive window
+                       call apply() with active window and nonactive window
             call exit() and remove handler when LMB confirm
 
-   exit()      cleanup, send notifier
-
 */
 
 typedef struct sAreaJoinData
@@ -1643,17 +1705,19 @@ typedef struct sAreaJoinData
 
 /* validate selection inside screen, set variables OK */
 /* return 0: init failed */
-static int join_areas_init (bContext *C, wmOperator *op)
+static int join_areas_init(bContext *C, wmOperator *op)
 {
        ScrArea *actarea = NULL;
        sAreaJoinData* jd= NULL;
-       
-       actarea = screen_areahascursor(C->screen, op->veci.x, op->veci.y);
-       if (actarea==NULL)
-       {
+       int x, y;
+
+       if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
                return 0;
-       }
        
+       actarea = screen_areahascursor(C->screen, x, y);
+       if(actarea==NULL)
+               return 0;
+
        jd = (sAreaJoinData*)MEM_callocN(sizeof (sAreaJoinData), "op_join_areas");
                
        jd->sa1 = actarea;
@@ -1665,7 +1729,7 @@ static int join_areas_init (bContext *C, wmOperator *op)
 }
 
 /* apply the join of the areas (space types) */
-static int join_areas_exec(bContext *C, wmOperator *op)
+static int join_areas_apply(bContext *C, wmOperator *op)
 {
        sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
        if (!jd) return 0;
@@ -1704,8 +1768,8 @@ static int join_areas_exec(bContext *C, wmOperator *op)
                screen_addedge(C->screen, jd->sa1->v3, jd->sa1->v4);
        }
 
-       if (C->curarea == jd->sa2) {
-               C->curarea = NULL;
+       if (C->area == jd->sa2) {
+               C->area = NULL;
        }
        screen_delarea(C->screen, jd->sa2);
        jd->sa2 = NULL;
@@ -1714,24 +1778,6 @@ static int join_areas_exec(bContext *C, wmOperator *op)
 
        return 1;
 }
-/* interaction callback */
-/* return 0 = stop evaluating for next handlers */
-static int join_areas_invoke (bContext *C, wmOperator *op, wmEvent *event)
-{
-       /* operator arguments and storage */
-       op->delta= 0;
-       op->veci.x= event->x;
-       op->veci.y= event->y;
-       op->customdata = NULL;
-       printf("invoke \n");
-       if(0==join_areas_init(C, op)) 
-               return 1;
-       
-       /* add temp handler */
-       WM_event_add_modal_handler(&C->window->handlers, op);
-       
-       return 0;
-}
 
 static int is_inside_area(ScrArea *ar, short x, short y)
 {
@@ -1746,7 +1792,7 @@ static int is_inside_area(ScrArea *ar, short x, short y)
 
 
 /* finish operation */
-static int join_areas_exit(bContext *C, wmOperator *op)
+static void join_areas_exit(bContext *C, wmOperator *op)
 {
        if (op->customdata) {
                MEM_freeN(op->customdata);
@@ -1757,13 +1803,57 @@ static int join_areas_exit(bContext *C, wmOperator *op)
        removedouble_scredges(C->screen);
        removenotused_scredges(C->screen);
        removenotused_scrverts(C->screen);
-       printf("exit \n");
-       return 1;
+}
+
+static int join_areas_exec(bContext *C, wmOperator *op)
+{
+       if(!join_areas_init(C, op)) 
+               return OPERATOR_CANCELLED;
+       
+       join_areas_apply(C, op);
+       join_areas_exit(C, op);
+
+       return OPERATOR_FINISHED;
+}
+
+/* interaction callback */
+static int join_areas_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       OP_verify_int(op, "x", event->x, NULL);
+       OP_verify_int(op, "y", event->y, NULL);
+
+       if(!join_areas_init(C, op)) 
+               return OPERATOR_PASS_THROUGH;
+       
+       /* add temp handler */
+       WM_event_add_modal_handler(&C->window->handlers, op);
+       
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int join_areas_cancel(bContext *C, wmOperator *op)
+{
+       sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+
+       if (jd->sa1) {
+               jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+               jd->sa1->flag &= ~AREA_FLAG_DRAWJOINTO;
+       }
+       if (jd->sa2) {
+               jd->sa2->flag &= ~AREA_FLAG_DRAWJOINFROM;
+               jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+       }
+
+       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
+       WM_event_remove_modal_handler(&C->window->handlers, op);                        
+       OP_set_int(op, "delta", 0);
+       join_areas_exit(C, op);
+
+       return OPERATOR_CANCELLED;
 }
 
 /* modal callback while selecting area (space) that will be removed */
-/* return 0 = stop evaluating for next handlers */
-static int join_areas_modal (bContext *C, wmOperator *op, wmEvent *event)
+static int join_areas_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
        /* execute the events */
        switch(event->type) {
@@ -1831,36 +1921,34 @@ static int join_areas_modal (bContext *C, wmOperator *op, wmEvent *event)
                        }
                case RIGHTMOUSE:
                        if(event->val==0) {
-                               join_areas_exec(C, op);
+                               join_areas_apply(C, op);
                                WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
                                join_areas_exit(C, op);
                                WM_event_remove_modal_handler(&C->window->handlers, op);
+                               return OPERATOR_FINISHED;
                        }
                        break;
                        
                case ESCKEY:
-                       op->delta= 0;
-                       join_areas_exit(C, op);
-                       WM_event_remove_modal_handler(&C->window->handlers, op);                        
-                       break;
+                       return join_areas_cancel(C, op);
        }
-       return 1;
+
+       return OPERATOR_RUNNING_MODAL;
 }
 
 /* Operator for joining two areas (space types) */
 void ED_SCR_OT_join_areas(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Join area";
        ot->idname= "ED_SCR_OT_join_areas";
        
        /* api callbacks */
-       ot->init= join_areas_init;
+       ot->exec= join_areas_exec;
        ot->invoke= join_areas_invoke;
+       ot->cancel= join_areas_cancel;
        ot->modal= join_areas_modal;
-       ot->exec= join_areas_exec;
-       ot->exit= join_areas_exit;
 
        ot->poll= ED_operator_screenactive;
 }
+
index 503dd01b5d54e62d7fd56eaa7c76956016fc56b1..54f9593ea7b09f3351afc37efab9650c1293d92c 100644 (file)
@@ -42,8 +42,6 @@
 
 #include "screen_intern.h"     /* own module include */
 
-static ListBase local_ops;
-
 /* ************** Poll tests ********************** */
 
 int ED_operator_screenactive(bContext *C)
@@ -69,31 +67,20 @@ static void ED_SCR_OT_cursor_type(wmOperatorType *ot)
     ot->idname= "ED_SCR_OT_cursor_type";
        
     ot->invoke= screen_cursor_test;
-    ot->exec= NULL;
     ot->poll= ED_operator_screenactive;
 }
 
-#define ADD_OPTYPE(opfunc)     ot= MEM_callocN(sizeof(wmOperatorType), "operatortype"); \
-                                                       opfunc(ot);  \
-                                                       BLI_addtail(&local_ops, ot)
-
-
-
-/* called via wm_init_exit.c ED_spacetypes_init() */
+/* called in spacetypes.c */
 void ED_operatortypes_screen(void)
 {
-       wmOperatorType *ot;
-       
-       ADD_OPTYPE( ED_SCR_OT_move_areas );
-       ADD_OPTYPE( ED_SCR_OT_cursor_type );
-       ADD_OPTYPE( ED_SCR_OT_split_area );
-       ADD_OPTYPE( ED_SCR_OT_join_areas );
-       
-       WM_operatortypelist_append(&local_ops);
+       WM_operatortype_append(ED_SCR_OT_move_areas);
+       WM_operatortype_append(ED_SCR_OT_cursor_type);
+       WM_operatortype_append(ED_SCR_OT_split_area);
+       WM_operatortype_append(ED_SCR_OT_join_areas);
 }
 
-/* called in wm.c */
-void ed_screen_keymap(wmWindowManager *wm)
+/* called in spacetypes.c */
+void ED_keymap_screen(wmWindowManager *wm)
 {
        WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_cursor_type", MOUSEMOVE, 0, 0, 0);
        WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_move_areas", LEFTMOUSE, KM_PRESS, 0, 0);
@@ -101,8 +88,3 @@ void ed_screen_keymap(wmWindowManager *wm)
        WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_join_areas", RIGHTMOUSE, KM_PRESS, KM_ALT, 0); 
 }
 
-
-
-
-
-
index 88ac8de1f882d3a3e4de9f33fd95aaad80377bb7..0292df8bc24f54ab35127b3e20a49c9b29f4de26 100644 (file)
 /* only call once on startup, storage is static data (no malloc!) in kernel listbase */
 void ED_spacetypes_init(void)
 {
+       const ListBase *spacetypes;
+       SpaceType *type;
+
+       /* create space types */
+       ED_spacetype_time();
        ED_spacetype_view3d();
 //     ED_spacetype_ipo();
 //     ...
        
-       
+       /* register operator types for screen and all spaces */
        ED_operatortypes_screen();
-//     ED_operatortypes_view3d();
-//     ...
-       
+
+       spacetypes = BKE_spacetypes_list();
+       for(type=spacetypes->first; type; type=type->next)
+               type->operatortypes();
 }
 
+/* called in wm.c */
+void ED_spacetypes_keymap(wmWindowManager *wm)
+{
+       const ListBase *spacetypes;
+       SpaceType *type;
+
+       ED_keymap_screen(wm);
+
+       spacetypes = BKE_spacetypes_list();
+       for(type=spacetypes->first; type; type=type->next)
+               type->keymap(wm);
+}
 
 /* ****************************** space template *********************** */
 
@@ -71,7 +89,7 @@ static void xxx_free(SpaceLink *sl)
 }
 
 /* spacetype; init callback for usage, should be redoable */
-static void xxx_init(ScrArea *sa)
+static void xxx_init(wmWindowManager *wm, ScrArea *sa)
 {
        
        /* link area to SpaceXXX struct */
@@ -93,6 +111,16 @@ static SpaceLink *xxx_duplicate(SpaceLink *sl)
        return NULL;
 }
 
+static void xxx_operatortypes(void)
+{
+       /* register operator types for this space */
+}
+
+static void xxx_keymap(wmWindowManager *wm)
+{
+       /* add default items to keymap */
+}
+
 /* only called once, from screen/spacetypes.c */
 void ED_spacetype_xxx(void)
 {
@@ -105,6 +133,8 @@ void ED_spacetype_xxx(void)
        st.init= xxx_init;
        st.refresh= xxx_refresh;
        st.duplicate= xxx_duplicate;
+       st.operatortypes= xxx_operatortypes;
+       st.keymap= xxx_keymap;
        
        BKE_spacetype_register(&st);
 }
diff --git a/source/blender/editors/space_time/Makefile b/source/blender/editors/space_time/Makefile
new file mode 100644 (file)
index 0000000..72dca17
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. 
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# Makes module object directory and bounces make to subdirectories.
+
+LIBNAME = ed_time
+DIR = $(OCGDIR)/blender/$(LIBNAME)
+
+include nan_compile.mk
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+
+# not very neat....
+CPPFLAGS += -I../../windowmanager
+CPPFLAGS += -I../../blenloader
+CPPFLAGS += -I../../blenkernel
+CPPFLAGS += -I../../blenlib
+CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../imbuf
+CPPFLAGS += -I../../python
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+
+# own include 
+
+CPPFLAGS += -I../include 
diff --git a/source/blender/editors/space_time/SConscript b/source/blender/editors/space_time/SConscript
new file mode 100644 (file)
index 0000000..091218e
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('*.c')
+
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs += '../../windowmanager #/intern/guardedalloc'
+
+env.BlenderLib ( 'bf_editors_space_time', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] )
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
new file mode 100644 (file)
index 0000000..f6557c5
--- /dev/null
@@ -0,0 +1,263 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "DNA_object_types.h"
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_rand.h"
+
+#include "BKE_global.h"
+#include "BKE_screen.h"
+
+#include "ED_area.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+#include "BIF_resources.h"
+#include "BIF_view2d.h"
+
+#include "time_intern.h"
+
+/* ************************ main time area region *********************** */
+
+/* draws a current frame indicator for the TimeLine */
+static void time_draw_cfra_time(const bContext *C, SpaceTime *stime)
+{
+       Scene *scene= C->scene;
+       float vec[2];
+       
+       vec[0]= scene->r.cfra;
+       vec[0]*= scene->r.framelen;
+
+       vec[1]= stime->v2d.cur.ymin;
+       BIF_ThemeColor(TH_CFRAME);      // no theme, should be global color once...
+       glLineWidth(3.0);
+
+       glBegin(GL_LINES);
+               glVertex2fv(vec);
+               vec[1]= stime->v2d.cur.ymax;
+               glVertex2fv(vec);
+       glEnd();
+       
+       glLineWidth(1.0);
+}
+
+static void time_draw_sfra_efra(const bContext *C, SpaceTime *stime)
+{
+    /* draw darkened area outside of active timeline 
+        * frame range used is preview range or scene range */
+       BIF_ThemeColorShade(TH_BACK, -25);
+
+       if (PSFRA < PEFRA) {
+               glRectf(stime->v2d.cur.xmin, stime->v2d.cur.ymin, PSFRA, stime->v2d.cur.ymax);
+               glRectf(PEFRA, stime->v2d.cur.ymin, stime->v2d.cur.xmax, stime->v2d.cur.ymax);
+       }
+       else {
+               glRectf(stime->v2d.cur.xmin, stime->v2d.cur.ymin, stime->v2d.cur.xmax, stime->v2d.cur.ymax);
+       }
+
+       BIF_ThemeColorShade(TH_BACK, -60);
+       /* thin lines where the actual frames are */
+       fdrawline(PSFRA, stime->v2d.cur.ymin, PSFRA, stime->v2d.cur.ymax);
+       fdrawline(PEFRA, stime->v2d.cur.ymin, PEFRA, stime->v2d.cur.ymax);
+}
+
+static void time_main_area_init(const bContext *C, ARegion *ar)
+{
+       /* add handlers, stuff you only do once or on area/region changes */
+}
+
+static void time_main_area_refresh(const bContext *C, ARegion *ar)
+{
+       /* refresh to match contextual changes */
+}
+
+static void time_main_area_draw(const bContext *C, ARegion *ar)
+{
+       /* draw entirely, windowsize changes should be handled here */
+       SpaceTime *stime= C->area->spacedata.first;
+       float col[3];
+       int unit, winx, winy;
+
+       winx= ar->winrct.xmax-ar->winrct.xmin;
+       winy= ar->winrct.ymax-ar->winrct.ymin;
+
+       /* clear and setup matrix */
+       BIF_GetThemeColor3fv(TH_BACK, col);
+       col[0]= 1.0f;
+       col[1]= 0.8f;
+       col[2]= 0.0f;
+       glClearColor(col[0], col[1], col[2], 0.0);
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       BIF_view2d_ortho(C, &stime->v2d);
+
+       /* start and end frame */
+       time_draw_sfra_efra(C, stime);
+
+       /* grid */
+       unit= (stime->flag & TIME_DRAWFRAMES)? V2D_UNIT_FRAMES: V2D_UNIT_SECONDS;
+       BIF_view2d_calc_grid(C, &stime->v2d, unit, V2D_GRID_CLAMP, winx, winy);
+       BIF_view2d_draw_grid(C, &stime->v2d, V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS);
+
+       /* current frame */
+       time_draw_cfra_time(C, stime);
+}
+
+static void time_main_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+       /* draw entirely, windowsize changes should be handled here */
+}
+
+/* ******************** default callbacks for time space ***************** */
+
+static SpaceLink *time_new(void)
+{
+       SpaceTime *stime;
+
+       stime= MEM_callocN(sizeof(SpaceTime), "inittime");
+
+       stime->spacetype= SPACE_TIME;
+       stime->blockscale= 0.7;
+       stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN;
+
+       stime->v2d.tot.xmin= -4.0;
+       stime->v2d.tot.ymin=  0.0;
+       stime->v2d.tot.xmax= (float)EFRA + 4.0;
+       //stime->v2d.tot.ymax= (float)stime->winy;
+
+       stime->v2d.cur= stime->v2d.tot;
+
+       stime->v2d.min[0]= 1.0;
+       //stime->v2d.min[1]= (float)stime->winy;
+
+       stime->v2d.max[0]= 32000.0;
+       //stime->v2d.max[1]= (float)stime->winy;
+
+       stime->v2d.minzoom= 0.1f;
+       stime->v2d.maxzoom= 10.0;
+
+       stime->v2d.scroll= 0;
+       stime->v2d.keepaspect= 0;
+       stime->v2d.keepzoom= 0;
+       stime->v2d.keeptot= 0;
+
+       stime->flag |= TIME_DRAWFRAMES;
+
+       return (SpaceLink*)stime;
+}
+
+/* not spacelink itself */
+static void time_free(SpaceLink *sl)
+{
+}
+
+/* spacetype; init callback */
+static void time_init(wmWindowManager *wm, ScrArea *sa)
+{
+       ARegion *ar;
+       
+       /* link area to SpaceXXX struct */
+
+       /* add handlers to area */
+       /* define how many regions, the order and types */
+       
+       /* add types to regions */
+       for(ar= sa->regionbase.first; ar; ar= ar->next) {
+               if(ar->regiontype == RGN_TYPE_WINDOW) {
+                       static ARegionType mainart={NULL, NULL, NULL, NULL};
+
+                       mainart.init= time_main_area_init;
+                       mainart.refresh= time_main_area_refresh;
+                       mainart.draw= time_main_area_draw;
+                       mainart.listener= time_main_area_listener;
+
+                       ar->type= &mainart;
+
+                       /* XXX the windowmanager may not be th best place to keep these
+                        * keymaps, and this function callback may not be the best one
+                        * to add the keymap handler, also will need to take care of
+                        * area type changes, etc, basically space callbacks need to
+                        * be looked at further */
+                       WM_event_remove_keymap_handler(&wm->timekeymap, &ar->handlers);
+                       WM_event_add_keymap_handler(&wm->timekeymap, &ar->handlers);
+               }
+               else {
+                       static ARegionType art={NULL, NULL, NULL, NULL};
+
+                       /* for time being; register 1 type */
+                       ar->type= &art;
+               }
+       }
+}
+
+/* spacetype; context changed */
+static void time_refresh(bContext *C, ScrArea *sa)
+{
+       
+}
+
+static SpaceLink *time_duplicate(SpaceLink *sl)
+{
+       SpaceTime *stime= (SpaceTime *)sl;
+       SpaceTime *stimen= MEM_dupallocN(stime);
+       
+       return (SpaceLink *)stimen;
+}
+
+/* only called once, from screen/spacetypes.c */
+void ED_spacetype_time(void)
+{
+       static SpaceType st;
+       
+       st.spaceid= SPACE_TIME;
+       
+       st.new= time_new;
+       st.free= time_free;
+       st.init= time_init;
+       st.refresh= time_refresh;
+       st.duplicate= time_duplicate;
+       st.operatortypes= time_operatortypes;
+       st.keymap= time_keymap;
+       
+       BKE_spacetype_register(&st);
+}
+
diff --git a/source/blender/editors/space_time/time_intern.h b/source/blender/editors/space_time/time_intern.h
new file mode 100644 (file)
index 0000000..e7fb9af
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef ED_TIME_INTERN_H
+#define ED_TIME_INTERN_H
+
+/* internal exports only */
+
+struct wmWindowManager;
+
+/* time_ops.c */
+void time_operatortypes(void);
+void time_keymap(struct wmWindowManager *wm);
+
+#endif /* ED_TIME_INTERN_H */
+
diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c
new file mode 100644 (file)
index 0000000..a02c5eb
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_blenlib.h"
+
+#include "BKE_global.h"
+
+#include "BIF_view2d.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* ********************** frame change operator ***************************/
+
+static int change_frame_init(bContext *C, wmOperator *op)
+{
+       SpaceTime *stime= C->area->spacedata.first;
+       int cfra;
+
+       if(!OP_get_int(op, "frame", &cfra))
+               return 0;
+       
+       stime->flag |= TIME_CFRA_NUM;
+       
+       return 1;
+}
+
+static void change_frame_apply(bContext *C, wmOperator *op)
+{
+       int cfra;
+
+       OP_get_int(op, "frame", &cfra);
+
+       if(cfra < MINFRAME)
+               cfra= MINFRAME;
+
+#if 0
+       if( cfra!=CFRA || first )
+       {
+               first= 0;
+               CFRA= cfra;
+               update_for_newframe_nodraw(0);  // 1= nosound
+               timeline_force_draw(stime->redraws);
+       }
+       else PIL_sleep_ms(30);
+#endif
+
+       if(cfra!=CFRA)
+               CFRA= cfra;
+       
+       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+       /* XXX: add WM_NOTE_TIME_CHANGED? */
+}
+
+static void change_frame_exit(bContext *C, wmOperator *op)
+{
+       SpaceTime *stime= C->area->spacedata.first;
+
+       stime->flag &= ~TIME_CFRA_NUM;
+}
+
+static int change_frame_exec(bContext *C, wmOperator *op)
+{
+       if(!change_frame_init(C, op))
+               return OPERATOR_CANCELLED;
+       
+       change_frame_apply(C, op);
+       change_frame_exit(C, op);
+       return OPERATOR_FINISHED;
+}
+
+static int frame_from_event(bContext *C, wmEvent *event)
+{
+       SpaceTime *stime= C->area->spacedata.first;
+       ARegion *region= C->region;
+       int x, y;
+       float viewx;
+
+       /* XXX region->winrect isn't updated on window changes */
+       x= event->x - region->winrct.xmin;
+       y= event->y - region->winrct.ymin;
+       BIF_view2d_region_to_view(&stime->v2d, x, y, &viewx, NULL);
+
+       return (int)(viewx+0.5f);
+}
+
+static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       OP_verify_int(op, "frame", frame_from_event(C, event), NULL);
+       change_frame_init(C, op);
+       change_frame_apply(C, op);
+
+       /* add temp handler */
+       WM_event_add_modal_handler(&C->region->handlers, op);
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int change_frame_cancel(bContext *C, wmOperator *op)
+{
+       change_frame_exit(C, op);
+       return OPERATOR_CANCELLED;
+}
+
+static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+       /* execute the events */
+       switch(event->type) {
+               case MOUSEMOVE:
+                       OP_set_int(op, "frame", frame_from_event(C, event));
+                       change_frame_apply(C, op);
+                       break;
+                       
+               case LEFTMOUSE:
+                       if(event->val==0) {
+                               change_frame_exit(C, op);
+                               WM_event_remove_modal_handler(&C->region->handlers, op);                                
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
+       }
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
+/* Operator for joining two areas (space types) */
+void ED_TIME_OT_change_frame(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Change frame";
+       ot->idname= "ED_TIME_OT_change_frame";
+       
+       /* api callbacks */
+       ot->exec= change_frame_exec;
+       ot->invoke= change_frame_invoke;
+       ot->cancel= change_frame_cancel;
+       ot->modal= change_frame_modal;
+}
+
+/* ************************** registration **********************************/
+
+void time_operatortypes(void)
+{
+       WM_operatortype_append(ED_TIME_OT_change_frame);
+}
+
+void time_keymap(wmWindowManager *wm)
+{
+       WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
+}
+
index 9a08c7cd016d4383081af4536061ca770c46a108..1abd860c661d70dfd4006c02ba104d6f02f43d66 100644 (file)
@@ -118,7 +118,7 @@ static void view3d_free(SpaceLink *sl)
 
 
 /* spacetype; init callback */
-static void view3d_init(ScrArea *sa)
+static void view3d_init(struct wmWindowManager *wm, ScrArea *sa)
 {
        ARegion *ar;
        
@@ -174,6 +174,14 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
        return (SpaceLink *)v3dn;
 }
 
+void view3d_operatortypes(void)
+{
+}
+
+void view3d_keymap(struct wmWindowManager *wm)
+{
+}
+
 /* only called once, from screen/spacetypes.c */
 void ED_spacetype_view3d(void)
 {
@@ -186,11 +194,9 @@ void ED_spacetype_view3d(void)
        st.init= view3d_init;
        st.refresh= view3d_refresh;
        st.duplicate= view3d_duplicate;
+       st.operatortypes= view3d_operatortypes;
+       st.keymap= view3d_keymap;
        
        BKE_spacetype_register(&st);
-       
-       
 }
 
-
-
index 56fdc3e113cda4039836341e75e17fd721e6dcb0..788f9f71e562b597eac5018db4961454a5ccbf92 100644 (file)
@@ -65,6 +65,7 @@ typedef struct wmWindowManager {
        /* custom keymaps */
        ListBase windowkeymap;
        ListBase screenkeymap;
+       ListBase timekeymap;
        
        
 } wmWindowManager;
@@ -108,18 +109,26 @@ typedef struct wmOperatorType {
        char *name;             /* text for ui, undo */
        char *idname;   /* unique identifier */
        
-       /* this callback alters UI, adds handlers, or uses cb's below */
-       int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *event);
-       /* this callback is for modal temporary ops, initialize was called */
-       int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *event);
-       
-       int (*init)(struct bContext *, struct wmOperator *);
+       /* this callback executes the operator without any interactive input,
+        * parameters may be provided through operator properties. cannot use
+        * any interface code or input device state.
+        * - see defines below for return values */
        int (*exec)(struct bContext *, struct wmOperator *);
-       int (*exit)(struct bContext *, struct wmOperator *);
-       
+
+       /* for modal temporary operators, initially invoke is called. then
+        * any further events are handled in modal. if the operation is
+        * cancelled due to some external reason, cancel is called
+        * - see defines below for return values */
+       int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *);
+       int (*cancel)(struct bContext *, struct wmOperator *);
+       int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *);
+
+       /* verify if the operator can be executed in the current context, note
+        * that the operator might still fail to execute even if this return true */
        int (*poll)(struct bContext *);
        
-       void *(*uiBlock)(struct wmOperator *);  /* panel for redo or repeat */
+       /* panel for redo and repeat */
+       void *(*uiBlock)(struct wmOperator *);
        
        char *customname;       /* dna name */
        void *customdata;       /* defaults */
@@ -153,21 +162,18 @@ typedef struct wmOperator {
        wmOperatorType *type;
        char idname[64];                /* used to retrieve type pointer */
        
-       /* default storage (lazy?) */
-       void *argv1, *argv2;
-       vec4f   vecf;
-       vec4i   veci;
-       float fac, deltaf;
-       int value, delta;
-       
        /* custom storage, dna pointer */
        void *customdata; 
        /* or IDproperty list */
        IDProperty *properties;
 
-       
 } wmOperator;
 
+/* operator type exec(), invoke() modal(), cancel() return values */
+#define OPERATOR_PASS_THROUGH  0
+#define OPERATOR_RUNNING_MODAL 1
+#define OPERATOR_CANCELLED             2
+#define OPERATOR_FINISHED              3
 
 #endif /* DNA_WINDOWMANAGER_TYPES_H */
 
index 64abda4a849a1fc3b8e67e47524a58614b777257..6b020a07fb94fa5ad6f78a63c397fff2f39eff6a 100644 (file)
@@ -65,6 +65,7 @@ void          WM_keymap_verify_item(ListBase *lb, char *idname, short type,
 void           WM_keymap_add_item      (ListBase *lb, char *idname, short type, 
                                                                 short val, int modifier, short keymodifier);
 struct wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers);
+void           WM_event_remove_keymap_handler(ListBase *keymap, ListBase *handlers);
 struct wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op);
 void           WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op);
 
@@ -81,7 +82,7 @@ int                   WM_operator_winactive   (struct bContext *C);
 
                        /* operator api */
 wmOperatorType *WM_operatortype_find(const char *idname);
-void           WM_operatortypelist_append(ListBase *lb);
+void           WM_operatortype_append(void (*opfunc)(wmOperatorType*));
 
 /* 
  * Operator property api
@@ -98,10 +99,13 @@ void                WM_operatortypelist_append(ListBase *lb);
  * I really think that is better duplicate the string, so we are
  * really sure that the property data don't change.
  *
- * OP_get_int/float/array return 0 on success (found the property)
- * or != 0 if can't found the property in the operator.
+ * OP_get_int/float/array return 1 on success (found the property)
+ * or 0 if can't find the property in the operator.
  * The property value are store in the "value" pointer.
  *
+ * OP_verify_* sets the value only if it wasn't set already, and
+ * returns the existing or new value.
+ *
  * Both array function copy the property data into the "array"
  * pointer, but you need init the len pointer to the "array" size.
  *
@@ -128,6 +132,12 @@ char *OP_get_string(wmOperator *op, char *name);
 int OP_get_int_array(wmOperator *op, char *name, int *array, short *len);
 int OP_get_float_array(wmOperator *op, char *name, float *array, short *len);
 
+void OP_verify_int(wmOperator *op, char *name, int value, int *result);
+void OP_verify_float(wmOperator *op, char *name, float value, int *result);
+char *OP_verify_string(wmOperator *op, char *name, char *str);
+void OP_verify_int_array(wmOperator *op, char *name, int *array, short len, int *resultarray, short *resultlen);
+void OP_verify_float_array(wmOperator *op, char *name, float *array, short len, float *resultarray, short *resultlen);
+
 /*
  * Need call this function in the "exit callback"
  * of the operator, but only if you use the property system.
@@ -135,9 +145,9 @@ int OP_get_float_array(wmOperator *op, char *name, float *array, short *len);
 void OP_free_property(wmOperator *op);
 
                        /* Gesture manager API */
-void WM_gesture_init(bContext *C, int type);
-void WM_gesture_update(bContext *C, struct wmGesture *from);
-void WM_gesture_end(bContext *C, int type);
+void WM_gesture_init(struct bContext *C, int type);
+void WM_gesture_update(struct bContext *C, struct wmGesture *from);
+void WM_gesture_end(struct bContext *C, int type);
 void WM_gesture_free(wmWindow *win);
 
                        /* OpenGL wrappers, mimicing opengl syntax */
index bc24895874eca4855ecbfd22bb015c440101083b..d40fd75116274e464903f4256f626c0f28e867a1 100644 (file)
 #include "ED_screen.h"
 
 /* ****************************************************** */
+
 #define MAX_OP_REGISTERED      32
 
+void wm_operator_free(wmOperator *op)
+{
+       OP_free_property(op);
+       MEM_freeN(op);
+}
+
 /* all operations get registered in the windowmanager here */
 /* called on event handling by event_system.c */
 void wm_operator_register(wmWindowManager *wm, wmOperator *op)
 {
-       wmOperator *opc= MEM_callocN(sizeof(wmOperator), "operator registry");
        int tot;
        
-       *opc= *op;
-       BLI_addtail(&wm->operators, opc);
-       
+       BLI_addtail(&wm->operators, op);
        tot= BLI_countlist(&wm->operators);
        
        while(tot>MAX_OP_REGISTERED) {
                wmOperator *opt= wm->operators.first;
                BLI_remlink(&wm->operators, opt);
-               MEM_freeN(opt);
+               wm_operator_free(opt);
                tot--;
        }
 }
@@ -95,15 +99,11 @@ void wm_check(bContext *C)
        /* case: no open windows at all, for old file reads */
        wm_window_add_ghostwindows(C->wm);
        
-       if(C->window==NULL) {
-               wm_window_make_drawable(C, C->wm->windrawable); 
-       }
-       
        /* case: fileread */
        if(C->wm->initialized==0) {
                
                wm_window_keymap(C->wm);
-               ed_screen_keymap(C->wm);
+               ED_spacetypes_keymap(C->wm);
                
                ED_screens_initialize(C->wm);
                C->wm->initialized= 1;
@@ -119,7 +119,7 @@ void wm_add_default(bContext *C)
        C->wm= wm;
        
        win= wm_window_new(C, C->screen);
-       wm->windrawable= win;
+       wm->winactive= win;
        wm_window_make_drawable(C, win); 
 }
 
@@ -128,14 +128,19 @@ void wm_add_default(bContext *C)
 void wm_close_and_free(bContext *C, wmWindowManager *wm)
 {
        wmWindow *win;
+       wmOperator *op;
        
        while((win= wm->windows.first)) {
                BLI_remlink(&wm->windows, win);
                wm_window_free(C, win);
        }
        
-       BLI_freelistN(&wm->operators);
-       
+       while((op= wm->operators.first)) {
+               BLI_remlink(&wm->operators, op);
+               wm_operator_free(op);
+       }
+
+       BLI_freelistN(&wm->timekeymap);
        BLI_freelistN(&wm->windowkeymap);
        BLI_freelistN(&wm->screenkeymap);
        
index bb0ad54d9679ee866f721d974b2dad64137db911..af61b78746231d9d0c8ebdd5f27c367d1799059c 100644 (file)
@@ -121,23 +121,37 @@ void wm_event_do_notifiers(bContext *C)
                
                for(win= C->wm->windows.first; win; win= win->next) {
                        ScrArea *sa;
+
+                       C->window= win;
+                       C->screen= win->screen;
                        
                        if(note->window && note->window!=win)
                                continue;
                        if(win->screen==NULL)
                                continue;
+
                        printf("notifier win %d screen %s\n", win->winid, win->screen->id.name+2);
                        ED_screen_do_listen(win, note);
                        
                        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
                                ARegion *ar= sa->regionbase.first;
                                
+                               C->area= sa;
+
                                for(; ar; ar= ar->next) {
                                        if(note->swinid && note->swinid!=ar->swinid)
                                                continue;
+
+                                       C->region= ar;
                                        ED_region_do_listen(ar, note);
+                                       C->region= NULL;
                                }
+
+                               C->area= NULL;
                        }
+
+                       C->window= NULL;
+                       C->screen= NULL;
                }
                if(note->data)
                        MEM_freeN(note->data);
@@ -178,6 +192,9 @@ void wm_draw_update(bContext *C)
        for(win= C->wm->windows.first; win; win= win->next) {
                if(wm_draw_update_test_window(win)) {
                        ScrArea *sa;
+
+                       C->window= win;
+                       C->screen= win->screen;
                        
                        /* sets context window+screen */
                        wm_window_make_drawable(C, win);
@@ -189,9 +206,13 @@ void wm_draw_update(bContext *C)
                        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
                                ARegion *ar= sa->regionbase.first;
                                int hasdrawn= 0;
+
+                               C->area= sa;
                                
                                for(; ar; ar= ar->next) {
                                        hasdrawn |= ar->do_draw;
+
+                                       C->region= ar;
                                        
                                        /* cached notifiers */
                                        if(ar->do_refresh)
@@ -199,7 +220,11 @@ void wm_draw_update(bContext *C)
                                        
                                        if(ar->swinid && ar->do_draw)
                                                ED_region_do_draw(C, ar);
+
+                                       C->region= NULL;
                                }
+
+                               C->area = NULL;
                        }
                        
                        /* move this here so we can do area 'overlay' drawing */
@@ -210,6 +235,9 @@ void wm_draw_update(bContext *C)
                                ED_screen_gesture(win);
 
                        wm_window_swap_buffers(win);
+
+                       C->window= NULL;
+                       C->screen= NULL;
                }
        }
 }
@@ -219,8 +247,6 @@ void wm_draw_update(bContext *C)
 /* not handler itself */
 static void wm_event_free_handler(wmEventHandler *handler)
 {
-       if(handler->op)
-               MEM_freeN(handler->op);
 }
 
 void wm_event_free_handlers(ListBase *lb)
@@ -252,57 +278,77 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km)
        return 1;
 }
 
+/* note: this might free the handler from the operator */
 static int wm_handler_operator_call(bContext *C, wmEventHandler *handler, wmEvent *event)
 {
-       int retval= 0;
+       int retval= OPERATOR_PASS_THROUGH;
        
        /* derived, modal or blocking operator */
        if(handler->op) {
-               if(handler->op->type->modal)
-                       retval= handler->op->type->modal(C, handler->op, event);
+               wmOperator *op= handler->op;
+               wmOperatorType *ot= op->type;
+
+               if(ot->modal) {
+
+                       retval= ot->modal(C, op, event);
+
+                       if(retval == OPERATOR_FINISHED && (ot->flag & OPTYPE_REGISTER))
+                               wm_operator_register(C->wm, op);
+                       else if(retval == OPERATOR_CANCELLED || retval == OPERATOR_FINISHED)
+                               wm_operator_free(op);
+               }
                else
                        printf("wm_handler_operator_call error\n");
        }
        else {
                wmOperatorType *ot= WM_operatortype_find(event->keymap_idname);
+
                if(ot) {
                        if(ot->poll==NULL || ot->poll(C)) {
-                               /* operator on stack, register or new modal handle malloc-copies */
-                               wmOperator op;
-                               
-                               memset(&op, 0, sizeof(wmOperator));
-                               op.type= ot;
+                               wmOperator *op= MEM_callocN(sizeof(wmOperator), "wmOperator");
 
-                               if(op.type->invoke)
-                                       retval= (*op.type->invoke)(C, &op, event);
-                               else if(&op.type->exec)
-                                       retval= op.type->exec(C, &op);
-                               
-                               if( ot->flag & OPTYPE_REGISTER)
-                                       wm_operator_register(C->wm, &op);
+                               op->type= ot;
+
+                               if(op->type->invoke)
+                                       retval= (*op->type->invoke)(C, op, event);
+                               else if(op->type->exec)
+                                       retval= op->type->exec(C, op);
+
+                               if(retval == OPERATOR_FINISHED && (ot->flag & OPTYPE_REGISTER))
+                                       wm_operator_register(C->wm, op);
+                               else if(retval != OPERATOR_RUNNING_MODAL)
+                                       wm_operator_free(op);
                        }
                }
        }
-       if(retval)
-               return WM_HANDLER_BREAK;
-       
-       return WM_HANDLER_CONTINUE;
+
+       if(retval == OPERATOR_PASS_THROUGH)
+               return WM_HANDLER_CONTINUE;
+
+       return WM_HANDLER_BREAK;
 }
 
 static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
 {
-       wmEventHandler *handler;
+       wmEventHandler *handler, *nexthandler;
        int action= WM_HANDLER_CONTINUE;
        
        if(handlers==NULL) return action;
        
-       for(handler= handlers->first; handler; handler= handler->next) {
+       /* in this loop, the handler might be freed in wm_handler_operator_call,
+        * and new handler might be added to the head of the list */
+       for(handler= handlers->first; handler; handler= nexthandler) {
+               nexthandler= handler->next;
+
+               /* modal+blocking handler */
+               if(handler->flag & WM_HANDLER_BLOCKING)
+                       action= WM_HANDLER_BREAK;
+
                if(handler->keymap) {
                        wmKeymapItem *km;
                        
                        for(km= handler->keymap->first; km; km= km->next) {
                                if(wm_eventmatch(event, km)) {
-                                       
                                        if(event->type!=MOUSEMOVE)
                                                printf("handle evt %d win %d op %s\n", event->type, C->window->winid, km->idname);
                                        
@@ -319,10 +365,6 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
                        action= wm_handler_operator_call(C, handler, event);
                }
 
-               /* modal+blocking handler */
-               if(handler->flag & WM_HANDLER_BLOCKING)
-                       action= WM_HANDLER_BREAK;
-
                if(action==WM_HANDLER_BREAK)
                        break;
                
@@ -341,7 +383,7 @@ static int wm_event_inside_i(wmEvent *event, rcti *rect)
 void wm_event_do_handlers(bContext *C)
 {
        wmWindow *win;
-       
+
        for(win= C->wm->windows.first; win; win= win->next) {
                wmEvent *event;
                
@@ -350,12 +392,11 @@ void wm_event_do_handlers(bContext *C)
                
                while( (event=wm_event_next(win)) ) {
                        int action;
-                       
-                       if(event->type==BORDERSELECT)
-                               printf("BORDERSELECT Event!!\n");
+
+                       C->window= win;
+                       C->screen= win->screen;
 
                        /* MVC demands to not draw in event handlers... for now we leave it */
-                       /* it also updates context (win, screen) */
                        wm_window_make_drawable(C, win);
                        
                        action= wm_handlers_do(C, event, &win->handlers);
@@ -366,7 +407,7 @@ void wm_event_do_handlers(bContext *C)
                                for(; sa; sa= sa->next) {
                                        if(wm_event_inside_i(event, &sa->totrct)) {
                                                
-                                               C->curarea= sa;
+                                               C->area= sa;
                                                action= wm_handlers_do(C, event, &sa->handlers);
                                                if(action==WM_HANDLER_CONTINUE) {
                                                        ARegion *ar= sa->regionbase.first;
@@ -375,17 +416,22 @@ void wm_event_do_handlers(bContext *C)
                                                                if(wm_event_inside_i(event, &ar->winrct)) {
                                                                        C->region= ar;
                                                                        action= wm_handlers_do(C, event, &ar->handlers);
+                                                                       C->region= NULL;
                                                                        if(action==WM_HANDLER_BREAK)
                                                                                break;
                                                                }
                                                        }
                                                }
+                                               C->area= NULL;
                                                if(action==WM_HANDLER_BREAK)
                                                        break;
                                        }
                                }
                        }
                        wm_event_free(event);
+
+                       C->window= NULL;
+                       C->screen= NULL;
                }
        }
 }
@@ -404,11 +450,8 @@ wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op)
        }
        else {
                wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
-               wmOperator *opc= MEM_mallocN(sizeof(wmOperator), "operator modal");
-               
+               handler->op= op;
                BLI_addhead(handlers, handler);
-               *opc= *op;
-               handler->op= opc;
                
                return handler;
        }
@@ -431,14 +474,33 @@ void WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op)
 
 wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers)
 {
-       wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
+       wmEventHandler *handler;
        
+       /* only allow same keymap once */
+       for(handler= handlers->first; handler; handler= handler->next)
+               if(handler->keymap==keymap)
+                       return;
+
+       handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
        BLI_addtail(handlers, handler);
        handler->keymap= keymap;
        
        return handler;
 }
 
+void WM_event_remove_keymap_handler(ListBase *keymap, ListBase *handlers)
+{
+       wmEventHandler *handler;
+       
+       for(handler= handlers->first; handler; handler= handler->next) {
+               if(handler->keymap==keymap) {
+                       BLI_remlink(handlers, handler);
+                       wm_event_free_handler(handler);
+                       MEM_freeN(handler);
+                       break;
+               }
+       }
+}
 
 /* ********************* ghost stuff *************** */
 
index 8dbe235d256c40eb6dacec306cfba38e3101886c..70bdb60eb48bb2a95cb55f653946364fbf1a83ab 100644 (file)
@@ -370,7 +370,7 @@ return;
        /* we take apart the used screens from non-active window */
        for(win= wm->windows.first; win; win= win->next) {
                BLI_strncpy(win->screenname, win->screen->id.name, MAX_ID_NAME);
-               if(win!=C->window) {
+               if(win!=C->wm->winactive) {
                        BLI_remlink(&G.main->screen, win->screen);
                        //BLI_addtail(screenbase, win->screen);
                }
index 283b269fdfc8d57c7055d10453647939f9832cbb..02e4a0124c26b76577b984b81811a8ee69bd2f07 100644 (file)
@@ -103,7 +103,6 @@ void WM_gesture_update(bContext *C, wmGesture *from)
        if(!to)
                return;
 
-       printf("found gesture!!\n");
        if(to->type==GESTURE_RECT)
                wm_gesture_rect_copy((wmGestureRect*)to, (wmGestureRect*)from);
 }
index 88408869aba569d4313a733b2f4170c34da97854..8b4a167365d19afb84fa7a64cf672bbb1beb42a7 100644 (file)
@@ -62,9 +62,13 @@ wmOperatorType *WM_operatortype_find(const char *idname)
 }
 
 /* all ops in 1 list (for time being... needs evaluation later) */
-void WM_operatortypelist_append(ListBase *lb)
+void WM_operatortype_append(void (*opfunc)(wmOperatorType*))
 {
-       addlisttolist(&global_ops, lb);
+       wmOperatorType *ot;
+       
+       ot= MEM_callocN(sizeof(wmOperatorType), "operatortype");
+       opfunc(ot);
+       BLI_addtail(&global_ops, ot);
 }
 
 /* ************ default ops, exported *********** */
@@ -133,89 +137,99 @@ static void WM_OT_exit_blender(wmOperatorType *ot)
  */
 static int border_select_init(bContext *C, wmOperator *op)
 {
-       OP_set_int(op, "start_x", op->veci.x);
-       OP_set_int(op, "start_y", op->veci.y);
+       int x, y;
+
+       if(!(OP_get_int(op, "start_x", &x) && OP_get_int(op, "start_y", &y)))
+               return 0;
+
        WM_gesture_init(C, GESTURE_RECT);
        return 1;
 }
 
-static int border_select_exec(bContext *C, wmOperator *op)
+static int border_select_apply(bContext *C, wmOperator *op)
 {
        wmGestureRect rect;
-       int x, y;
+       int x, y, endx, endy;
 
        OP_get_int(op, "start_x", &x);
        OP_get_int(op, "start_y", &y);
+       OP_get_int(op, "end_x", &endx);
+       OP_get_int(op, "end_y", &endy);
 
        rect.gesture.next= rect.gesture.prev= NULL;
        rect.gesture.type= GESTURE_RECT;
        rect.x1= x;
        rect.y1= y;
-       rect.x2= op->veci.x;
-       rect.y2= op->veci.y;
+       rect.x2= endx;
+       rect.y2= endy;
        WM_gesture_update(C, (wmGesture *) &rect);
        WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_GESTURE_CHANGED, GESTURE_RECT, NULL);
+
        return 1;
 }
 
+static int border_select_exit(bContext *C, wmOperator *op)
+{
+       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+       OP_free_property(op);
+       return 1;
+}
+
+static int border_select_exec(bContext *C, wmOperator *op)
+{
+       if(!border_select_init(C, op))
+               return OPERATOR_CANCELLED;
+       
+       border_select_apply(C, op);
+       border_select_exit(C, op);
+
+       return OPERATOR_FINISHED;
+}
+
 static int border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        /* operator arguments and storage. */
-       op->properties= NULL;
-       op->veci.x= event->x;
-       op->veci.y= event->y;
+       OP_verify_int(op, "start_x", event->x, NULL);
+       OP_verify_int(op, "start_y", event->y, NULL);
 
-       if(0==border_select_init(C, op))
-               return 1;
+       if(!border_select_init(C, op))
+               return OPERATOR_CANCELLED;
 
        /* add temp handler */
        WM_event_add_modal_handler(&C->window->handlers, op);
-       return 0;
+       return OPERATOR_RUNNING_MODAL;
 }
 
-static int border_select_exit(bContext *C, wmOperator *op)
+static int border_select_cancel(bContext *C, wmOperator *op)
 {
-       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-       OP_free_property(op);
-       return 1;
+       WM_event_remove_modal_handler(&C->window->handlers, op);
+       border_select_exit(C, op);
+       return OPERATOR_CANCELLED;
 }
 
 static int border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
 {
        switch(event->type) {
                case MOUSEMOVE:
-                       op->veci.x= event->x;
-                       op->veci.y= event->y;
-                       border_select_exec(C, op);
+                       OP_set_int(op, "end_x", event->x);
+                       OP_set_int(op, "end_y", event->y);
+                       border_select_apply(C, op);
+                       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_GESTURE_CHANGED, GESTURE_RECT, NULL);
                        WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
                        break;
                case LEFTMOUSE:
                        if(event->val==0) {
-                               wmGestureRect rect;
-                               int x, y;
-
-                               OP_get_int(op, "start_x", &x);
-                               OP_get_int(op, "start_y", &y);
-
-                               rect.gesture.next= rect.gesture.prev= NULL;
-                               rect.gesture.type= GESTURE_RECT;
-                               rect.x1= x;
-                               rect.y1= y;
-                               rect.x2= op->veci.x;
-                               rect.y2= op->veci.y;
-                               WM_gesture_update(C, (wmGesture*)&rect);
+                               border_select_apply(C, op);
                                WM_gesture_end(C, GESTURE_RECT);
-
                                border_select_exit(C, op);
                                WM_event_remove_modal_handler(&C->window->handlers, op);
+                               return OPERATOR_FINISHED;
                        }
                        break;
                case ESCKEY:
-                       WM_event_remove_modal_handler(&C->window->handlers, op);
-                       border_select_exit(C, op);
-                       break;
+                       return border_select_cancel(C, op);
        }
-       return 1;
+       return OPERATOR_RUNNING_MODAL;
 }
 
 void WM_OT_border_select(wmOperatorType *ot)
@@ -224,20 +238,14 @@ void WM_OT_border_select(wmOperatorType *ot)
        ot->name= "Border select";
        ot->idname= "WM_OT_border_select";
 
-       ot->init= border_select_init;
+       ot->exec= border_select_exec;
        ot->invoke= border_select_invoke;
+       ot->cancel= border_select_cancel;
        ot->modal= border_select_modal;
-       ot->exec= border_select_exec;
-       ot->exit= border_select_exit;
 
        ot->poll= WM_operator_winactive;
 }
  
-#define ADD_OPTYPE(opfunc)     ot= MEM_callocN(sizeof(wmOperatorType), "operatortype"); \
-                                                       opfunc(ot);  \
-                                                       BLI_addtail(&global_ops, ot)
-
-
 /* called on initialize WM_exit() */
 void wm_operatortype_free(void)
 {
@@ -247,20 +255,23 @@ void wm_operatortype_free(void)
 /* called on initialize WM_init() */
 void wm_operatortype_init(void)
 {
-       wmOperatorType *ot;
-       
-       ADD_OPTYPE(WM_OT_window_duplicate);
-       ADD_OPTYPE(WM_OT_save_homefile);
-       ADD_OPTYPE(WM_OT_window_fullscreen_toggle);
-       ADD_OPTYPE(WM_OT_exit_blender);
-       ADD_OPTYPE(WM_OT_border_select);
+       WM_operatortype_append(WM_OT_window_duplicate);
+       WM_operatortype_append(WM_OT_save_homefile);
+       WM_operatortype_append(WM_OT_window_fullscreen_toggle);
+       WM_operatortype_append(WM_OT_exit_blender);
+       WM_operatortype_append(WM_OT_border_select);
 }
 
 /* wrapped to get property from a operator. */
 IDProperty *op_get_property(wmOperator *op, char *name)
 {
-       IDProperty *prop= IDP_GetPropertyFromGroup(op->properties, name);
-       return(prop);
+       IDProperty *prop;
+       
+       if(!op->properties)
+               return NULL;
+
+       prop= IDP_GetPropertyFromGroup(op->properties, name);
+       return prop;
 }
 
 /*
@@ -279,13 +290,15 @@ void op_init_property(wmOperator *op)
 /* ***** Property API, exported ***** */
 void OP_free_property(wmOperator *op)
 {
-       IDP_FreeProperty(op->properties);
-       /*
-        * This need change, when the idprop code only
-        * need call IDP_FreeProperty. (check BKE_idprop.h)
-        */
-       MEM_freeN(op->properties);
-       op->properties= NULL;
+       if(op->properties) {
+               IDP_FreeProperty(op->properties);
+               /*
+                * This need change, when the idprop code only
+                * need call IDP_FreeProperty. (check BKE_idprop.h)
+                */
+               MEM_freeN(op->properties);
+               op->properties= NULL;
+       }
 }
 
 void OP_set_int(wmOperator *op, char *name, int value)
@@ -370,11 +383,11 @@ void OP_set_string(wmOperator *op, char *name, char *str)
 int OP_get_int(wmOperator *op, char *name, int *value)
 {
        IDProperty *prop= op_get_property(op, name);
-       int status= 1;
+       int status= 0;
 
        if ((prop) && (prop->type == IDP_INT)) {
                (*value)= prop->data.val;
-               status= 0;
+               status= 1;
        }
        return (status);
 }
@@ -382,11 +395,11 @@ int OP_get_int(wmOperator *op, char *name, int *value)
 int OP_get_float(wmOperator *op, char *name, float *value)
 {
        IDProperty *prop= op_get_property(op, name);
-       int status= 1;
+       int status= 0;
 
        if ((prop) && (prop->type == IDP_FLOAT)) {
                (*value)= *(float*)&prop->data.val;
-               status= 0;
+               status= 1;
        }
        return (status);
 }
@@ -395,7 +408,7 @@ int OP_get_int_array(wmOperator *op, char *name, int *array, short *len)
 {
        IDProperty *prop= op_get_property(op, name);
        short i;
-       int status= 1;
+       int status= 0;
        int *pointer;
 
        if ((prop) && (prop->type == IDP_ARRAY)) {
@@ -405,7 +418,7 @@ int OP_get_int_array(wmOperator *op, char *name, int *array, short *len)
                        array[i]= pointer[i];
 
                (*len)= i;
-               status= 0;
+               status= 1;
        }
        return (status);
 }
@@ -415,7 +428,7 @@ int OP_get_float_array(wmOperator *op, char *name, float *array, short *len)
        IDProperty *prop= op_get_property(op, name);
        short i;
        float *pointer;
-       int status= 1;
+       int status= 0;
 
        if ((prop) && (prop->type == IDP_ARRAY)) {
                pointer= (float *) prop->data.pointer;
@@ -424,7 +437,7 @@ int OP_get_float_array(wmOperator *op, char *name, float *array, short *len)
                        array[i]= pointer[i];
 
                (*len)= i;
-               status= 0;
+               status= 1;
        }
        return (status);
 }
@@ -436,3 +449,76 @@ char *OP_get_string(wmOperator *op, char *name)
                return ((char *) prop->data.pointer);
        return (NULL);
 }
+
+void OP_verify_int(wmOperator *op, char *name, int value, int *result)
+{
+       int rvalue;
+
+       if(OP_get_int(op, name, &rvalue))
+               value= rvalue;
+       else
+               OP_set_int(op, name, value);
+
+       if(result)
+               *result= value;
+}
+
+void OP_verify_float(wmOperator *op, char *name, float value, int *result)
+{
+       float rvalue;
+
+       if(OP_get_float(op, name, &rvalue))
+               value= rvalue;
+       else
+               OP_set_float(op, name, value);
+       
+       if(result)
+               *result= value;
+}
+
+char *OP_verify_string(wmOperator *op, char *name, char *str)
+{
+       char *result= OP_get_string(op, name);
+
+       if(!result) {
+               OP_set_string(op, name, str);
+               result= OP_get_string(op, name);
+       }
+
+       return result;
+}
+
+void OP_verify_int_array(wmOperator *op, char *name, int *array, short len, int *resultarray, short *resultlen)
+{
+       int rarray[1];
+       short rlen= 1;
+
+       if(resultarray && resultlen) {
+               if(!OP_get_int_array(op, name, resultarray, &rlen)) {
+                       OP_set_int_array(op, name, array, len);
+                       OP_get_int_array(op, name, resultarray, resultlen);
+               }
+       }
+       else {
+               if(!OP_get_int_array(op, name, rarray, &rlen))
+                       OP_set_int_array(op, name, array, len);
+       }
+}
+
+void OP_verify_float_array(wmOperator *op, char *name, float *array, short len, float *resultarray, short *resultlen)
+{
+       float rarray[1];
+       short rlen= 1;
+
+       if(resultarray && resultlen) {
+               if(!OP_get_float_array(op, name, resultarray, &rlen)) {
+                       OP_set_float_array(op, name, array, len);
+                       OP_get_float_array(op, name, resultarray, resultlen);
+               }
+       }
+       else {
+               if(!OP_get_float_array(op, name, rarray, &rlen))
+                       OP_set_float_array(op, name, array, len);
+       }
+}
+
index 23fbba7a054c356401ede0214f29dfb6efe544f4..b0789ba08ed06afc3a7377449038184a8d8c3a96 100644 (file)
@@ -163,7 +163,7 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct)
        win->curswin= swin= MEM_callocN(sizeof(wmSubWindow), "swinopen");
        BLI_addtail(&win->subwindows, swin);
        
-       printf("swin %d added\n", freewinid);
+       if(G.f & G_DEBUG) printf("swin %d added\n", freewinid);
        swin->swinid= freewinid;
        swin->winrct= *winrct;
 
index 214d10a41091e4f8e21e6a17bbb30a2ffb67135a..dd481cef1c01012896b82a9eb50b86d09e00c154 100644 (file)
@@ -161,11 +161,10 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
 /* operator callback */
 int wm_window_duplicate_op(bContext *C, wmOperator *op)
 {
-       
        wm_window_copy(C, C->window);
        wm_check(C);
        
-       return 1;
+       return OPERATOR_FINISHED;
 }
 
 /* fullscreen operator callback */
@@ -177,7 +176,7 @@ int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op)
        else
                GHOST_SetWindowState(C->window->ghostwin, GHOST_kWindowStateNormal);
 
-       return 1;
+       return OPERATOR_FINISHED;
        
 }
 
@@ -186,7 +185,7 @@ static void wm_window_close(bContext *C, wmWindow *win)
 {
        BLI_remlink(&C->wm->windows, win);
        wm_window_free(C, win);
-       
+
        if(C->wm->windows.first==NULL)
                WM_exit(C);
 }
@@ -200,7 +199,7 @@ int wm_exit_blender_op(bContext *C, wmOperator *op)
                win= win->next;
        }
 
-       return 1;
+       return OPERATOR_FINISHED;
 }
 
 static void wm_window_open(wmWindowManager *wm, char *title, wmWindow *win)
@@ -316,13 +315,11 @@ static int query_qual(char qual)
 
 void wm_window_make_drawable(bContext *C, wmWindow *win) 
 {
-       if (win != C->window && win->ghostwin) {
+       if (win != C->wm->windrawable && win->ghostwin) {
 //             win->lmbut= 0;  /* keeps hanging when mousepressed while other window opened */
                
                C->wm->windrawable= win;
-               C->window= win;
-               C->screen= win->screen;
-               printf("set drawable %d\n", win->winid);
+               if(G.f & G_DEBUG) printf("set drawable %d\n", win->winid);
                GHOST_ActivateWindowDrawingContext(win->ghostwin);
        }
 }
@@ -363,7 +360,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                GHOST_TEventKeyData kdata;
                                int cx, cy, wx, wy;
                                
-                               C->wm->winactive= win; /* no context change! c->window is drawable, or for area queues */
+                               C->wm->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */
                                
                                win->active= 1;
 //                             window_handle(win, INPUTCHANGE, win->active);
@@ -404,7 +401,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                break;
                        }
                        case GHOST_kEventWindowUpdate: {
-                               printf("ghost redraw\n");
+                               if(G.f & G_DEBUG) printf("ghost redraw\n");
                                
                                wm_window_make_drawable(C, win);
                                WM_event_add_notifier(C->wm, win, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
@@ -432,17 +429,22 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                        GHOST_TWindowState state;
                                        state = GHOST_GetWindowState(win->ghostwin);
 
-                                       if(state==GHOST_kWindowStateNormal)
-                                               printf("window state: normal\n");
-                                       else if(state==GHOST_kWindowStateMinimized)
-                                               printf("window state: minimized\n");
-                                       else if(state==GHOST_kWindowStateMaximized)
-                                               printf("window state: maximized\n");
-                                       else if(state==GHOST_kWindowStateFullScreen)
-                                               printf("window state: fullscreen\n");
+                                       if(state==GHOST_kWindowStateNormal) {
+                                               if(G.f & G_DEBUG) printf("window state: normal\n");
+                                       }
+                                       else if(state==GHOST_kWindowStateMinimized) {
+                                               if(G.f & G_DEBUG) printf("window state: minimized\n");
+                                       }
+                                       else if(state==GHOST_kWindowStateMaximized) {
+                                               if(G.f & G_DEBUG) printf("window state: maximized\n");
+                                       }
+                                       else if(state==GHOST_kWindowStateFullScreen) {
+                                               if(G.f & G_DEBUG) printf("window state: fullscreen\n");
+                                       }
                                        
-                                       if(type!=GHOST_kEventWindowSize)
-                                               printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey);
+                                       if(type!=GHOST_kEventWindowSize) {
+                                               if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey);
+                                       }
                                        
                                }
                                
index 8269dd48533450546b07f0d2cc41f5b65fb128fc..c381ac269d966a878d9d09cbf3b0830c101e3b75 100644 (file)
@@ -34,8 +34,9 @@ extern void wm_close_and_free_all(bContext *C, ListBase *);
 extern void wm_add_default(bContext *C);
 extern void wm_check(bContext *C);
                        
+void           wm_operator_free(wmOperator *op);
                        /* register to windowmanager for redo or macro */
-void           wm_operator_register(wmWindowManager *wm, wmOperator *ot);
+void           wm_operator_register(wmWindowManager *wm, wmOperator *op);
 
 /* wm_operator.c, for init/exit */
 void wm_operatortype_free(void);
index 93079deb63317d66ed7ab43898a884a8ebd0a643..b4d12d1358c9bf48b04867a36e5d14ce68c8ae15 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: wm_window.h
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -43,7 +43,7 @@ int           wm_subwindow_get(wmWindow *win);                                /* returns id */
 void   wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct);
 
 
-void   wm_subwindow_getsize(wmWindow *win, int *x, int *y) ;
+void   wm_subwindow_getsize(wmWindow *win, int *x, int *y);
 void   wm_subwindow_getorigin(wmWindow *win, int *x, int *y);