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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/animation/anim_ops.c')
-rw-r--r--source/blender/editors/animation/anim_ops.c124
1 files changed, 110 insertions, 14 deletions
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 2de42933dc0..86b368fe0d2 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -60,6 +60,8 @@
#include "anim_intern.h"
+#include "MEM_guardedalloc.h"
+
/* ********************** frame change operator ***************************/
/* Check if the operator can be run from the current context */
@@ -90,10 +92,11 @@ static int change_frame_poll(bContext *C)
}
/* Set the new frame number */
-static void change_frame_apply(bContext *C, wmOperator *op)
+static void change_frame_apply(bContext *C, wmOperator *op, bool final)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ ARegion *ar_op = CTX_wm_region(C);
int frame = RNA_int_get(op->ptr, "frame");
bool do_snap = RNA_boolean_get(op->ptr, "snap");
@@ -107,8 +110,44 @@ static void change_frame_apply(bContext *C, wmOperator *op)
SUBFRA = 0.0f;
/* do updates */
- BKE_sound_seek_scene(bmain, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+
+ if (final) {
+ BKE_sound_seek_scene(bmain, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ }
+ else
+ {
+ bScreen *screen = CTX_wm_screen(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *window;
+ ScrArea *sa;
+
+ BKE_sound_seek_scene(bmain, scene);
+
+ ED_update_for_newframe(bmain, scene, 1);
+
+ for (window = wm->windows.first; window; window = window->next) {
+ for (sa = window->screen->areabase.first; sa; sa = sa->next) {
+ ARegion *ar;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ bool redraw = false;
+ if (ar == ar_op) {
+ redraw = true;
+ }
+ else if (ED_match_region_with_redraws(sa->spacetype, ar->regiontype, screen->redraws_flag)) {
+ redraw = true;
+ }
+
+ if (redraw) {
+ ED_region_tag_redraw(ar);
+ }
+ }
+
+ if (ED_match_area_with_refresh(sa->spacetype, SPACE_TIME))
+ ED_area_tag_refresh(sa);
+ }
+ }
+ }
}
/* ---- */
@@ -116,8 +155,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
/* Non-modal callback for running operator without user input */
static int change_frame_exec(bContext *C, wmOperator *op)
{
- change_frame_apply(C, op);
-
+ change_frame_apply(C, op, true);
return OPERATOR_FINISHED;
}
@@ -154,13 +192,35 @@ static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event)
}
}
}
-static void change_frame_seq_preview_end(bContext *C)
+
+typedef struct ChangeFrameData {
+ wmTimer *timer;
+ double last_duration;
+ int frame;
+ int last_frame;
+} ChangeFrameData;
+
+static void change_frame_seq_preview_end(bContext *C, wmOperator *op)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+
if (ED_sequencer_special_preview_get() != NULL) {
Scene *scene = CTX_data_scene(C);
ED_sequencer_special_preview_clear();
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
+
+ if (op->customdata) {
+ ChangeFrameData *data = op->customdata;
+ WM_event_remove_timer(wm, win, data->timer);
+ MEM_freeN(data);
+ op->customdata = NULL;
+ /* add here too to take care of cancelling */
+ if (win->screen)
+ win->screen->scrubbing = false;
+ }
+
}
/* Modal Operator init */
@@ -170,11 +230,22 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
* as user could click on a single frame (jump to frame) as well as
* click-dragging over a range (modal scrubbing).
*/
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ ChangeFrameData *data = MEM_callocN(sizeof(ChangeFrameData), "changeframedata");
+
+ data->timer = WM_event_add_timer(wm, win, TIMER, FRA2TIME(1.0));
+
RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
+ op->customdata = data;
change_frame_seq_preview_begin(C, event);
- change_frame_apply(C, op);
+ if (win->screen)
+ win->screen->scrubbing = true;
+
+ change_frame_apply(C, op, false);
/* add temp handler */
WM_event_add_modal_handler(C, op);
@@ -182,24 +253,43 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
return OPERATOR_RUNNING_MODAL;
}
-static void change_frame_cancel(bContext *C, wmOperator *UNUSED(op))
+static void change_frame_cancel(bContext *C, wmOperator *op)
{
- change_frame_seq_preview_end(C);
+ change_frame_seq_preview_end(C, op);
}
/* Modal event handling of frame changing */
static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ChangeFrameData *data = op->customdata;
+ wmWindow *win = CTX_wm_window(C);
+
int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
switch (event->type) {
case ESCKEY:
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ if (win->screen)
+ win->screen->scrubbing = false;
+ BKE_sound_seek_scene(bmain, scene);
ret = OPERATOR_FINISHED;
break;
case MOUSEMOVE:
- RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
- change_frame_apply(C, op);
+ data->frame = frame_from_event(C, event);
+ break;
+
+ case TIMER:
+ if (data->timer->duration - data->last_duration > FRA2TIME(1)) {
+ if (data->frame != data->last_frame) {
+ RNA_int_set(op->ptr, "frame", data->frame);
+ change_frame_apply(C, op, false);
+ data->last_frame = data->frame;
+ data->last_duration = data->timer->duration;
+ }
+ }
break;
case LEFTMOUSE:
@@ -208,8 +298,14 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init
* the modal op) doesn't work for some reason
*/
- if (event->val == KM_RELEASE)
+ if (event->val == KM_RELEASE) {
+ if (win->screen)
+ win->screen->scrubbing = false;
+ data->frame = frame_from_event(C, event);
+ RNA_int_set(op->ptr, "frame", data->frame);
+ change_frame_apply(C, op, true);
ret = OPERATOR_FINISHED;
+ }
break;
case LEFTCTRLKEY:
@@ -224,7 +320,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret != OPERATOR_RUNNING_MODAL) {
- change_frame_seq_preview_end(C);
+ change_frame_seq_preview_end(C, op);
}
return ret;
@@ -247,7 +343,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
ot->poll = change_frame_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
/* rna */
ot->prop = RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);