Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-06-11 14:10:31 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-06-11 14:10:31 +0400
commita019f1d3d6a6f8bd17d4683e9a948a84a0ba9925 (patch)
tree30aa6d88bceb23df15c05e287cbc00b39157f746 /source/blender
parent161d60debf9d9facb0169b677999eb7907346012 (diff)
2.5 Branch
========== * 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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_global.h16
-rw-r--r--source/blender/blenkernel/BKE_screen.h30
-rw-r--r--source/blender/blenkernel/intern/screen.c5
-rw-r--r--source/blender/editors/Makefile2
-rw-r--r--source/blender/editors/SConscript1
-rw-r--r--source/blender/editors/include/BIF_view2d.h63
-rw-r--r--source/blender/editors/include/ED_area.h9
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/interface/SConscript4
-rw-r--r--source/blender/editors/interface/view2d.c252
-rw-r--r--source/blender/editors/screen/area.c3
-rw-r--r--source/blender/editors/screen/screen_edit.c494
-rw-r--r--source/blender/editors/screen/screen_ops.c32
-rw-r--r--source/blender/editors/screen/spacetypes.c40
-rw-r--r--source/blender/editors/space_time/Makefile52
-rw-r--r--source/blender/editors/space_time/SConscript9
-rw-r--r--source/blender/editors/space_time/space_time.c263
-rw-r--r--source/blender/editors/space_time/time_intern.h41
-rw-r--r--source/blender/editors/space_time/time_ops.c185
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c16
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h40
-rw-r--r--source/blender/windowmanager/WM_api.h22
-rw-r--r--source/blender/windowmanager/intern/wm.c31
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c140
-rw-r--r--source/blender/windowmanager/intern/wm_files.c2
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c1
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c228
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c2
-rw-r--r--source/blender/windowmanager/intern/wm_window.c44
-rw-r--r--source/blender/windowmanager/wm.h3
-rw-r--r--source/blender/windowmanager/wm_subwindow.h4
31 files changed, 1590 insertions, 448 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index a78625fe662..f2929bd8d61 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -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 */
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 4c968eb0450..14090719de6 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index c5b30b26f74..b259138ee42 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -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);
diff --git a/source/blender/editors/Makefile b/source/blender/editors/Makefile
index dcd183688bf..3ea82ebe3b4 100644
--- a/source/blender/editors/Makefile
+++ b/source/blender/editors/Makefile
@@ -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
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index 46c63c4900b..113cc7a2d7b 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -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
index 00000000000..191826bb31b
--- /dev/null
+++ b/source/blender/editors/include/BIF_view2d.h
@@ -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 */
+
diff --git a/source/blender/editors/include/ED_area.h b/source/blender/editors/include/ED_area.h
index 2cb5b42e2cb..6666907c63d 100644
--- a/source/blender/editors/include/ED_area.h
+++ b/source/blender/editors/include/ED_area.h
@@ -25,20 +25,15 @@
*
* ***** 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 */
-
-
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index f9450e3717b..0adac2c9657 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -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);
diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript
index 5743674bfb2..6602bba014f 100644
--- a/source/blender/editors/interface/SConscript
+++ b/source/blender/editors/interface/SConscript
@@ -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
index 00000000000..139ba03bb03
--- /dev/null
+++ b/source/blender/editors/interface/view2d.c
@@ -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;
+ }
+}
+
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f67769fdd3d..fb72f47e7bf 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -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;
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index c20c5944665..b1ec306ba69 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -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;
}
+
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 503dd01b5d5..54f9593ea7b 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -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);
}
-
-
-
-
-
diff --git a/source/blender/editors/screen/spacetypes.c b/source/blender/editors/screen/spacetypes.c
index 88ac8de1f88..0292df8bc24 100644
--- a/source/blender/editors/screen/spacetypes.c
+++ b/source/blender/editors/screen/spacetypes.c
@@ -44,17 +44,35 @@
/* 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
index 00000000000..72dca174dba
--- /dev/null
+++ b/source/blender/editors/space_time/Makefile
@@ -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
index 00000000000..091218e0794
--- /dev/null
+++ b/source/blender/editors/space_time/SConscript
@@ -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
index 00000000000..f6557c5f14f
--- /dev/null
+++ b/source/blender/editors/space_time/space_time.c
@@ -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
index 00000000000..e7fb9af7906
--- /dev/null
+++ b/source/blender/editors/space_time/time_intern.h
@@ -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
index 00000000000..a02c5eb6844
--- /dev/null
+++ b/source/blender/editors/space_time/time_ops.c
@@ -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);
+}
+
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 9a08c7cd016..1abd860c661 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -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);
-
-
}
-
-
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 56fdc3e113c..788f9f71e56 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -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 */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 64abda4a849..6b020a07fb9 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -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 */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index bc24895874e..d40fd751162 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -47,24 +47,28 @@
#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);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index bb0ad54d967..af61b787462 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -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 *************** */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 8dbe235d256..70bdb60eb48 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -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);
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 283b269fdfc..02e4a0124c2 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -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);
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 88408869aba..8b4a167365d 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -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);
+ }
+}
+
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 23fbba7a054..b0789ba08ed 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -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;
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 214d10a4109..dd481cef1c0 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -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);
+ }
}
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 8269dd48533..c381ac269d9 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -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);
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
index 93079deb633..b4d12d1358c 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -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);