diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c new file mode 100644 index 00000000000..ad7b53c177f --- /dev/null +++ b/source/blender/editors/animation/anim_ops.c @@ -0,0 +1,299 @@ +/** + * $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, Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_action_types.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_context.h" +#include "BKE_utildefines.h" + +#include "UI_interface.h" +#include "UI_view2d.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_anim_api.h" +#include "ED_markers.h" +#include "ED_screen.h" + +/* ********************** frame change operator ***************************/ + +/* Set any flags that are necessary to indicate modal time-changing operation */ +static int change_frame_init(bContext *C, wmOperator *op) +{ + ScrArea *curarea= CTX_wm_area(C); + + if (curarea == NULL) + return 0; + + if (curarea->spacetype == SPACE_TIME) { + SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); + + /* timeline displays frame number only when dragging indicator */ + // XXX make this more in line with other anim editors? + stime->flag |= TIME_CFRA_NUM; + } + + return 1; +} + +/* Set the new frame number */ +static void change_frame_apply(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + int cfra; + + /* get frame, and clamp to MINFRAME */ + cfra= RNA_int_get(op->ptr, "frame"); + 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); + } +#endif + + /* XXX why don't we directly set this? */ + if (cfra != scene->r.cfra) + scene->r.cfra= cfra; + + WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL); + /* XXX: add WM_NOTE_TIME_CHANGED? */ +} + +/* Clear any temp flags */ +static void change_frame_exit(bContext *C, wmOperator *op) +{ + ScrArea *curarea= CTX_wm_area(C); + + if (curarea == NULL) + return; + + if (curarea->spacetype == SPACE_TIME) { + SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); + + /* timeline displays frame number only when dragging indicator */ + // XXX make this more in line with other anim editors? + stime->flag &= ~TIME_CFRA_NUM; + } +} + +/* ---- */ + +/* Non-modal callback for running operator without user input */ +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; +} + +/* ---- */ + +/* Get frame from mouse coordinates */ +static int frame_from_event(bContext *C, wmEvent *event) +{ + ARegion *region= CTX_wm_region(C); + float viewx; + int x, y; + + /* convert screen coordinates to region coordinates */ + x= event->x - region->winrct.xmin; + y= event->y - region->winrct.ymin; + + /* convert from region coordinates to View2D 'tot' space */ + UI_view2d_region_to_view(®ion->v2d, x, y, &viewx, NULL); + + /* round result to nearest int (frames are ints!) */ + return (int)floor(viewx+0.5f); +} + +/* Modal Operator init */ +static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + /* Change to frame that mouse is over before adding modal handler, + * as user could click on a single frame (jump to frame) as well as + * click-dragging over a range (modal scrubbing). + */ + RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); + + change_frame_init(C, op); + change_frame_apply(C, op); + + /* add temp handler */ + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + + return OPERATOR_RUNNING_MODAL; +} + +/* In case modal operator is cancelled */ +static int change_frame_cancel(bContext *C, wmOperator *op) +{ + change_frame_exit(C, op); + return OPERATOR_CANCELLED; +} + +/* Modal event handling of frame changing */ +static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + /* execute the events */ + switch (event->type) { + case MOUSEMOVE: + RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); + change_frame_apply(C, op); + break; + + case LEFTMOUSE: + if (event->val==0) { + change_frame_exit(C, op); + return OPERATOR_FINISHED; + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void ED_ANIM_OT_change_frame(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Change frame"; + ot->idname= "ED_ANIM_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; + + /* rna */ + prop= RNA_def_property(ot->srna, "frame", PROP_INT, PROP_NONE); +} + +/* ****************** time display toggle operator ****************************/ + +static int toggle_time_exec(bContext *C, wmOperator *op) +{ + ScrArea *curarea= CTX_wm_area(C); + + if (curarea == NULL) + return OPERATOR_CANCELLED; + + /* simply toggle draw frames flag in applicable spaces */ + // XXX or should relevant spaces define their own version of this? + switch (curarea->spacetype) { + case SPACE_TIME: /* TimeLine */ + { + SpaceTime *stime= (SpaceTime *)CTX_wm_space_data(C); + stime->flag ^= TIME_DRAWFRAMES; + } + break; + case SPACE_ACTION: /* Action Editor */ + { + SpaceAction *saction= (SpaceAction *)CTX_wm_space_data(C); + saction->flag ^= SACTION_DRAWTIME; + } + break; + case SPACE_IPO: /* IPO Editor */ + { + SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C); + sipo->flag ^= SIPO_DRAWTIME; + } + break; + case SPACE_NLA: /* NLA Editor */ + { + SpaceNla *snla= (SpaceNla *)CTX_wm_space_data(C); + snla->flag ^= SNLA_DRAWTIME; + } + break; + case SPACE_SEQ: /* Sequencer */ + { + SpaceSeq *sseq= (SpaceSeq *)CTX_wm_space_data(C); + sseq->flag ^= SEQ_DRAWFRAMES; + } + break; + + default: /* editor doesn't show frames */ + return OPERATOR_CANCELLED; // XXX or should we pass through instead? + } + + ED_area_tag_redraw(curarea); + + return OPERATOR_FINISHED; +} + +void ED_ANIM_OT_toggle_time(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Frames/Seconds"; + ot->idname= "ED_ANIM_OT_toggle_time"; + + /* api callbacks */ + ot->exec= toggle_time_exec; +} + +/* ************************** registration **********************************/ + +void ED_operatortypes_anim(void) +{ + WM_operatortype_append(ED_ANIM_OT_change_frame); + WM_operatortype_append(ED_ANIM_OT_toggle_time); +} + +void ED_keymap_anim(wmWindowManager *wm) +{ + ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0); + + WM_keymap_verify_item(keymap, "ED_ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "ED_ANIM_OT_toggle_time", TKEY, KM_PRESS, 0, 0); +} + diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index a2786b5ed1c..61065cd970d 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -216,6 +216,12 @@ void ANIM_draw_cfra(const bContext *C, struct View2D *v2d, short flag); void ANIM_draw_previewrange(const bContext *C, struct View2D *v2d); /* ************************************************* */ +/* OPERATORS */ + +void ED_operatortypes_anim(void); +void ED_keymap_anim(struct wmWindowManager *wm); + +/* ************************************************ */ #endif /* ED_ANIM_API_H */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 6eafc07bcda..06293090f6f 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -86,6 +86,7 @@ int ED_operator_areaactive(struct bContext *C); #define ED_KEYMAP_UI 1 #define ED_KEYMAP_VIEW2D 2 #define ED_KEYMAP_MARKERS 4 +#define ED_KEYMAP_ANIMATION 8 #endif /* ED_SCREEN_H */ diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 5995cccc874..b45d8ea6cbb 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1097,7 +1097,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event) /* firstly, check context to see if mouse is actually in region */ // XXX isn't this the job of poll() callbacks which can't check events, but only context? if (ar == NULL) - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH;//OPERATOR_CANCELLED; else v2d= &ar->v2d; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 3f7ca19c1f0..194000a8362 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -416,6 +416,7 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla { /* note, add-handler checks if it already exists */ + // XXX it would be good to have boundbox checks for some of these... if(flag & ED_KEYMAP_UI) { UI_add_region_handlers(handlers); } @@ -427,6 +428,10 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } + if(flag & ED_KEYMAP_ANIMATION) { + ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 2342d5c2e8b..dd88b7ad2c3 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1439,6 +1439,7 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_verify_item(keymap, "ED_SCR_OT_repeat_last", F4KEY, KM_PRESS, 0, 0); /* screen level global keymaps */ + // err... ED_marker_keymap(wm); } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index a592cd1e866..105d9b3806c 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -179,7 +179,7 @@ static void action_main_area_draw(const bContext *C, ARegion *ar) /* time grid */ unit= (saction->flag & SACTION_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES; - grid= UI_view2d_grid_calc(C, v2d, unit, V2D_GRID_NOCLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); + grid= UI_view2d_grid_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); UI_view2d_grid_draw(C, v2d, grid, V2D_GRIDLINES_ALL); UI_view2d_grid_free(grid); @@ -202,7 +202,7 @@ static void action_main_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); /* scrollers */ - scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_NOCLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); UI_view2d_scrollers_draw(C, v2d, scrollers); UI_view2d_scrollers_free(scrollers); } @@ -311,7 +311,7 @@ void ED_spacetype_action(void) art->init= action_main_area_init; art->draw= action_main_area_draw; art->listener= action_main_area_listener; - art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS; + art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 2e958a4d6dc..e2f9ead8e59 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -39,6 +39,7 @@ #include "ED_screen.h" #include "ED_space_api.h" +#include "ED_anim_api.h" ARegionType *ED_regiontype_from_id(SpaceType *st, int regionid) @@ -81,6 +82,7 @@ void ED_spacetypes_init(void) /* register operator types for screen and all spaces */ ED_operatortypes_screen(); ui_view2d_operatortypes(); + ED_operatortypes_anim(); spacetypes = BKE_spacetypes_list(); for(type=spacetypes->first; type; type=type->next) @@ -98,6 +100,7 @@ void ED_spacetypes_keymap(wmWindowManager *wm) ED_keymap_screen(wm); UI_view2d_keymap(wm); + ED_keymap_anim(wm); spacetypes = BKE_spacetypes_list(); for(stype=spacetypes->first; stype; stype=stype->next) { diff --git a/source/blender/editors/space_ipo/space_ipo.c b/source/blender/editors/space_ipo/space_ipo.c index 6f8589a76d7..23723062479 100644 --- a/source/blender/editors/space_ipo/space_ipo.c +++ b/source/blender/editors/space_ipo/space_ipo.c @@ -305,7 +305,7 @@ void ED_spacetype_ipo(void) art->init= ipo_main_area_init; art->draw= ipo_main_area_draw; art->listener= ipo_main_area_listener; - art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS; + art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 5cadd521b66..54ab83e6de8 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -296,12 +296,12 @@ void ED_spacetype_time(void) /* regions: main window */ art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); art->regionid = RGN_TYPE_WINDOW; - art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS; + art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION; art->init= time_main_area_init; art->draw= time_main_area_draw; art->listener= time_main_area_listener; - art->keymap= time_keymap; + //art->keymap= time_keymap; BLI_addhead(&st->regiontypes, art); /* regions: header */ diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index e8704457c00..51808fbf623 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -50,175 +50,18 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_markers.h" -/* ********************** frame change operator ***************************/ - -static int change_frame_init(bContext *C, wmOperator *op) -{ - SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); - - stime->flag |= TIME_CFRA_NUM; - - return 1; -} - -static void change_frame_apply(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - int cfra; - - cfra= RNA_int_get(op->ptr, "frame"); - - 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!=scene->r.cfra) - scene->r.cfra= cfra; - - WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL); - /* XXX: add WM_NOTE_TIME_CHANGED? */ -} - -static void change_frame_exit(bContext *C, wmOperator *op) -{ - SpaceTime *stime= (SpaceTime*)CTX_wm_space_data(C); - - 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) -{ - ARegion *region= CTX_wm_region(C); - int x, y; - float viewx; - - x= event->x - region->winrct.xmin; - y= event->y - region->winrct.ymin; - UI_view2d_region_to_view(®ion->v2d, x, y, &viewx, NULL); - - return (int)floor(viewx+0.5f); -} - -static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); - change_frame_init(C, op); - change_frame_apply(C, op); - - /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->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: - RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); - change_frame_apply(C, op); - break; - - case LEFTMOUSE: - if(event->val==0) { - change_frame_exit(C, op); - return OPERATOR_FINISHED; - } - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -void ED_TIME_OT_change_frame(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* 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; - - /* rna */ - prop= RNA_def_property(ot->srna, "frame", PROP_INT, PROP_NONE); -} - -/* ****************** time display toggle operator ****************************/ - -static int toggle_time_exec(bContext *C, wmOperator *op) -{ - SpaceTime *stime= (SpaceTime *)CTX_wm_space_data(C); - ScrArea *curarea= CTX_wm_area(C); - - if (ELEM(NULL, curarea, stime)) - return OPERATOR_CANCELLED; - - /* simply toggle draw frames flag for now */ - // in past, this asked user to choose in a menu beforehand, but that is clumsy - stime->flag ^= TIME_DRAWFRAMES; - - ED_area_tag_redraw(curarea); - - return OPERATOR_FINISHED; -} - -void ED_TIME_OT_toggle_time(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Frames/Seconds"; - ot->idname= "ED_TIME_OT_toggle_time"; - - /* api callbacks */ - ot->exec= toggle_time_exec; -} +/* *************************************************/ /* ************************** registration **********************************/ void time_operatortypes(void) { - WM_operatortype_append(ED_TIME_OT_change_frame); - WM_operatortype_append(ED_TIME_OT_toggle_time); + } void time_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "TimeLine", SPACE_TIME, 0); - WM_keymap_verify_item(keymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "ED_TIME_OT_toggle_time", TKEY, KM_PRESS, 0, 0); }