[Bf-blender-cvs] [3551b0a6721] blender-v3.3-release: Fix T99255: Strips inserting incorrectly

Sebastian Parborg noreply at git.blender.org
Mon Aug 15 14:24:55 CEST 2022


Commit: 3551b0a67213c3f35446a9cd673da4aa3b39ff1e
Author: Sebastian Parborg
Date:   Tue Aug 2 19:36:42 2022 +0200
Branches: blender-v3.3-release
https://developer.blender.org/rB3551b0a67213c3f35446a9cd673da4aa3b39ff1e

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 = &region->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, &region->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 = &region->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, &region->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. @@



More information about the Bf-blender-cvs mailing list