From a019f1d3d6a6f8bd17d4683e9a948a84a0ba9925 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 11 Jun 2008 10:10:31 +0000 Subject: 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. --- source/blender/blenkernel/BKE_global.h | 16 +- source/blender/blenkernel/BKE_screen.h | 30 +- source/blender/blenkernel/intern/screen.c | 5 + source/blender/editors/Makefile | 2 +- source/blender/editors/SConscript | 1 + source/blender/editors/include/BIF_view2d.h | 63 +++ source/blender/editors/include/ED_area.h | 9 +- source/blender/editors/include/ED_screen.h | 4 +- source/blender/editors/interface/SConscript | 4 +- source/blender/editors/interface/view2d.c | 252 +++++++++++ source/blender/editors/screen/area.c | 3 +- source/blender/editors/screen/screen_edit.c | 494 ++++++++++++--------- source/blender/editors/screen/screen_ops.c | 32 +- source/blender/editors/screen/spacetypes.c | 40 +- source/blender/editors/space_time/Makefile | 52 +++ source/blender/editors/space_time/SConscript | 9 + source/blender/editors/space_time/space_time.c | 263 +++++++++++ source/blender/editors/space_time/time_intern.h | 41 ++ source/blender/editors/space_time/time_ops.c | 185 ++++++++ source/blender/editors/space_view3d/space_view3d.c | 16 +- source/blender/makesdna/DNA_windowmanager_types.h | 40 +- source/blender/windowmanager/WM_api.h | 22 +- source/blender/windowmanager/intern/wm.c | 31 +- .../blender/windowmanager/intern/wm_event_system.c | 140 ++++-- source/blender/windowmanager/intern/wm_files.c | 2 +- source/blender/windowmanager/intern/wm_gesture.c | 1 - source/blender/windowmanager/intern/wm_operators.c | 228 +++++++--- source/blender/windowmanager/intern/wm_subwindow.c | 2 +- source/blender/windowmanager/intern/wm_window.c | 44 +- source/blender/windowmanager/wm.h | 3 +- source/blender/windowmanager/wm_subwindow.h | 4 +- 31 files changed, 1590 insertions(+), 448 deletions(-) create mode 100644 source/blender/editors/include/BIF_view2d.h create mode 100644 source/blender/editors/interface/view2d.c create mode 100644 source/blender/editors/space_time/Makefile create mode 100644 source/blender/editors/space_time/SConscript create mode 100644 source/blender/editors/space_time/space_time.c create mode 100644 source/blender/editors/space_time/time_intern.h create mode 100644 source/blender/editors/space_time/time_ops.c (limited to 'source/blender') 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 + +#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; acur.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.xwindow->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.xwindow->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.ywindow->sizey-1) { - v1->vec.y= origval + op->delta; + if((md->dir=='h') && v1->vec.y>0 && v1->vec.ywindow->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 +#include + +#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 + +#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); -- cgit v1.2.3