Commit: b010985e4ac49a98e12802567efdf6b38f7b5bf2 Author: Sebastian Parborg Date: Tue Aug 2 19:36:42 2022 +0200 Branches: master https://developer.blender.org/rBb010985e4ac49a98e12802567efdf6b38f7b5bf2
Fix T99255: Strips inserting incorrectly When dropping file to sequencer timeline, coordinates for strip position and overlap handling are used even if not set. Reset internal state in on_drag_start callback and set is_modal variable only if coordinates are updated. This way when dragging file from external file browser, strip is added at current frame as before modal operator was implemented. Reviewed By: Richard Antalik Differential Revision: http://developer.blender.org/D15333 =================================================================== M source/blender/editors/space_sequencer/sequencer_drag_drop.c =================================================================== diff --git a/source/blender/editors/space_sequencer/sequencer_drag_drop.c b/source/blender/editors/space_sequencer/sequencer_drag_drop.c index f6561cf07b9..4796d80b3a0 100644 --- a/source/blender/editors/space_sequencer/sequencer_drag_drop.c +++ b/source/blender/editors/space_sequencer/sequencer_drag_drop.c @@ -51,7 +51,9 @@ typedef struct SeqDropCoords { float start_frame, channel; int strip_len, channel_len; + float playback_rate; bool in_use; + bool has_read_mouse_pos; bool is_intersecting; bool use_snapping; float snap_point_x; @@ -63,7 +65,7 @@ typedef struct SeqDropCoords { * preloading data on drag start. * Therefore we will for now use a global variable for this. */ -static SeqDropCoords g_drop_coords = {.in_use = false}; +static SeqDropCoords g_drop_coords = {.in_use = false, .has_read_mouse_pos = false}; static void generic_poll_operations(const wmEvent *event, uint8_t type) { @@ -82,31 +84,134 @@ static bool image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *ev } } - return WM_drag_is_ID_type(drag, ID_IM); + if (WM_drag_is_ID_type(drag, ID_IM)) { + generic_poll_operations(event, TH_SEQ_IMAGE); + return true; + } + + return false; } -static bool movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +static bool is_movie(wmDrag *drag) { if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { /* Rule might not work? */ - generic_poll_operations(event, TH_SEQ_MOVIE); + if (ELEM(drag->icon, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { /* Rule might not work? */ return true; } } + if (WM_drag_is_ID_type(drag, ID_MC)) { + return true; + } + return false; +} + +static bool movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +{ + if (is_movie(drag)) { + generic_poll_operations(event, TH_SEQ_MOVIE); + return true; + } - return WM_drag_is_ID_type(drag, ID_MC); + return false; } -static bool sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +static bool is_sound(wmDrag *drag) { if (drag->type == WM_DRAG_PATH) { if (ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK)) { /* Rule might not work? */ - generic_poll_operations(event, TH_SEQ_AUDIO); return true; } } + if (WM_drag_is_ID_type(drag, ID_SO)) { + return true; + } + return false; +} - return WM_drag_is_ID_type(drag, ID_SO); +static bool sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +{ + if (is_sound(drag)) { + generic_poll_operations(event, TH_SEQ_AUDIO); + return true; + } + + return false; +} + +static float update_overlay_strip_position_data(bContext *C, const int mval[2]) +{ + SeqDropCoords *coords = &g_drop_coords; + ARegion *region = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + int hand; + View2D *v2d = ®ion->v2d; + + /* Update the position were we would place the strip if we complete the drag and drop action. + */ + UI_view2d_region_to_view(v2d, mval[0], mval[1], &coords->start_frame, &coords->channel); + coords->start_frame = roundf(coords->start_frame); + if (coords->channel < 1.0f) { + coords->channel = 1; + } + + float start_frame = coords->start_frame; + float end_frame; + float strip_len; + + if (coords->playback_rate != 0.0f) { + float scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base; + strip_len = coords->strip_len / (coords->playback_rate / scene_playback_rate); + } + else { + strip_len = coords->strip_len; + } + + end_frame = coords->start_frame + strip_len; + + if (coords->use_snapping) { + /* Do snapping via the existing transform code. */ + int snap_delta; + float snap_frame; + bool valid_snap; + + valid_snap = ED_transform_snap_sequencer_to_closest_strip_calc( + scene, region, start_frame, end_frame, &snap_delta, &snap_frame); + + if (valid_snap) { + /* We snapped onto something! */ + start_frame += snap_delta; + coords->start_frame = start_frame; + end_frame = start_frame + strip_len; + coords->snap_point_x = snap_frame; + } + else { + /* Nothing was snapped to, disable snap drawing. */ + coords->use_snapping = false; + } + } + + if (strip_len < 1) { + /* Only check if there is a strip already under the mouse cursor. */ + coords->is_intersecting = find_nearest_seq(scene, ®ion->v2d, &hand, mval); + } + else { + /* Check if there is a strip that would intersect with the new strip(s). */ + coords->is_intersecting = false; + Sequence dummy_seq = {.machine = coords->channel, + .start = coords->start_frame, + .len = coords->strip_len, + .speed_factor = 1.0f, + .media_playback_rate = coords->playback_rate, + .flag = SEQ_AUTO_PLAYBACK_RATE}; + Editing *ed = SEQ_editing_ensure(scene); + + for (int i = 0; i < coords->channel_len && !coords->is_intersecting; i++) { + coords->is_intersecting = SEQ_transform_test_overlap(scene, ed->seqbasep, &dummy_seq); + dummy_seq.machine++; + } + } + + return strip_len; } static void sequencer_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop) @@ -153,93 +258,77 @@ static void sequencer_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop) RNA_collection_add(drop->ptr, "files", &itemptr); RNA_string_set(&itemptr, "name", file); } - - if (g_drop_coords.in_use) { - RNA_int_set(drop->ptr, "frame_start", g_drop_coords.start_frame); - RNA_int_set(drop->ptr, "channel", g_drop_coords.channel); - RNA_boolean_set(drop->ptr, "overlap_shuffle_override", true); - } - else { - Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_active_seqbase_get(ed); - ListBase *channels = SEQ_channels_displayed_get(ed); - SpaceSeq *sseq = CTX_wm_space_seq(C); - - SeqCollection *strips = SEQ_query_rendered_strips( - scene, channels, seqbase, scene->r.cfra, sseq->chanshown); - - /* Get the top most strip channel that is in view.*/ - Sequence *seq; - int max_channel = -1; - SEQ_ITERATOR_FOREACH (seq, strips) { - max_channel = max_ii(seq->machine, max_channel); - } - - if (max_channel != -1) { - RNA_int_set(drop->ptr, "channel", max_channel); - } - SEQ_collection_free(strips); - } } -} -static void update_overlay_strip_poistion_data(bContext *C, const int mval[2]) -{ - SeqDropCoords *coords = &g_drop_coords; - ARegion *region = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); - int hand; - View2D *v2d = ®ion->v2d; + if (g_drop_coords.in_use) { + if (!g_drop_coords.has_read_mouse_pos) { + /* We didn't read the mouse position, so we need to do it manually here. */ + int xy[2]; + wmWindow *win = CTX_wm_window(C); + xy[0] = win->eventstate->xy[0]; + xy[1] = win->eventstate->xy[1]; + + ARegion *region = CTX_wm_region(C); + int mval[2]; + /* Convert mouse coordinates to region local coordinates. */ + mval[0] = xy[0] - region->winrct.xmin; + mval[1] = xy[1] - region->winrct.ymin; + + update_overlay_strip_position_data(C, mval); + } - /* Update the position were we would place the strip if we complete the drag and drop action. - */ - UI_view2d_region_to_view(v2d, mval[0], mval[1], &coords->start_frame, &coords->channel); - coords->start_frame = roundf(coords->start_frame); - if (coords->channel < 1.0f) { - coords->channel = 1; + RNA_int_set(drop->ptr, "frame_start", g_drop_coords.start_frame); + RNA_int_set(drop->ptr, "channel", g_drop_coords.channel); + RNA_boolean_set(drop->ptr, "overlap_shuffle_override", true); } + else { + /* We are dropped inside the preview region. Put the strip on top of the + * current displayed frame. */ + Scene *scene = CTX_data_scene(C); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); + SpaceSeq *sseq = CTX_wm_space_seq(C); - float start_frame = coords->start_frame; - float end_frame = coords->start_frame + coords->strip_len; - - if (coords->use_snapping) { - /* Do snapping via the existing transform code. */ - int snap_delta; - float snap_frame; - bool valid_snap; - - valid_snap = ED_transform_snap_sequencer_to_closest_strip_calc( - scene, region, start_frame, end_frame, &snap_delta, &snap_frame); + SeqCollection *strips = SEQ_query_rendered_strips( + scene, channels, seqbase, scene->r.cfra, sseq->chanshown); - if (valid_snap) { - /* We snapped onto something! */ - start_frame += snap_delta; - coords->start_frame = start_frame; - end_frame = start_frame + coords->strip_len; - coords->snap_point_x = snap_frame; + /* Get the top most strip channel that is in view.*/ + Sequence *seq; + int max_channel = -1; + SEQ_ITERATOR_FOREACH (seq, strips) { + max_channel = max_ii(seq->machine, max_channel); } - else { - /* Nothing was snapped to, disable snap drawing. */ - coords->use_snapping = false; + + if (max_channel != -1) { + RNA_int_set(drop->ptr, "channel", max_channel); } + SEQ_collection_free(strips); } +} - if (coords->strip_len < 1) { - /* Only check if there is a strip already under the mouse cursor. */ - coords->is_intersecting = find_nearest_seq(scene, ®ion->v2d, &hand, mval); +static void get_drag_path(wmDrag *drag, char r_path[FILE_MAX]) +{ + ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0); + /* ID dropped. */ + if (id != NULL) { + const ID_Type id_type = GS(id->name); + if (id_type == ID_IM) { + Image *ima = (Image *)id; + BLI_strncpy(r_path, ima->filepath, FILE_MAX); + } + else if (id_type == ID_MC) { + MovieClip *clip = (MovieClip *)id; + BLI_strncpy(r_path, clip->filepath, FILE_MAX); + } + else if (id_type == ID_SO) { + bSound *sound = (bSound *)id; + BLI_strncpy(r_ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs