From 5dc5bd5a2b1a54120f7f4b7583e42d050947f965 Mon Sep 17 00:00:00 2001 From: Ramon Klauck Date: Sun, 17 Aug 2025 14:01:40 +0200 Subject: [PATCH] VSE: Add "Mirror" menu to preview strip menu This PR adds a "Mirror" menu to the Strip menu within the VSE preview. This menu is similar to the "Mirror" menu in the view3d "Object" menu. It allows the user to access the mirror operator through a menu, rather than via a shortcut. Pull Request: https://projects.blender.org/blender/blender/pulls/142506 --- scripts/startup/bl_ui/space_sequencer.py | 28 +++++++++++++++++++ .../transform_convert_sequencer_image.cc | 17 +++++------ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/scripts/startup/bl_ui/space_sequencer.py b/scripts/startup/bl_ui/space_sequencer.py index d8677ed64e1..4ca87af61ed 100644 --- a/scripts/startup/bl_ui/space_sequencer.py +++ b/scripts/startup/bl_ui/space_sequencer.py @@ -9,6 +9,7 @@ from bpy.types import ( Panel, ) from bpy.app.translations import ( + pgettext_iface as iface_, contexts as i18n_contexts, pgettext_iface as iface_, pgettext_rpt as rpt_, @@ -994,6 +995,31 @@ class SEQUENCER_MT_strip_animation(Menu): layout.operator("anim.keyframe_clear_vse", text="Clear Keyframes...") +class SEQUENCER_MT_strip_mirror(Menu): + bl_label = "Mirror" + + def draw(self, _context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_PREVIEW' + + layout.operator("transform.mirror", text="Interactive Mirror") + + layout.separator() + + for (space_name, space_id) in (("Global", 'GLOBAL'), ("Local", 'LOCAL')): + for axis_index, axis_name in enumerate("XY"): + props = layout.operator( + "transform.mirror", + text="{:s} {:s}".format(axis_name, iface_(space_name)), + translate=False, + ) + props.constraint_axis[axis_index] = True + props.orient_type = space_id + + if space_id == 'GLOBAL': + layout.separator() + + class SEQUENCER_MT_strip_input(Menu): bl_label = "Inputs" @@ -1147,6 +1173,7 @@ class SEQUENCER_MT_strip(Menu): strip = context.active_strip if has_preview: + layout.menu("SEQUENCER_MT_strip_mirror") layout.separator() layout.operator("sequencer.preview_duplicate_move", text="Duplicate") layout.operator("sequencer.copy", text="Copy") @@ -3202,6 +3229,7 @@ classes = ( SEQUENCER_MT_strip_text, SEQUENCER_MT_strip_show_hide, SEQUENCER_MT_strip_animation, + SEQUENCER_MT_strip_mirror, SEQUENCER_MT_strip_input, SEQUENCER_MT_strip_lock_mute, SEQUENCER_MT_image, diff --git a/source/blender/editors/transform/transform_convert_sequencer_image.cc b/source/blender/editors/transform/transform_convert_sequencer_image.cc index 33f63630671..f27be5f10a8 100644 --- a/source/blender/editors/transform/transform_convert_sequencer_image.cc +++ b/source/blender/editors/transform/transform_convert_sequencer_image.cc @@ -289,7 +289,7 @@ static void image_transform_set(TransInfo *t) transform->xofs *= t->values_final[0]; transform->yofs *= t->values_final[1]; - if (t->orient_curr == O_SET) { + if (t->orient_curr == O_SET && t->orient_type_mask & (1 << V3D_ORIENT_LOCAL)) { if (strip == ed->act_strip) { transform->rotation = tdseq->orig_rotation; } @@ -298,15 +298,16 @@ static void image_transform_set(TransInfo *t) } } else { - strip->flag = tdseq->orig_flag; - if (t->values_final[0] == -1) { - strip->flag ^= SEQ_FLIPX; - } - if (t->values_final[1] == -1) { - strip->flag ^= SEQ_FLIPY; - } transform->rotation = tdseq->orig_rotation; } + + strip->flag = tdseq->orig_flag; + if (t->values_final[0] == -1) { + strip->flag ^= SEQ_FLIPX; + } + if (t->values_final[1] == -1) { + strip->flag ^= SEQ_FLIPY; + } } if ((t->animtimer) && animrig::is_autokey_on(scene)) {