diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/Makefile | 2 | ||||
-rw-r--r-- | source/blender/editors/SConscript | 1 | ||||
-rw-r--r-- | source/blender/editors/include/BIF_view2d.h | 63 | ||||
-rw-r--r-- | source/blender/editors/include/ED_area.h | 9 | ||||
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 4 | ||||
-rw-r--r-- | source/blender/editors/interface/SConscript | 4 | ||||
-rw-r--r-- | source/blender/editors/interface/view2d.c | 252 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 3 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 494 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 32 | ||||
-rw-r--r-- | source/blender/editors/screen/spacetypes.c | 40 | ||||
-rw-r--r-- | source/blender/editors/space_time/Makefile | 52 | ||||
-rw-r--r-- | source/blender/editors/space_time/SConscript | 9 | ||||
-rw-r--r-- | source/blender/editors/space_time/space_time.c | 263 | ||||
-rw-r--r-- | source/blender/editors/space_time/time_intern.h | 41 | ||||
-rw-r--r-- | source/blender/editors/space_time/time_ops.c | 185 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 16 |
17 files changed, 1219 insertions, 251 deletions
diff --git a/source/blender/editors/Makefile b/source/blender/editors/Makefile index dcd183688bf..3ea82ebe3b4 100644 --- a/source/blender/editors/Makefile +++ b/source/blender/editors/Makefile @@ -29,6 +29,6 @@ # Bounces make to subdirectories. SOURCEDIR = source/blender/editors -DIRS = datafiles screen space_view3d interface +DIRS = datafiles screen space_time space_view3d interface include nan_subdirs.mk diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index 46c63c4900b..113cc7a2d7b 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -6,6 +6,7 @@ SConscript(['datafiles/SConscript', 'interface/SConscript', 'mesh/SConscript', 'object/SConscript', + 'space_time/SConscript', 'space_view3d/SConscript', 'transform/SConscript', 'screen/SConscript']) diff --git a/source/blender/editors/include/BIF_view2d.h b/source/blender/editors/include/BIF_view2d.h new file mode 100644 index 00000000000..191826bb31b --- /dev/null +++ b/source/blender/editors/include/BIF_view2d.h @@ -0,0 +1,63 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BIF_VIEW2D_H +#define BIF_VIEW2D_H + +/* start of a generic 2d view with should allow drawing grids, + * panning, zooming, scrolling, .. */ + +#define V2D_UNIT_SECONDS 0 +#define V2D_UNIT_FRAMES 1 + +#define V2D_GRID_CLAMP 0 +#define V2D_GRID_NOCLAMP 1 + +#define V2D_IS_CLIPPED 12000 + +#define V2D_HORIZONTAL_LINES 1 +#define V2D_VERTICAL_LINES 2 +#define V2D_HORIZONTAL_AXIS 4 +#define V2D_VERTICAL_AXIS 8 + +struct View2D; +struct bContext; + +void BIF_view2d_ortho(const struct bContext *C, struct View2D *v2d); + +/* grid drawing */ +void BIF_view2d_calc_grid(const struct bContext *C, struct View2D *v2d, int unit, int type, int winx, int winy); +void BIF_view2d_draw_grid(const struct bContext *C, struct View2D *v2d, int flag); + +/* coordinate conversion */ +void BIF_view2d_region_to_view(struct View2D *v2d, short x, short y, float *viewx, float *viewy); +void BIF_view2d_view_to_region(struct View2D *v2d, float x, float y, short *regionx, short *regiony); +void BIF_view2d_to_region_no_clip(struct View2D *v2d, float x, float y, short *regionx, short *region_y); + +#endif /* BIF_VIEW2D_H */ + diff --git a/source/blender/editors/include/ED_area.h b/source/blender/editors/include/ED_area.h index 2cb5b42e2cb..6666907c63d 100644 --- a/source/blender/editors/include/ED_area.h +++ b/source/blender/editors/include/ED_area.h @@ -25,20 +25,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ + #ifndef ED_AREA_H #define ED_AREA_H /* the pluginnable API for export to editors */ - /* calls for registering default spaces */ +void ED_spacetype_time(void); void ED_spacetype_view3d(void); -/* calls for registering operator types */ -void ED_operatortypes_screen(void); - - #endif /* ED_AREA_H */ - - diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index f9450e3717b..0adac2c9657 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -44,6 +44,7 @@ void ED_region_do_refresh(struct bContext *C, ARegion *ar); /* spaces */ void ED_spacetypes_init(void); +void ED_spacetypes_keymap(struct wmWindowManager *wm); /* areas */ void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa); @@ -57,7 +58,8 @@ void ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note); bScreen *ED_screen_duplicate(struct wmWindow *win, bScreen *sc); void ED_screen_set_subwinactive(struct wmWindow *win); -void ed_screen_keymap(struct wmWindowManager *wm); +void ED_operatortypes_screen(void); +void ED_keymap_screen(struct wmWindowManager *wm); /* operators; context poll callbacks */ int ED_operator_screenactive(bContext *C); diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript index 5743674bfb2..6602bba014f 100644 --- a/source/blender/editors/interface/SConscript +++ b/source/blender/editors/interface/SConscript @@ -4,6 +4,6 @@ Import ('env') sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' -incs += ' #/intern/guardedalloc' +incs += ' ../../windowmanager #/intern/guardedalloc' -env.BlenderLib ( 'bf_editors_interface', sources, Split(incs), [], libtype=['core','intern'], priority=[15, 30] ) +env.BlenderLib ( 'bf_editors_interface', sources, Split(incs), [], libtype=['core','intern'], priority=[40, 45] ) diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c new file mode 100644 index 00000000000..139ba03bb03 --- /dev/null +++ b/source/blender/editors/interface/view2d.c @@ -0,0 +1,252 @@ + +#include <math.h> + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view2d_types.h" + +#include "BKE_global.h" + +#include "WM_api.h" + +#include "BIF_gl.h" +#include "BIF_resources.h" +#include "BIF_view2d.h" + +/* minimum pixels per gridstep */ +#define IPOSTEP 35 + +static float ipogrid_dx, ipogrid_dy, ipogrid_startx, ipogrid_starty; +static int ipomachtx, ipomachty; + +static int vertymin, vertymax, horxmin, horxmax; /* globals to test LEFTMOUSE for scrollbar */ + +void BIF_view2d_ortho(const bContext *C, View2D *v2d) +{ + wmOrtho2(C->window, v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax); +} + +static void step_to_grid(float *step, int *macht, int unit) +{ + float loga, rem; + + /* try to write step as a power of 10 */ + + loga= log10(*step); + *macht= (int)(loga); + + rem= loga- *macht; + rem= pow(10.0, rem); + + if(loga<0.0) { + if(rem < 0.2) rem= 0.2; + else if(rem < 0.5) rem= 0.5; + else rem= 1.0; + + *step= rem*pow(10.0, (float)*macht); + + if(unit == V2D_UNIT_FRAMES) { + rem = 1.0; + *step = 1.0; + } + + if(rem==1.0) (*macht)++; // prevents printing 1.0 2.0 3.0 etc + } + else { + if(rem < 2.0) rem= 2.0; + else if(rem < 5.0) rem= 5.0; + else rem= 10.0; + + *step= rem*pow(10.0, (float)*macht); + + (*macht)++; + if(rem==10.0) (*macht)++; // prevents printing 1.0 2.0 3.0 etc + } +} + +void BIF_view2d_calc_grid(const bContext *C, View2D *v2d, int unit, int clamp, int winx, int winy) +{ + float space, pixels, seconddiv; + int secondgrid; + + /* rule: gridstep is minimal IPOSTEP pixels */ + /* how large is IPOSTEP pixels? */ + + if(unit == V2D_UNIT_FRAMES) { + secondgrid= 0; + seconddiv= 0.01f * FPS; + } + else { + secondgrid= 1; + seconddiv= 1.0f; + } + + space= v2d->cur.xmax - v2d->cur.xmin; + pixels= v2d->mask.xmax - v2d->mask.xmin; + + ipogrid_dx= IPOSTEP*space/(seconddiv*pixels); + step_to_grid(&ipogrid_dx, &ipomachtx, unit); + ipogrid_dx*= seconddiv; + + if(clamp == V2D_GRID_CLAMP) { + if(ipogrid_dx < 0.1) ipogrid_dx= 0.1; + ipomachtx-= 2; + if(ipomachtx<-2) ipomachtx= -2; + } + + space= (v2d->cur.ymax - v2d->cur.ymin); + pixels= winy; + ipogrid_dy= IPOSTEP*space/pixels; + step_to_grid(&ipogrid_dy, &ipomachty, unit); + + if(clamp == V2D_GRID_CLAMP) { + if(ipogrid_dy < 1.0) ipogrid_dy= 1.0; + if(ipomachty<1) ipomachty= 1; + } + + ipogrid_startx= seconddiv*(v2d->cur.xmin/seconddiv - fmod(v2d->cur.xmin/seconddiv, ipogrid_dx/seconddiv)); + if(v2d->cur.xmin<0.0) ipogrid_startx-= ipogrid_dx; + + ipogrid_starty= (v2d->cur.ymin-fmod(v2d->cur.ymin, ipogrid_dy)); + if(v2d->cur.ymin<0.0) ipogrid_starty-= ipogrid_dy; +} + +void BIF_view2d_draw_grid(const bContext *C, View2D *v2d, int flag) +{ + float vec1[2], vec2[2]; + int a, step; + + if(flag & V2D_VERTICAL_LINES) { + /* vertical lines */ + vec1[0]= vec2[0]= ipogrid_startx; + vec1[1]= ipogrid_starty; + vec2[1]= v2d->cur.ymax; + + step= (v2d->mask.xmax - v2d->mask.xmin+1)/IPOSTEP; + + BIF_ThemeColor(TH_GRID); + + for(a=0; a<step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[0]= vec1[0]+= ipogrid_dx; + } + + vec2[0]= vec1[0]-= 0.5*ipogrid_dx; + + BIF_ThemeColorShade(TH_GRID, 16); + + step++; + for(a=0; a<=step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[0]= vec1[0]-= ipogrid_dx; + } + } + + if(flag & V2D_HORIZONTAL_LINES) { + /* horizontal lines */ + vec1[0]= ipogrid_startx; + vec1[1]= vec2[1]= ipogrid_starty; + vec2[0]= v2d->cur.xmax; + + step= (C->area->winy+1)/IPOSTEP; + + BIF_ThemeColor(TH_GRID); + for(a=0; a<=step; a++) { + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + vec2[1]= vec1[1]+= ipogrid_dy; + } + vec2[1]= vec1[1]-= 0.5*ipogrid_dy; + step++; + } + + BIF_ThemeColorShade(TH_GRID, -50); + + if(flag & V2D_HORIZONTAL_AXIS) { + /* horizontal axis */ + vec1[0]= v2d->cur.xmin; + vec2[0]= v2d->cur.xmax; + vec1[1]= vec2[1]= 0.0; + glBegin(GL_LINE_STRIP); + + glVertex2fv(vec1); + glVertex2fv(vec2); + + glEnd(); + } + + if(flag & V2D_VERTICAL_AXIS) { + /* vertical axis */ + vec1[1]= v2d->cur.ymin; + vec2[1]= v2d->cur.ymax; + vec1[0]= vec2[0]= 0.0; + glBegin(GL_LINE_STRIP); + glVertex2fv(vec1); glVertex2fv(vec2); + glEnd(); + } +} + +void BIF_view2d_region_to_view(View2D *v2d, short x, short y, float *viewx, float *viewy) +{ + float div, ofs; + + if(viewx) { + div= v2d->mask.xmax-v2d->mask.xmin; + ofs= v2d->mask.xmin; + + *viewx= v2d->cur.xmin+ (v2d->cur.xmax-v2d->cur.xmin)*(x-ofs)/div; + } + + if(viewy) { + div= v2d->mask.ymax-v2d->mask.ymin; + ofs= v2d->mask.ymin; + + *viewy= v2d->cur.ymin+ (v2d->cur.ymax-v2d->cur.ymin)*(y-ofs)/div; + } +} + +void BIF_view2d_view_to_region(View2D *v2d, float x, float y, short *regionx, short *regiony) +{ + *regionx= V2D_IS_CLIPPED; + *regiony= V2D_IS_CLIPPED; + + x= (x - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin); + y= (x - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin); + + if(x>=0.0 && x<=1.0) { + if(y>=0.0 && y<=1.0) { + if(regionx) + *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin); + if(regiony) + *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin); + } + } +} + +void BIF_view2d_to_region_no_clip(View2D *v2d, float x, float y, short *regionx, short *regiony) +{ + x= (x - v2d->cur.xmin)/(v2d->cur.xmax-v2d->cur.xmin); + y= (x - v2d->cur.ymin)/(v2d->cur.ymax-v2d->cur.ymin); + + x= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin); + y= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin); + + if(regionx) { + if(x<-32760) *regionx= -32760; + else if(x>32760) *regionx= 32760; + else *regionx= x; + } + + if(regiony) { + if(y<-32760) *regiony= -32760; + else if(y>32760) *regiony= 32760; + else *regiony= y; + } +} + diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f67769fdd3d..fb72f47e7bf 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -264,7 +264,6 @@ static void area_calc_totrct(ScrArea *sa, int sizex, int sizey) void area_azone_initialize(ScrArea *sa) { AZone *az; if(sa->actionzones.first==NULL) { - printf("area_azone_initialize\n"); /* set action zones - should these actually be ARegions? With these we can easier check area hotzones */ az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); BLI_addtail(&(sa->actionzones), az); @@ -367,7 +366,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) /* regiontype callback, it should create/verify the amount of subregions with minsizes etc */ if(sa->type->init) - sa->type->init(sa); + sa->type->init(wm, sa); /* region rect sizes */ rect= sa->totrct; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index c20c5944665..b1ec306ba69 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1018,13 +1018,13 @@ void ED_screen_draw(wmWindow *win) scrarea_draw_shape_dark(sa2, dir); scrarea_draw_shape_light(sa1, dira); } - printf("draw screen\n"); + if(G.f & G_DEBUG) printf("draw screen\n"); win->screen->do_draw= 0; } void ED_screen_gesture(wmWindow *win) { - printf("gesture draw screen\n"); + if(G.f & G_DEBUG) printf("gesture draw screen\n"); if(win->gesture.first) { ed_gesture_update(win); @@ -1052,7 +1052,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) ED_area_initialize(wm, win, sa); } - printf("set screen\n"); + if(G.f & G_DEBUG) printf("set screen\n"); win->screen->do_refresh= 0; } @@ -1126,108 +1126,125 @@ int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event) else WM_set_cursor(C, CURSOR_STD); } - return 1; + return OPERATOR_PASS_THROUGH; } -/* ************** move area edge operator ********************************************** */ +/* ************** move area edge operator *********************************** */ /* operator state vars used: - op->veci mouse coord near edge - op->delta movement of edge + x, y mouse coord near edge + delta movement of edge + + internal: + + init() set default property values, find edge based on mouse coords, test + if the edge can be moved, select edges, calculate min and max movement + + apply() apply delta on selection + + exit() cleanup, send notifier callbacks: - init() find edge based on op->veci, test if the edge can be moved, select edges, - clear delta, calculate min and max movement + exec() execute without any user interaction, based on properties + call init(), apply(), exit() - exec() apply op->delta on selection - - invoke() handler gets called on a mouse click near edge - call init() - add handler + invoke() gets called on mouse click near edge + call init(), add handler - modal() accept modal events while doing it - call exec() with delta motion + modal() accept modal events while doing it + call apply() with delta motion call exit() and remove handler - exit() cleanup, send notifier + cancel() cancel moving */ +typedef struct sAreaMoveData { + int bigger, smaller, origval; + char dir; +} sAreaMoveData; + /* validate selection inside screen, set variables OK */ /* return 0: init failed */ static int move_areas_init (bContext *C, wmOperator *op) { - ScrEdge *actedge= screen_find_active_scredge(C->screen, op->veci.x, op->veci.y); + ScrEdge *actedge; ScrArea *sa; - int bigger, smaller, dir, origval; - + sAreaMoveData *md; + int x, y; + + /* required properties */ + if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y))) + return 0; + + /* default properties */ + OP_verify_int(op, "delta", 0, NULL); + + /* setup */ + actedge= screen_find_active_scredge(C->screen, x, y); if(actedge==NULL) return 0; - - dir= scredge_is_horizontal(actedge)?'h':'v'; - if(dir=='h') origval= actedge->v1->vec.y; - else origval= actedge->v1->vec.x; + + md= MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData"); + op->customdata= md; + + md->dir= scredge_is_horizontal(actedge)?'h':'v'; + if(md->dir=='h') md->origval= actedge->v1->vec.y; + else md->origval= actedge->v1->vec.x; select_connected_scredge(C->screen, actedge); /* now all verices with 'flag==1' are the ones that can be moved. */ /* we check all areas and test for free space with MINSIZE */ - bigger= smaller= 10000; + md->bigger= md->smaller= 10000; for(sa= C->screen->areabase.first; sa; sa= sa->next) { - if(dir=='h') { /* if top or down edge selected, test height */ + if(md->dir=='h') { /* if top or down edge selected, test height */ if(sa->v1->flag && sa->v4->flag) { int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY; - bigger= MIN2(bigger, y1); + md->bigger= MIN2(md->bigger, y1); } else if(sa->v2->flag && sa->v3->flag) { int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY; - smaller= MIN2(smaller, y1); + md->smaller= MIN2(md->smaller, y1); } } else { /* if left or right edge selected, test width */ if(sa->v1->flag && sa->v2->flag) { int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX; - bigger= MIN2(bigger, x1); + md->bigger= MIN2(md->bigger, x1); } else if(sa->v3->flag && sa->v4->flag) { int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX; - smaller= MIN2(smaller, x1); + md->smaller= MIN2(md->smaller, x1); } } } - OP_set_int(op, "bigger", bigger); - OP_set_int(op, "smaller", smaller); - OP_set_int(op, "dir", dir); - OP_set_int(op, "origval", origval); - return 1; } /* moves selected screen edge amount of delta */ /* needs init call to work */ -static int move_areas_exec(bContext *C, wmOperator *op) +static void move_areas_apply(bContext *C, wmOperator *op) { ScrVert *v1; - int bigger, smaller, dir, origval; + int delta; + sAreaMoveData *md= op->customdata; - OP_get_int(op, "bigger", &bigger); - OP_get_int(op, "smaller", &smaller); - OP_get_int(op, "dir", &dir); - OP_get_int(op, "origval", &origval); + OP_get_int(op, "delta", &delta); - op->delta= CLAMPIS(op->delta, -smaller, bigger); + delta= CLAMPIS(delta, -md->smaller, md->bigger); for (v1= C->screen->vertbase.first; v1; v1= v1->next) { if (v1->flag) { /* that way a nice AREAGRID */ - if((dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) { - v1->vec.x= origval + op->delta; - if(op->delta != bigger && op->delta != -smaller) v1->vec.x-= (v1->vec.x % AREAGRID); + if((md->dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) { + v1->vec.x= md->origval + delta; + if(delta != md->bigger && delta != -md->smaller) v1->vec.x-= (v1->vec.x % AREAGRID); } - if((dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) { - v1->vec.y= origval + op->delta; + if((md->dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) { + v1->vec.y= md->origval + delta; v1->vec.y+= AREAGRID-1; v1->vec.y-= (v1->vec.y % AREAGRID); @@ -1238,93 +1255,102 @@ static int move_areas_exec(bContext *C, wmOperator *op) } } } - return 1; + + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); } -static int move_areas_exit(bContext *C, wmOperator *op) +static void move_areas_exit(bContext *C, wmOperator *op) { - WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); + if(op->customdata) + MEM_freeN(op->customdata); /* this makes sure aligned edges will result in aligned grabbing */ removedouble_scrverts(C->screen); removedouble_scredges(C->screen); - - OP_free_property(op); - return 1; } -/* interaction callback */ -/* return 0 = stop evaluating for next handlers */ -static int move_areas_invoke (bContext *C, wmOperator *op, wmEvent *event) +static int move_areas_exec(bContext *C, wmOperator *op) { + if(!move_areas_init(C, op)) + return OPERATOR_CANCELLED; - /* operator arguments and storage */ - op->properties = NULL; - op->delta= 0; - op->veci.x= event->x; - op->veci.y= event->y; + move_areas_apply(C, op); + move_areas_exit(C, op); - if(0==move_areas_init(C, op)) - return 1; + return OPERATOR_FINISHED; +} + +/* interaction callback */ +static int move_areas_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + OP_verify_int(op, "x", event->x, NULL); + OP_verify_int(op, "y", event->y, NULL); + + if(!move_areas_init(C, op)) + return OPERATOR_PASS_THROUGH; /* add temp handler */ WM_event_add_modal_handler(&C->window->handlers, op); - return 0; + return OPERATOR_RUNNING_MODAL; +} + +static int move_areas_cancel(bContext *C, wmOperator *op) +{ + WM_event_remove_modal_handler(&C->window->handlers, op); + + OP_set_int(op, "delta", 0); + move_areas_apply(C, op); + move_areas_exit(C, op); + + return OPERATOR_CANCELLED; } /* modal callback for while moving edges */ -/* return 0 = stop evaluating for next handlers */ -static int move_areas_modal (bContext *C, wmOperator *op, wmEvent *event) +static int move_areas_modal(bContext *C, wmOperator *op, wmEvent *event) { - int dir; + sAreaMoveData *md; + int delta, x, y; - OP_get_int(op, "dir", &dir); + md= op->customdata; + + OP_get_int(op, "x", &x); + OP_get_int(op, "y", &y); /* execute the events */ switch(event->type) { case MOUSEMOVE: - - if(dir=='v') - op->delta= event->x - op->veci.x; - else - op->delta= event->y - op->veci.y; - - move_areas_exec(C, op); - WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); + delta= (md->dir == 'v')? event->x - x: event->y - y; + OP_set_int(op, "delta", delta); + + move_areas_apply(C, op); break; case LEFTMOUSE: if(event->val==0) { move_areas_exit(C, op); WM_event_remove_modal_handler(&C->window->handlers, op); + return OPERATOR_FINISHED; } break; case ESCKEY: - op->delta= 0; - move_areas_exec(C, op); - - WM_event_remove_modal_handler(&C->window->handlers, op); - move_areas_exit(C, op); - break; + return move_areas_cancel(C, op); } - return 1; + return OPERATOR_RUNNING_MODAL; } void ED_SCR_OT_move_areas(wmOperatorType *ot) { - /* identifiers */ ot->name= "Move area edges"; ot->idname= "ED_SCR_OT_move_areas"; - ot->init= move_areas_init; + ot->exec= move_areas_exec; ot->invoke= move_areas_invoke; + ot->cancel= move_areas_cancel; ot->modal= move_areas_modal; - ot->exec= move_areas_exec; - ot->exit= move_areas_exit; ot->poll= ED_operator_screen_mainwinactive; } @@ -1353,26 +1379,60 @@ typedef struct sAreaSplitData ScrArea *narea; /* new area */ } sAreaSplitData; +static int split_area_init(bContext *C, wmOperator *op) +{ + AZone *az= NULL; + ScrArea *sa= NULL; + sAreaSplitData *sd= NULL; + int x, y; + + /* required properties */ + if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y))) + return 0; + + OP_verify_int(op, "delta", 0, NULL); + OP_verify_int(op, "dir", 0, NULL); + + for(sa= C->screen->areabase.first; sa; sa= sa->next) { + az= is_in_area_actionzone(sa, x, y); + if(az!=NULL) break; + } + + if(az==NULL) return 0; + + sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_split_area"); + op->customdata= sd; + + sd->state= SPLIT_STARTED; + sd->deltax= 0; + sd->deltay= 0; + + return 1; +} + /* the moving of the new egde */ -static int split_area_exec(bContext *C, wmOperator *op) +static void split_area_apply(bContext *C, wmOperator *op) { sAreaSplitData *sd= (sAreaSplitData *)op->customdata; - int newval= sd->origval + op->delta; - + int newval, delta, dir; + + OP_get_int(op, "delta", &delta); + OP_get_int(op, "dir", &dir); + + newval= sd->origval + delta; newval= CLAMPIS(newval, -sd->min, sd->max); - if((sd->dir=='v') && (newval > sd->min && newval < sd->max-1)) { + if((dir=='v') && (newval > sd->min && newval < sd->max-1)) { sd->nedge->v1->vec.x= newval; sd->nedge->v2->vec.x= newval; } - if((sd->dir=='h') && (newval > sd->min+HEADERY && newval < sd->max-HEADERY)) { + if((dir=='h') && (newval > sd->min+HEADERY && newval < sd->max-HEADERY)) { sd->nedge->v1->vec.y= newval; sd->nedge->v2->vec.y= newval; } - return 1; } -static int split_area_exit(bContext *C, wmOperator *op) +static void split_area_exit(bContext *C, wmOperator *op) { if (op->customdata) { MEM_freeN(op->customdata); @@ -1384,27 +1444,29 @@ static int split_area_exit(bContext *C, wmOperator *op) /* this makes sure aligned edges will result in aligned grabbing */ removedouble_scrverts(C->screen); removedouble_scredges(C->screen); - - return 1; } -static int split_initintern(bContext *C, wmOperator *op, sAreaSplitData *sd) +static int split_area_init_intern(bContext *C, wmOperator *op, sAreaSplitData *sd) { float fac= 0.0; - if(sd->dir=='h') { - sd->origval= op->veci.y; - fac= 1.0 - ((float)(sd->sarea->v3->vec.y - op->veci.y)) / (float)sd->sarea->winy; + int dir; + + OP_get_int(op, "dir", &dir); + + if(dir=='h') { + OP_get_int(op, "y", &sd->origval); + fac= 1.0 - ((float)(sd->sarea->v3->vec.y - sd->origval)) / (float)sd->sarea->winy; sd->min= sd->aedge->v1->vec.y; sd->max= sd->aedge->v2->vec.y; } else { - sd->origval= op->veci.x; - fac= 1.0 - ((float)(sd->sarea->v4->vec.x - op->veci.x)) / (float)sd->sarea->winx; + OP_get_int(op, "x", &sd->origval); + fac= 1.0 - ((float)(sd->sarea->v4->vec.x - sd->origval)) / (float)sd->sarea->winx; sd->min= sd->aedge->v1->vec.x; sd->max= sd->aedge->v2->vec.x; } - sd->narea= splitarea(C->window, C->screen, sd->sarea, sd->dir, fac); + sd->narea= splitarea(C->window, C->screen, sd->sarea, dir, fac); if(sd->narea==NULL) return 0; @@ -1418,46 +1480,32 @@ static int split_initintern(bContext *C, wmOperator *op, sAreaSplitData *sd) return 1; } -static int split_area_init (bContext *C, wmOperator *op) +static int split_area_exec(bContext *C, wmOperator *op) { - AZone *az= NULL; - ScrArea *sa= NULL; - sAreaSplitData *sd= NULL; - - for(sa= C->screen->areabase.first; sa; sa= sa->next) { - az= is_in_area_actionzone(sa, op->veci.x, op->veci.y); - if(az!=NULL) break; - } + /* XXX: this does nothing, part of the code should be moved + * out of modal() */ - if(az==NULL) return 0; + if(!split_area_init(C, op)) + return OPERATOR_CANCELLED; - sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_split_area"); - op->customdata= sd; + split_area_apply(C, op); + split_area_exit(C, op); - sd->state= SPLIT_STARTED; - sd->deltax= 0; - sd->deltay= 0; - - return 1; + return OPERATOR_FINISHED; } static int split_area_invoke(bContext *C, wmOperator *op, wmEvent *event) { - /* operator arguments and storage */ - op->customdata= NULL; - op->delta= 0; - op->veci.x= event->x; - op->veci.y= event->y; + OP_verify_int(op, "x", event->x, NULL); + OP_verify_int(op, "y", event->y, NULL); - op->customdata= NULL; - - if(0==split_area_init(C, op)) - return 1; + if(!split_area_init(C, op)) + return OPERATOR_PASS_THROUGH; /* add temp handler */ WM_event_add_modal_handler(&C->window->handlers, op); - return 0; + return OPERATOR_RUNNING_MODAL; } /* join areas */ @@ -1490,8 +1538,8 @@ static void split_joincurrent(bContext *C, sAreaSplitData *sd) screen_addedge(C->screen, sd->sarea->v3, sd->sarea->v4); } - if (C->curarea == sd->narea) { - C->curarea = NULL; + if (C->area == sd->narea) { + C->area = NULL; } screen_delarea(C->screen, sd->narea); sd->narea = NULL; @@ -1500,10 +1548,28 @@ static void split_joincurrent(bContext *C, sAreaSplitData *sd) } } +static int split_area_cancel(bContext *C, wmOperator *op) +{ + sAreaSplitData *sd= (sAreaSplitData *)op->customdata; + + WM_event_remove_modal_handler(&C->window->handlers, op); + + OP_set_int(op, "delta", 0); + split_joincurrent(C, sd); + split_area_exit(C, op); + + return OPERATOR_CANCELLED; +} + static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event) { ScrArea *sa= NULL, *sold=NULL; sAreaSplitData *sd= (sAreaSplitData *)op->customdata; + int x, y, dir; + + OP_get_int(op, "x", &x); + OP_get_int(op, "y", &y); + OP_get_int(op, "dir", &dir); /* execute the events */ switch(event->type) { @@ -1515,19 +1581,19 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event) If one dir is delta threshold, and other dir is within "grey area" -> vert/hor split. If we get both over threshold -> subdiv. */ - sd->deltax= event->x - op->veci.x; - sd->deltay= event->y - op->veci.y; + sd->deltax= event->x - x; + sd->deltay= event->y - y; if(sd->deltax>10 && sd->deltay<4) { printf("split on v\n"); - sd->dir='v'; sd->state= SPLIT_PROGRESS; - op->delta= sd->deltax; + OP_set_int(op, "dir", 'v'); + OP_set_int(op, "delta", sd->deltax); } else if(sd->deltay>10 && sd->deltax<4) { printf("split on h\n"); - sd->dir='h'; sd->state= SPLIT_PROGRESS; - op->delta= sd->deltay; + OP_set_int(op, "dir", 'h'); + OP_set_int(op, "delta", sd->deltay); } } else if(sd->state==SPLIT_PROGRESS) { @@ -1539,7 +1605,7 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event) split_joincurrent(C, sd); /* now find aedge with same orientation as sd->dir (inverted) */ - if(sd->dir=='v') { + if(dir=='v') { sd->aedge= screen_findedge(C->screen, sa->v1, sa->v4); if(sd->aedge==NULL) sd->aedge= screen_findedge(C->screen, sa->v2, sa->v3); } @@ -1550,19 +1616,19 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event) /* set sd and op to new init state */ sd->sarea= sa; - op->delta= 0; - op->veci.x= event->x; - op->veci.y= event->y; - split_initintern(C, op, sd); + OP_set_int(op, "delta", 0); + OP_set_int(op, "x", event->x); + OP_set_int(op, "y", event->y); + split_area_init_intern(C, op, sd); } else { /* all is cool, update delta according complicated formula */ - if(sd->dir=='v') - op->delta= event->x - op->veci.x; + if(dir=='v') + OP_set_int(op, "delta", event->x - y); else - op->delta= event->y - op->veci.y; + OP_set_int(op, "delta", event->x - y); - split_area_exec(C, op); + split_area_apply(C, op); } } else if (sd->state==SPLIT_DONE) { /* shouldn't get here anymore */ @@ -1573,18 +1639,15 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event) if(event->val==0) { /* mouse up => confirm if not near/on starting edge */ split_area_exit(C, op); WM_event_remove_modal_handler(&C->window->handlers, op); + return OPERATOR_FINISHED; } break; case RIGHTMOUSE: /* cancel operation */ case ESCKEY: - op->delta= 0; - split_joincurrent(C, sd); - WM_event_remove_modal_handler(&C->window->handlers, op); - split_area_exit(C, op); - break; + return split_area_cancel(C, op); } - return 1; + return OPERATOR_RUNNING_MODAL; } void ED_SCR_OT_split_area(wmOperatorType *ot) @@ -1592,11 +1655,9 @@ void ED_SCR_OT_split_area(wmOperatorType *ot) ot->name = "Split area"; ot->idname = "ED_SCR_OT_split_area"; - ot->init= split_area_init; + ot->exec= split_area_exec; ot->invoke= split_area_invoke; ot->modal= split_area_modal; - ot->exec= split_area_exec; - ot->exit= split_area_exit; ot->poll= ED_operator_screenactive; } @@ -1604,8 +1665,8 @@ void ED_SCR_OT_split_area(wmOperatorType *ot) /* ************** join area operator ********************************************** */ /* operator state vars used: - op->veci mouse coord near edge - op->delta movement of edge + x, y mouse coord near edge + delta movement of edge callbacks: @@ -1613,6 +1674,9 @@ void ED_SCR_OT_split_area(wmOperatorType *ot) test if the edge divides two areas, store active and nonactive area, + apply() + + exit() cleanup, send notifier exec() remove active window, recalc size, @@ -1624,11 +1688,9 @@ void ED_SCR_OT_split_area(wmOperatorType *ot) add handler modal() accept modal events while doing it - call exec() with active window and nonactive window + call apply() with active window and nonactive window call exit() and remove handler when LMB confirm - exit() cleanup, send notifier - */ typedef struct sAreaJoinData @@ -1643,17 +1705,19 @@ typedef struct sAreaJoinData /* validate selection inside screen, set variables OK */ /* return 0: init failed */ -static int join_areas_init (bContext *C, wmOperator *op) +static int join_areas_init(bContext *C, wmOperator *op) { ScrArea *actarea = NULL; sAreaJoinData* jd= NULL; - - actarea = screen_areahascursor(C->screen, op->veci.x, op->veci.y); - if (actarea==NULL) - { + int x, y; + + if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y))) return 0; - } + actarea = screen_areahascursor(C->screen, x, y); + if(actarea==NULL) + return 0; + jd = (sAreaJoinData*)MEM_callocN(sizeof (sAreaJoinData), "op_join_areas"); jd->sa1 = actarea; @@ -1665,7 +1729,7 @@ static int join_areas_init (bContext *C, wmOperator *op) } /* apply the join of the areas (space types) */ -static int join_areas_exec(bContext *C, wmOperator *op) +static int join_areas_apply(bContext *C, wmOperator *op) { sAreaJoinData *jd = (sAreaJoinData *)op->customdata; if (!jd) return 0; @@ -1704,8 +1768,8 @@ static int join_areas_exec(bContext *C, wmOperator *op) screen_addedge(C->screen, jd->sa1->v3, jd->sa1->v4); } - if (C->curarea == jd->sa2) { - C->curarea = NULL; + if (C->area == jd->sa2) { + C->area = NULL; } screen_delarea(C->screen, jd->sa2); jd->sa2 = NULL; @@ -1714,24 +1778,6 @@ static int join_areas_exec(bContext *C, wmOperator *op) return 1; } -/* interaction callback */ -/* return 0 = stop evaluating for next handlers */ -static int join_areas_invoke (bContext *C, wmOperator *op, wmEvent *event) -{ - /* operator arguments and storage */ - op->delta= 0; - op->veci.x= event->x; - op->veci.y= event->y; - op->customdata = NULL; - printf("invoke \n"); - if(0==join_areas_init(C, op)) - return 1; - - /* add temp handler */ - WM_event_add_modal_handler(&C->window->handlers, op); - - return 0; -} static int is_inside_area(ScrArea *ar, short x, short y) { @@ -1746,7 +1792,7 @@ static int is_inside_area(ScrArea *ar, short x, short y) /* finish operation */ -static int join_areas_exit(bContext *C, wmOperator *op) +static void join_areas_exit(bContext *C, wmOperator *op) { if (op->customdata) { MEM_freeN(op->customdata); @@ -1757,13 +1803,57 @@ static int join_areas_exit(bContext *C, wmOperator *op) removedouble_scredges(C->screen); removenotused_scredges(C->screen); removenotused_scrverts(C->screen); - printf("exit \n"); - return 1; +} + +static int join_areas_exec(bContext *C, wmOperator *op) +{ + if(!join_areas_init(C, op)) + return OPERATOR_CANCELLED; + + join_areas_apply(C, op); + join_areas_exit(C, op); + + return OPERATOR_FINISHED; +} + +/* interaction callback */ +static int join_areas_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + OP_verify_int(op, "x", event->x, NULL); + OP_verify_int(op, "y", event->y, NULL); + + if(!join_areas_init(C, op)) + return OPERATOR_PASS_THROUGH; + + /* add temp handler */ + WM_event_add_modal_handler(&C->window->handlers, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int join_areas_cancel(bContext *C, wmOperator *op) +{ + sAreaJoinData *jd = (sAreaJoinData *)op->customdata; + + if (jd->sa1) { + jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; + jd->sa1->flag &= ~AREA_FLAG_DRAWJOINTO; + } + if (jd->sa2) { + jd->sa2->flag &= ~AREA_FLAG_DRAWJOINFROM; + jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; + } + + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL); + WM_event_remove_modal_handler(&C->window->handlers, op); + OP_set_int(op, "delta", 0); + join_areas_exit(C, op); + + return OPERATOR_CANCELLED; } /* modal callback while selecting area (space) that will be removed */ -/* return 0 = stop evaluating for next handlers */ -static int join_areas_modal (bContext *C, wmOperator *op, wmEvent *event) +static int join_areas_modal(bContext *C, wmOperator *op, wmEvent *event) { /* execute the events */ switch(event->type) { @@ -1831,36 +1921,34 @@ static int join_areas_modal (bContext *C, wmOperator *op, wmEvent *event) } case RIGHTMOUSE: if(event->val==0) { - join_areas_exec(C, op); + join_areas_apply(C, op); WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); join_areas_exit(C, op); WM_event_remove_modal_handler(&C->window->handlers, op); + return OPERATOR_FINISHED; } break; case ESCKEY: - op->delta= 0; - join_areas_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); - break; + return join_areas_cancel(C, op); } - return 1; + + return OPERATOR_RUNNING_MODAL; } /* Operator for joining two areas (space types) */ void ED_SCR_OT_join_areas(wmOperatorType *ot) { - /* identifiers */ ot->name= "Join area"; ot->idname= "ED_SCR_OT_join_areas"; /* api callbacks */ - ot->init= join_areas_init; + ot->exec= join_areas_exec; ot->invoke= join_areas_invoke; + ot->cancel= join_areas_cancel; ot->modal= join_areas_modal; - ot->exec= join_areas_exec; - ot->exit= join_areas_exit; ot->poll= ED_operator_screenactive; } + diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 503dd01b5d5..54f9593ea7b 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -42,8 +42,6 @@ #include "screen_intern.h" /* own module include */ -static ListBase local_ops; - /* ************** Poll tests ********************** */ int ED_operator_screenactive(bContext *C) @@ -69,31 +67,20 @@ static void ED_SCR_OT_cursor_type(wmOperatorType *ot) ot->idname= "ED_SCR_OT_cursor_type"; ot->invoke= screen_cursor_test; - ot->exec= NULL; ot->poll= ED_operator_screenactive; } -#define ADD_OPTYPE(opfunc) ot= MEM_callocN(sizeof(wmOperatorType), "operatortype"); \ - opfunc(ot); \ - BLI_addtail(&local_ops, ot) - - - -/* called via wm_init_exit.c ED_spacetypes_init() */ +/* called in spacetypes.c */ void ED_operatortypes_screen(void) { - wmOperatorType *ot; - - ADD_OPTYPE( ED_SCR_OT_move_areas ); - ADD_OPTYPE( ED_SCR_OT_cursor_type ); - ADD_OPTYPE( ED_SCR_OT_split_area ); - ADD_OPTYPE( ED_SCR_OT_join_areas ); - - WM_operatortypelist_append(&local_ops); + WM_operatortype_append(ED_SCR_OT_move_areas); + WM_operatortype_append(ED_SCR_OT_cursor_type); + WM_operatortype_append(ED_SCR_OT_split_area); + WM_operatortype_append(ED_SCR_OT_join_areas); } -/* called in wm.c */ -void ed_screen_keymap(wmWindowManager *wm) +/* called in spacetypes.c */ +void ED_keymap_screen(wmWindowManager *wm) { WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_cursor_type", MOUSEMOVE, 0, 0, 0); WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_move_areas", LEFTMOUSE, KM_PRESS, 0, 0); @@ -101,8 +88,3 @@ void ed_screen_keymap(wmWindowManager *wm) WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_join_areas", RIGHTMOUSE, KM_PRESS, KM_ALT, 0); } - - - - - diff --git a/source/blender/editors/screen/spacetypes.c b/source/blender/editors/screen/spacetypes.c index 88ac8de1f88..0292df8bc24 100644 --- a/source/blender/editors/screen/spacetypes.c +++ b/source/blender/editors/screen/spacetypes.c @@ -44,17 +44,35 @@ /* only call once on startup, storage is static data (no malloc!) in kernel listbase */ void ED_spacetypes_init(void) { + const ListBase *spacetypes; + SpaceType *type; + + /* create space types */ + ED_spacetype_time(); ED_spacetype_view3d(); // ED_spacetype_ipo(); // ... - + /* register operator types for screen and all spaces */ ED_operatortypes_screen(); -// ED_operatortypes_view3d(); -// ... - + + spacetypes = BKE_spacetypes_list(); + for(type=spacetypes->first; type; type=type->next) + type->operatortypes(); } +/* called in wm.c */ +void ED_spacetypes_keymap(wmWindowManager *wm) +{ + const ListBase *spacetypes; + SpaceType *type; + + ED_keymap_screen(wm); + + spacetypes = BKE_spacetypes_list(); + for(type=spacetypes->first; type; type=type->next) + type->keymap(wm); +} /* ****************************** space template *********************** */ @@ -71,7 +89,7 @@ static void xxx_free(SpaceLink *sl) } /* spacetype; init callback for usage, should be redoable */ -static void xxx_init(ScrArea *sa) +static void xxx_init(wmWindowManager *wm, ScrArea *sa) { /* link area to SpaceXXX struct */ @@ -93,6 +111,16 @@ static SpaceLink *xxx_duplicate(SpaceLink *sl) return NULL; } +static void xxx_operatortypes(void) +{ + /* register operator types for this space */ +} + +static void xxx_keymap(wmWindowManager *wm) +{ + /* add default items to keymap */ +} + /* only called once, from screen/spacetypes.c */ void ED_spacetype_xxx(void) { @@ -105,6 +133,8 @@ void ED_spacetype_xxx(void) st.init= xxx_init; st.refresh= xxx_refresh; st.duplicate= xxx_duplicate; + st.operatortypes= xxx_operatortypes; + st.keymap= xxx_keymap; BKE_spacetype_register(&st); } diff --git a/source/blender/editors/space_time/Makefile b/source/blender/editors/space_time/Makefile new file mode 100644 index 00000000000..72dca174dba --- /dev/null +++ b/source/blender/editors/space_time/Makefile @@ -0,0 +1,52 @@ +# +# $Id: Makefile 14 2002-10-13 15:57:19Z hans $ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2007 Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL LICENSE BLOCK ***** +# +# Makes module object directory and bounces make to subdirectories. + +LIBNAME = ed_time +DIR = $(OCGDIR)/blender/$(LIBNAME) + +include nan_compile.mk + +CFLAGS += $(LEVEL_1_C_WARNINGS) + +CPPFLAGS += -I$(OPENGL_HEADERS) + +# not very neat.... +CPPFLAGS += -I../../windowmanager +CPPFLAGS += -I../../blenloader +CPPFLAGS += -I../../blenkernel +CPPFLAGS += -I../../blenlib +CPPFLAGS += -I../../makesdna +CPPFLAGS += -I../../imbuf +CPPFLAGS += -I../../python +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include + +# own include + +CPPFLAGS += -I../include diff --git a/source/blender/editors/space_time/SConscript b/source/blender/editors/space_time/SConscript new file mode 100644 index 00000000000..091218e0794 --- /dev/null +++ b/source/blender/editors/space_time/SConscript @@ -0,0 +1,9 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') + +incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' +incs += '../../windowmanager #/intern/guardedalloc' + +env.BlenderLib ( 'bf_editors_space_time', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] ) diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c new file mode 100644 index 00000000000..f6557c5f14f --- /dev/null +++ b/source/blender/editors/space_time/space_time.c @@ -0,0 +1,263 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> +#include <stdio.h> + +#include "DNA_object_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "BKE_global.h" +#include "BKE_screen.h" + +#include "ED_area.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_resources.h" +#include "BIF_view2d.h" + +#include "time_intern.h" + +/* ************************ main time area region *********************** */ + +/* draws a current frame indicator for the TimeLine */ +static void time_draw_cfra_time(const bContext *C, SpaceTime *stime) +{ + Scene *scene= C->scene; + float vec[2]; + + vec[0]= scene->r.cfra; + vec[0]*= scene->r.framelen; + + vec[1]= stime->v2d.cur.ymin; + BIF_ThemeColor(TH_CFRAME); // no theme, should be global color once... + glLineWidth(3.0); + + glBegin(GL_LINES); + glVertex2fv(vec); + vec[1]= stime->v2d.cur.ymax; + glVertex2fv(vec); + glEnd(); + + glLineWidth(1.0); +} + +static void time_draw_sfra_efra(const bContext *C, SpaceTime *stime) +{ + /* draw darkened area outside of active timeline + * frame range used is preview range or scene range */ + BIF_ThemeColorShade(TH_BACK, -25); + + if (PSFRA < PEFRA) { + glRectf(stime->v2d.cur.xmin, stime->v2d.cur.ymin, PSFRA, stime->v2d.cur.ymax); + glRectf(PEFRA, stime->v2d.cur.ymin, stime->v2d.cur.xmax, stime->v2d.cur.ymax); + } + else { + glRectf(stime->v2d.cur.xmin, stime->v2d.cur.ymin, stime->v2d.cur.xmax, stime->v2d.cur.ymax); + } + + BIF_ThemeColorShade(TH_BACK, -60); + /* thin lines where the actual frames are */ + fdrawline(PSFRA, stime->v2d.cur.ymin, PSFRA, stime->v2d.cur.ymax); + fdrawline(PEFRA, stime->v2d.cur.ymin, PEFRA, stime->v2d.cur.ymax); +} + +static void time_main_area_init(const bContext *C, ARegion *ar) +{ + /* add handlers, stuff you only do once or on area/region changes */ +} + +static void time_main_area_refresh(const bContext *C, ARegion *ar) +{ + /* refresh to match contextual changes */ +} + +static void time_main_area_draw(const bContext *C, ARegion *ar) +{ + /* draw entirely, windowsize changes should be handled here */ + SpaceTime *stime= C->area->spacedata.first; + float col[3]; + int unit, winx, winy; + + winx= ar->winrct.xmax-ar->winrct.xmin; + winy= ar->winrct.ymax-ar->winrct.ymin; + + /* clear and setup matrix */ + BIF_GetThemeColor3fv(TH_BACK, col); + col[0]= 1.0f; + col[1]= 0.8f; + col[2]= 0.0f; + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + BIF_view2d_ortho(C, &stime->v2d); + + /* start and end frame */ + time_draw_sfra_efra(C, stime); + + /* grid */ + unit= (stime->flag & TIME_DRAWFRAMES)? V2D_UNIT_FRAMES: V2D_UNIT_SECONDS; + BIF_view2d_calc_grid(C, &stime->v2d, unit, V2D_GRID_CLAMP, winx, winy); + BIF_view2d_draw_grid(C, &stime->v2d, V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS); + + /* current frame */ + time_draw_cfra_time(C, stime); +} + +static void time_main_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* draw entirely, windowsize changes should be handled here */ +} + +/* ******************** default callbacks for time space ***************** */ + +static SpaceLink *time_new(void) +{ + SpaceTime *stime; + + stime= MEM_callocN(sizeof(SpaceTime), "inittime"); + + stime->spacetype= SPACE_TIME; + stime->blockscale= 0.7; + stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN; + + stime->v2d.tot.xmin= -4.0; + stime->v2d.tot.ymin= 0.0; + stime->v2d.tot.xmax= (float)EFRA + 4.0; + //stime->v2d.tot.ymax= (float)stime->winy; + + stime->v2d.cur= stime->v2d.tot; + + stime->v2d.min[0]= 1.0; + //stime->v2d.min[1]= (float)stime->winy; + + stime->v2d.max[0]= 32000.0; + //stime->v2d.max[1]= (float)stime->winy; + + stime->v2d.minzoom= 0.1f; + stime->v2d.maxzoom= 10.0; + + stime->v2d.scroll= 0; + stime->v2d.keepaspect= 0; + stime->v2d.keepzoom= 0; + stime->v2d.keeptot= 0; + + stime->flag |= TIME_DRAWFRAMES; + + return (SpaceLink*)stime; +} + +/* not spacelink itself */ +static void time_free(SpaceLink *sl) +{ +} + +/* spacetype; init callback */ +static void time_init(wmWindowManager *wm, ScrArea *sa) +{ + ARegion *ar; + + /* link area to SpaceXXX struct */ + + /* add handlers to area */ + /* define how many regions, the order and types */ + + /* add types to regions */ + for(ar= sa->regionbase.first; ar; ar= ar->next) { + if(ar->regiontype == RGN_TYPE_WINDOW) { + static ARegionType mainart={NULL, NULL, NULL, NULL}; + + mainart.init= time_main_area_init; + mainart.refresh= time_main_area_refresh; + mainart.draw= time_main_area_draw; + mainart.listener= time_main_area_listener; + + ar->type= &mainart; + + /* XXX the windowmanager may not be th best place to keep these + * keymaps, and this function callback may not be the best one + * to add the keymap handler, also will need to take care of + * area type changes, etc, basically space callbacks need to + * be looked at further */ + WM_event_remove_keymap_handler(&wm->timekeymap, &ar->handlers); + WM_event_add_keymap_handler(&wm->timekeymap, &ar->handlers); + } + else { + static ARegionType art={NULL, NULL, NULL, NULL}; + + /* for time being; register 1 type */ + ar->type= &art; + } + } +} + +/* spacetype; context changed */ +static void time_refresh(bContext *C, ScrArea *sa) +{ + +} + +static SpaceLink *time_duplicate(SpaceLink *sl) +{ + SpaceTime *stime= (SpaceTime *)sl; + SpaceTime *stimen= MEM_dupallocN(stime); + + return (SpaceLink *)stimen; +} + +/* only called once, from screen/spacetypes.c */ +void ED_spacetype_time(void) +{ + static SpaceType st; + + st.spaceid= SPACE_TIME; + + st.new= time_new; + st.free= time_free; + st.init= time_init; + st.refresh= time_refresh; + st.duplicate= time_duplicate; + st.operatortypes= time_operatortypes; + st.keymap= time_keymap; + + BKE_spacetype_register(&st); +} + diff --git a/source/blender/editors/space_time/time_intern.h b/source/blender/editors/space_time/time_intern.h new file mode 100644 index 00000000000..e7fb9af7906 --- /dev/null +++ b/source/blender/editors/space_time/time_intern.h @@ -0,0 +1,41 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef ED_TIME_INTERN_H +#define ED_TIME_INTERN_H + +/* internal exports only */ + +struct wmWindowManager; + +/* time_ops.c */ +void time_operatortypes(void); +void time_keymap(struct wmWindowManager *wm); + +#endif /* ED_TIME_INTERN_H */ + diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c new file mode 100644 index 00000000000..a02c5eb6844 --- /dev/null +++ b/source/blender/editors/space_time/time_ops.c @@ -0,0 +1,185 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_windowmanager_types.h" + +#include "BLI_blenlib.h" + +#include "BKE_global.h" + +#include "BIF_view2d.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* ********************** frame change operator ***************************/ + +static int change_frame_init(bContext *C, wmOperator *op) +{ + SpaceTime *stime= C->area->spacedata.first; + int cfra; + + if(!OP_get_int(op, "frame", &cfra)) + return 0; + + stime->flag |= TIME_CFRA_NUM; + + return 1; +} + +static void change_frame_apply(bContext *C, wmOperator *op) +{ + int cfra; + + OP_get_int(op, "frame", &cfra); + + if(cfra < MINFRAME) + cfra= MINFRAME; + +#if 0 + if( cfra!=CFRA || first ) + { + first= 0; + CFRA= cfra; + update_for_newframe_nodraw(0); // 1= nosound + timeline_force_draw(stime->redraws); + } + else PIL_sleep_ms(30); +#endif + + if(cfra!=CFRA) + CFRA= cfra; + + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); + /* XXX: add WM_NOTE_TIME_CHANGED? */ +} + +static void change_frame_exit(bContext *C, wmOperator *op) +{ + SpaceTime *stime= C->area->spacedata.first; + + stime->flag &= ~TIME_CFRA_NUM; +} + +static int change_frame_exec(bContext *C, wmOperator *op) +{ + if(!change_frame_init(C, op)) + return OPERATOR_CANCELLED; + + change_frame_apply(C, op); + change_frame_exit(C, op); + return OPERATOR_FINISHED; +} + +static int frame_from_event(bContext *C, wmEvent *event) +{ + SpaceTime *stime= C->area->spacedata.first; + ARegion *region= C->region; + int x, y; + float viewx; + + /* XXX region->winrect isn't updated on window changes */ + x= event->x - region->winrct.xmin; + y= event->y - region->winrct.ymin; + BIF_view2d_region_to_view(&stime->v2d, x, y, &viewx, NULL); + + return (int)(viewx+0.5f); +} + +static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + OP_verify_int(op, "frame", frame_from_event(C, event), NULL); + change_frame_init(C, op); + change_frame_apply(C, op); + + /* add temp handler */ + WM_event_add_modal_handler(&C->region->handlers, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int change_frame_cancel(bContext *C, wmOperator *op) +{ + change_frame_exit(C, op); + return OPERATOR_CANCELLED; +} + +static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + /* execute the events */ + switch(event->type) { + case MOUSEMOVE: + OP_set_int(op, "frame", frame_from_event(C, event)); + change_frame_apply(C, op); + break; + + case LEFTMOUSE: + if(event->val==0) { + change_frame_exit(C, op); + WM_event_remove_modal_handler(&C->region->handlers, op); + return OPERATOR_FINISHED; + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +/* Operator for joining two areas (space types) */ +void ED_TIME_OT_change_frame(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change frame"; + ot->idname= "ED_TIME_OT_change_frame"; + + /* api callbacks */ + ot->exec= change_frame_exec; + ot->invoke= change_frame_invoke; + ot->cancel= change_frame_cancel; + ot->modal= change_frame_modal; +} + +/* ************************** registration **********************************/ + +void time_operatortypes(void) +{ + WM_operatortype_append(ED_TIME_OT_change_frame); +} + +void time_keymap(wmWindowManager *wm) +{ + WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); +} + diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 9a08c7cd016..1abd860c661 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -118,7 +118,7 @@ static void view3d_free(SpaceLink *sl) /* spacetype; init callback */ -static void view3d_init(ScrArea *sa) +static void view3d_init(struct wmWindowManager *wm, ScrArea *sa) { ARegion *ar; @@ -174,6 +174,14 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) return (SpaceLink *)v3dn; } +void view3d_operatortypes(void) +{ +} + +void view3d_keymap(struct wmWindowManager *wm) +{ +} + /* only called once, from screen/spacetypes.c */ void ED_spacetype_view3d(void) { @@ -186,11 +194,9 @@ void ED_spacetype_view3d(void) st.init= view3d_init; st.refresh= view3d_refresh; st.duplicate= view3d_duplicate; + st.operatortypes= view3d_operatortypes; + st.keymap= view3d_keymap; BKE_spacetype_register(&st); - - } - - |