Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/animation/anim_ops.c
| /* SPDX-License-Identifier: GPL-2.0-or-later | /* SPDX-License-Identifier: GPL-2.0-or-later | ||||
| * Copyright 2008 Blender Foundation. All rights reserved. */ | * Copyright 2008 Blender Foundation. All rights reserved. */ | ||||
| /** \file | /** \file | ||||
| * \ingroup edanimation | * \ingroup edanimation | ||||
| */ | */ | ||||
| #include <math.h> | #include <math.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include "BLI_sys_types.h" | #include "BLI_sys_types.h" | ||||
| #include "BLI_math_base.h" | #include "BLI_math_base.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_video_edit_types.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | static bool change_frame_poll(bContext *C) | ||||
| } | } | ||||
| CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active"); | CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active"); | ||||
| return false; | return false; | ||||
| } | } | ||||
| static int seq_snap_threshold_get_frame_distance(bContext *C) | static int seq_snap_threshold_get_frame_distance(bContext *C) | ||||
| { | { | ||||
| const int snap_distance = SEQ_tool_settings_snap_distance_get(CTX_data_scene(C)); | const int snap_distance = SEQ_tool_settings_snap_distance_get(CTX_data_video_edit(C)); | ||||
| const ARegion *region = CTX_wm_region(C); | const ARegion *region = CTX_wm_region(C); | ||||
| return round_fl_to_int(UI_view2d_region_to_view_x(®ion->v2d, snap_distance) - | return round_fl_to_int(UI_view2d_region_to_view_x(®ion->v2d, snap_distance) - | ||||
| UI_view2d_region_to_view_x(®ion->v2d, 0)); | UI_view2d_region_to_view_x(®ion->v2d, 0)); | ||||
| } | } | ||||
| static void seq_frame_snap_update_best(const int position, | static void seq_frame_snap_update_best(const int position, | ||||
| const int timeline_frame, | const int timeline_frame, | ||||
| int *r_best_frame, | int *r_best_frame, | ||||
| int *r_best_distance) | int *r_best_distance) | ||||
| { | { | ||||
| if (abs(position - timeline_frame) < *r_best_distance) { | if (abs(position - timeline_frame) < *r_best_distance) { | ||||
| *r_best_distance = abs(position - timeline_frame); | *r_best_distance = abs(position - timeline_frame); | ||||
| *r_best_frame = position; | *r_best_frame = position; | ||||
| } | } | ||||
| } | } | ||||
| static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame) | static int seq_frame_apply_snap(bContext *C, VideoEdit *video_edit, const int timeline_frame) | ||||
| { | { | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(video_edit); | |||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | |||||
| SeqCollection *strips = SEQ_query_all_strips(seqbase); | SeqCollection *strips = SEQ_query_all_strips(seqbase); | ||||
| int best_frame = 0; | int best_frame = 0; | ||||
| int best_distance = MAXFRAME; | int best_distance = MAXFRAME; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| seq_frame_snap_update_best( | seq_frame_snap_update_best(SEQ_time_left_handle_frame_get(video_edit, seq), | ||||
| SEQ_time_left_handle_frame_get(scene, seq), timeline_frame, &best_frame, &best_distance); | timeline_frame, | ||||
| seq_frame_snap_update_best( | &best_frame, | ||||
| SEQ_time_right_handle_frame_get(scene, seq), timeline_frame, &best_frame, &best_distance); | &best_distance); | ||||
| seq_frame_snap_update_best(SEQ_time_right_handle_frame_get(video_edit, seq), | |||||
| timeline_frame, | |||||
| &best_frame, | |||||
| &best_distance); | |||||
| } | } | ||||
| SEQ_collection_free(strips); | SEQ_collection_free(strips); | ||||
| if (best_distance < seq_snap_threshold_get_frame_distance(C)) { | if (best_distance < seq_snap_threshold_get_frame_distance(C)) { | ||||
| return best_frame; | return best_frame; | ||||
| } | } | ||||
| return timeline_frame; | return timeline_frame; | ||||
| } | } | ||||
| /* Set the new frame number */ | /* Set the new frame number */ | ||||
| static void change_frame_apply(bContext *C, wmOperator *op) | static void change_frame_apply(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| VideoEdit *video_edit = CTX_data_video_edit(C); | |||||
| float frame = RNA_float_get(op->ptr, "frame"); | float frame = RNA_float_get(op->ptr, "frame"); | ||||
| bool do_snap = RNA_boolean_get(op->ptr, "snap"); | bool do_snap = RNA_boolean_get(op->ptr, "snap"); | ||||
| if (do_snap) { | if (do_snap) { | ||||
| if (CTX_wm_space_seq(C) && SEQ_editing_get(scene) != NULL) { | if (CTX_wm_space_seq(C) && video_edit != NULL) { | ||||
| frame = seq_frame_apply_snap(C, scene, frame); | frame = seq_frame_apply_snap(C, video_edit, frame); | ||||
| } | } | ||||
| else { | else { | ||||
| frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame); | frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame); | ||||
| } | } | ||||
| } | } | ||||
| /* set the new frame number */ | /* set the new frame number */ | ||||
| if (CTX_wm_space_seq(C)) { | |||||
| if (video_edit->r.flag & SCER_SHOW_SUBFRAME) { | |||||
| video_edit->r.cfra = (int)frame; | |||||
| video_edit->r.subframe = frame - (int)frame; | |||||
| } | |||||
| else { | |||||
| video_edit->r.cfra = round_fl_to_int(frame); | |||||
| video_edit->r.subframe = 0.0f; | |||||
| } | |||||
| FRAMENUMBER_MIN_CLAMP(video_edit->r.cfra); | |||||
| /* do updates */ | |||||
| DEG_id_tag_update(&video_edit->id, ID_RECALC_FRAME_CHANGE); | |||||
| WM_event_add_notifier(C, NC_VIDEO_EDIT | ND_FRAME, video_edit); | |||||
| } | |||||
| else { | |||||
| if (scene->r.flag & SCER_SHOW_SUBFRAME) { | if (scene->r.flag & SCER_SHOW_SUBFRAME) { | ||||
| scene->r.cfra = (int)frame; | scene->r.cfra = (int)frame; | ||||
| scene->r.subframe = frame - (int)frame; | scene->r.subframe = frame - (int)frame; | ||||
| } | } | ||||
| else { | else { | ||||
| scene->r.cfra = round_fl_to_int(frame); | scene->r.cfra = round_fl_to_int(frame); | ||||
| scene->r.subframe = 0.0f; | scene->r.subframe = 0.0f; | ||||
| } | } | ||||
| FRAMENUMBER_MIN_CLAMP(scene->r.cfra); | FRAMENUMBER_MIN_CLAMP(scene->r.cfra); | ||||
| /* do updates */ | /* do updates */ | ||||
| DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); | DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); | WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); | ||||
| } | } | ||||
| } | |||||
| /* ---- */ | /* ---- */ | ||||
| /* Non-modal callback for running operator without user input */ | /* Non-modal callback for running operator without user input */ | ||||
| static int change_frame_exec(bContext *C, wmOperator *op) | static int change_frame_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| change_frame_apply(C, op); | change_frame_apply(C, op); | ||||
| ▲ Show 20 Lines • Show All 469 Lines • Show Last 20 Lines | |||||