diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-10-07 04:32:04 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-10-07 19:27:55 +0300 |
commit | d04d27b406b856396102452cab0eedf315e94a54 (patch) | |
tree | 4a881ab29123828287f83272a0ca1d03b62b4472 | |
parent | 919e513fa8f9fb4f1304ea4b752869b6d63b1608 (diff) |
Sequencer: 2D cursor for the preview & transform
- Use 2D cursor in the preview space using shortcuts
matching the UV editor and 3D view.
- Add Cursor tool, cursor transform.
- Support for cursor and bound-box pivot.
- Add pivot pie menu.
27 files changed, 363 insertions, 77 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index b8b27b0e8ba..7152069972d 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -2826,6 +2826,8 @@ def km_sequencerpreview(params): value=params.select_mouse_value_fallback, legacy=params.legacy, ), + op_menu_pie("SEQUENCER_MT_pivot_pie", {"type": 'PERIOD', "value": 'PRESS'}), + ("sequencer.view_all_preview", {"type": 'HOME', "value": 'PRESS'}, None), ("sequencer.view_all_preview", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("sequencer.view_ghost_border", {"type": 'O', "value": 'PRESS'}, None), @@ -2862,6 +2864,18 @@ def km_sequencerpreview(params): *_template_items_context_menu("SEQUENCER_MT_preview_context_menu", params.context_menu_event), ]) + # 2D cursor. + if params.cursor_tweak_event: + items.extend([ + ("sequencer.cursor_set", params.cursor_set_event, None), + ("transform.translate", params.cursor_tweak_event, + {"properties": [("release_confirm", True), ("cursor_transform", True)]}), + ]) + else: + items.extend([ + ("sequencer.cursor_set", params.cursor_set_event, None), + ]) + return keymap @@ -7465,13 +7479,13 @@ def km_sequencer_editor_tool_select(params, *, fallback): _fallback_id("Sequencer Tool: Tweak", fallback), {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, {"items": [ - # TODO: Use 2D cursor for preview region (currently `sequencer.sample`). *([] if fallback else - _template_items_tool_select(params, "sequencer.select", "sequencer.sample", extend="toggle") + _template_items_tool_select(params, "sequencer.select", "sequencer.cursor_set", extend="toggle") ), *([] if (not params.use_fallback_tool_rmb) else _template_sequencer_generic_select( type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), + # Ignored for preview. *_template_items_change_frame(params), ]}, ) @@ -7490,6 +7504,7 @@ def km_sequencer_editor_tool_select_box(params, *, fallback): *_template_sequencer_select_for_fallback(params, fallback), # RMB select can already set the frame, match the tweak tool. + # Ignored for preview. *(_template_items_change_frame(params) if params.select_mouse == 'LEFTMOUSE' else []), ]}, @@ -7506,6 +7521,19 @@ def km_sequencer_editor_tool_generic_sample(params): ) +def km_sequencer_editor_tool_cursor(params): + return ( + "Sequencer Tool: Cursor", + {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, + {"items": [ + ("sequencer.cursor_set", {"type": params.tool_mouse, "value": 'PRESS'}, None), + # Don't use `tool_maybe_tweak_event` since it conflicts with `PRESS` that places the cursor. + ("transform.translate", params.tool_tweak_event, + {"properties": [("release_confirm", True), ("cursor_transform", True)]}), + ]}, + ) + + def km_sequencer_editor_tool_blade(_params): return ( "Sequencer Tool: Blade", @@ -7808,6 +7836,7 @@ def generate_keymaps(params=None): *(km_sequencer_editor_tool_select_box(params, fallback=fallback) for fallback in (False, True)), km_sequencer_editor_tool_blade(params), km_sequencer_editor_tool_generic_sample(params), + km_sequencer_editor_tool_cursor(params), km_sequencer_editor_tool_scale(params), km_sequencer_editor_tool_rotate(params), km_sequencer_editor_tool_move(params), diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 03a090255f6..58afb6d9203 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1042,6 +1042,22 @@ class SEQUENCER_MT_preview_context_menu(Menu): pass +class SEQUENCER_MT_pivot_pie(Menu): + bl_label = "Pivot Point" + + def draw(self, context): + layout = self.layout + pie = layout.menu_pie() + + tool_settings = context.tool_settings + sequencer_tool_settings = context.tool_settings.sequencer_tool_settings + + pie.prop_enum(sequencer_tool_settings, "pivot_point", value='CENTER') + pie.prop_enum(sequencer_tool_settings, "pivot_point", value='CURSOR') + pie.prop_enum(sequencer_tool_settings, "pivot_point", value='INDIVIDUAL_ORIGINS') + pie.prop_enum(sequencer_tool_settings, "pivot_point", value='MEDIAN') + + class SequencerButtonsPanel: bl_space_type = 'SEQUENCE_EDITOR' bl_region_type = 'UI' @@ -2185,6 +2201,22 @@ class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel): col.prop(st, "show_separate_color") +class SEQUENCER_PT_view_cursor(SequencerButtonsPanel_Output, Panel): + bl_category = "View" + bl_label = "2D Cursor" + + def draw(self, context): + layout = self.layout + + st = context.space_data + + layout.use_property_split = True + layout.use_property_decorate = False + + col = layout.column() + col.prop(st, "cursor_location", text="Location") + + class SEQUENCER_PT_frame_overlay(SequencerButtonsPanel_Output, Panel): bl_label = "Frame Overlay" bl_category = "View" @@ -2464,6 +2496,7 @@ classes = ( SEQUENCER_MT_color_tag_picker, SEQUENCER_MT_context_menu, SEQUENCER_MT_preview_context_menu, + SEQUENCER_MT_pivot_pie, SEQUENCER_PT_color_tag_picker, @@ -2500,6 +2533,7 @@ classes = ( SEQUENCER_PT_custom_props, SEQUENCER_PT_view, + SEQUENCER_PT_view_cursor, SEQUENCER_PT_frame_overlay, SEQUENCER_PT_view_safe_areas, SEQUENCER_PT_view_safe_areas_center_cut, diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 6478cff3597..008129cd389 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -2441,6 +2441,19 @@ class _defs_node_edit: class _defs_sequencer_generic: @ToolDef.from_fn + def cursor(): + return dict( + idname="builtin.cursor", + label="Cursor", + description=( + "Set the cursor location, drag to transform" + ), + icon="ops.generic.cursor", + keymap="Sequencer Tool: Cursor", + options={'KEYMAP_FALLBACK'}, + ) + + @ToolDef.from_fn def blade(): def draw_settings(_context, layout, tool): props = tool.operator_properties("sequencer.split") @@ -3094,6 +3107,8 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): ], 'PREVIEW': [ *_tools_select, + _defs_sequencer_generic.cursor, + None, _defs_sequencer_generic.translate, _defs_sequencer_generic.rotate, _defs_sequencer_generic.scale, @@ -3106,6 +3121,8 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): ], 'SEQUENCER_PREVIEW': [ *_tools_select, + _defs_sequencer_generic.cursor, + None, _defs_sequencer_generic.translate, _defs_sequencer_generic.rotate, _defs_sequencer_generic.scale, diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 927a29ed6b6..af6c8ea62b2 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -179,6 +179,9 @@ void DRW_viewport_data_free(struct DRWData *drw_data); bool DRW_opengl_context_release(void); void DRW_opengl_context_activate(bool drw_state); +/* We may want to move this into a more general location. */ +void DRW_draw_cursor_2d_ex(const struct ARegion *region, const float cursor[2]); + #ifdef __cplusplus } #endif diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 90bb3762473..bbd345271b1 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -28,6 +28,7 @@ #include "DNA_view3d_types.h" #include "ED_screen.h" +#include "ED_util.h" #include "ED_view3d.h" #include "GPU_immediate.h" @@ -226,6 +227,46 @@ static bool is_cursor_visible_2d(const DRWContextState *draw_ctx) return (sima->overlay.flag & SI_OVERLAY_SHOW_OVERLAYS) != 0; } +/* -------------------------------------------------------------------- */ +/** \name Generic Cursor + * \{ */ + +/** + * \note This doesn't require the draw context to be in use. + */ +void DRW_draw_cursor_2d_ex(const ARegion *region, const float cursor[2]) +{ + int co[2]; + UI_view2d_view_to_region(®ion->v2d, cursor[0], cursor[1], &co[0], &co[1]); + + /* Draw nice Anti Aliased cursor. */ + GPU_line_width(1.0f); + GPU_blend(GPU_BLEND_ALPHA); + GPU_line_smooth(true); + + /* Draw lines */ + float original_proj[4][4]; + GPU_matrix_projection_get(original_proj); + GPU_matrix_push(); + ED_region_pixelspace(region); + GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); + GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); + + GPUBatch *cursor_batch = DRW_cache_cursor_get(true); + + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); + GPU_batch_set_shader(cursor_batch, shader); + + GPU_batch_draw(cursor_batch); + + GPU_blend(GPU_BLEND_NONE); + GPU_line_smooth(false); + GPU_matrix_pop(); + GPU_matrix_projection_set(original_proj); +} + +/** \} */ + void DRW_draw_cursor_2d(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -236,33 +277,8 @@ void DRW_draw_cursor_2d(void) GPU_depth_test(GPU_DEPTH_NONE); if (is_cursor_visible_2d(draw_ctx)) { - SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; - int co[2]; - UI_view2d_view_to_region(®ion->v2d, sima->cursor[0], sima->cursor[1], &co[0], &co[1]); - - /* Draw nice Anti Aliased cursor. */ - GPU_line_width(1.0f); - GPU_blend(GPU_BLEND_ALPHA); - GPU_line_smooth(true); - - /* Draw lines */ - float original_proj[4][4]; - GPU_matrix_projection_get(original_proj); - GPU_matrix_push(); - ED_region_pixelspace(region); - GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); - GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); - - GPUBatch *cursor_batch = DRW_cache_cursor_get(true); - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); - GPU_batch_set_shader(cursor_batch, shader); - - GPU_batch_draw(cursor_batch); - - GPU_blend(GPU_BLEND_NONE); - GPU_line_smooth(false); - GPU_matrix_pop(); - GPU_matrix_projection_set(original_proj); + const SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; + DRW_draw_cursor_2d_ex(region, sima->cursor); } } /** \} */ diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h index 24fabaae05e..2646918cd3e 100644 --- a/source/blender/draw/intern/draw_view.h +++ b/source/blender/draw/intern/draw_view.h @@ -22,6 +22,8 @@ #pragma once +struct ARegion; + void DRW_draw_region_info(void); void DRW_clear_background(void); void DRW_draw_cursor(void); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 3958c7f9e34..8232df968ed 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -74,9 +74,17 @@ static bool change_frame_poll(bContext *C) * this shouldn't show up in 3D editor (or others without 2D timeline view) via search */ if (area) { - if (ELEM(area->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) { + if (ELEM(area->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_CLIP)) { return true; } + if (area->spacetype == SPACE_SEQ) { + /* Check the region type so tools (which are shared between preview/strip view) + * don't conflict with actions which can have the same key bound (2D cursor for example). */ + const ARegion *region = CTX_wm_region(C); + if (region && region->regiontype == RGN_TYPE_WINDOW) { + return true; + } + } if (area->spacetype == SPACE_GRAPH) { const SpaceGraph *sipo = area->spacedata.first; /* Driver Editor's X axis is not time. */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index b6936892803..92aeaf03329 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -68,7 +68,7 @@ void ED_region_do_layout(struct bContext *C, struct ARegion *region); void ED_region_do_draw(struct bContext *C, struct ARegion *region); void ED_region_exit(struct bContext *C, struct ARegion *region); void ED_region_remove(struct bContext *C, struct ScrArea *area, struct ARegion *region); -void ED_region_pixelspace(struct ARegion *region); +void ED_region_pixelspace(const struct ARegion *region); void ED_region_update_rect(struct ARegion *region); void ED_region_floating_init(struct ARegion *region); void ED_region_tag_redraw(struct ARegion *region); diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 0105af843bb..df132e6ae80 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -30,6 +30,7 @@ extern "C" { #endif +struct GPUBatch; struct Main; struct bContext; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 9967d36fd40..473674f1059 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -134,7 +134,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si GPU_blend(GPU_BLEND_NONE); } -void ED_region_pixelspace(ARegion *region) +void ED_region_pixelspace(const ARegion *region) { wmOrtho2_region_pixelspace(region); GPU_matrix_identity_set(); diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index 1471929defb..bf8cf89699d 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -22,6 +22,7 @@ set(INC ../../blenlib ../../blentranslation ../../depsgraph + ../../draw ../../gpu ../../imbuf ../../makesdna diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 655cfb9375c..50a74d9e636 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3397,3 +3397,64 @@ void SEQUENCER_OT_strip_color_tag_set(struct wmOperatorType *ot) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Set 2D Cursor Operator + * \{ */ + +static int sequencer_set_2d_cursor_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + SpaceSeq *sseq = CTX_wm_space_seq(C); + + float cursor_pixel[2]; + RNA_float_get_array(op->ptr, "location", cursor_pixel); + + SEQ_image_preview_unit_from_px(scene, cursor_pixel, sseq->cursor); + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + + return OPERATOR_FINISHED; +} + +static int sequencer_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *region = CTX_wm_region(C); + float cursor_pixel[2]; + UI_view2d_region_to_view( + ®ion->v2d, event->mval[0], event->mval[1], &cursor_pixel[0], &cursor_pixel[1]); + + RNA_float_set_array(op->ptr, "location", cursor_pixel); + + return sequencer_set_2d_cursor_exec(C, op); +} + +void SEQUENCER_OT_cursor_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set 2D Cursor"; + ot->description = "Set 2D cursor location"; + ot->idname = "SEQUENCER_OT_cursor_set"; + + /* api callbacks */ + ot->exec = sequencer_set_2d_cursor_exec; + ot->invoke = sequencer_set_2d_cursor_invoke; + ot->poll = sequencer_view_preview_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, + "location", + 2, + NULL, + -FLT_MAX, + FLT_MAX, + "Location", + "Cursor location in normalized preview coordinates", + -10.0f, + 10.0f); +} + +/** \} */ diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 730d4d11e78..5982a0a8993 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -165,6 +165,7 @@ void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot); void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot); void SEQUENCER_OT_strip_color_tag_set(struct wmOperatorType *ot); +void SEQUENCER_OT_cursor_set(struct wmOperatorType *ot); /* sequencer_select.c */ void SEQUENCER_OT_select_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 95f7b44264c..2c5f211b0e4 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -80,6 +80,7 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_strip_transform_fit); WM_operatortype_append(SEQUENCER_OT_strip_color_tag_set); + WM_operatortype_append(SEQUENCER_OT_cursor_set); /* sequencer_select.c */ WM_operatortype_append(SEQUENCER_OT_select_all); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index ad0ceb82709..c1f853270e9 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -41,6 +41,8 @@ #include "BKE_screen.h" #include "BKE_sequencer_offscreen.h" +#include "GPU_state.h" + #include "ED_screen.h" #include "ED_space_api.h" #include "ED_transform.h" @@ -53,6 +55,7 @@ #include "RNA_access.h" +#include "SEQ_transform.h" #include "SEQ_utils.h" #include "UI_interface.h" @@ -61,6 +64,9 @@ #include "IMB_imbuf.h" +/* Only for cursor drawing. */ +#include "DRW_engine.h" + /* Own include. */ #include "sequencer_intern.h" @@ -803,6 +809,17 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region) } } + { + GPU_color_mask(true, true, true, true); + GPU_depth_mask(false); + GPU_depth_test(GPU_DEPTH_NONE); + + float cursor_pixel[2]; + SEQ_image_preview_unit_to_px(scene, sseq->cursor, cursor_pixel); + + DRW_draw_cursor_2d_ex(region, cursor_pixel); + } + WM_gizmomap_draw(region->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D); if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) { diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6ed2c28a7eb..9dcd3a3e510 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -48,6 +48,8 @@ #include "ED_screen.h" #include "ED_space_api.h" +#include "SEQ_transform.h" + #include "WM_api.h" #include "WM_message.h" #include "WM_types.h" @@ -128,6 +130,11 @@ void setTransformViewAspect(TransInfo *t, float r_aspect[3]) ED_space_image_get_uv_aspect(sima, &r_aspect[0], &r_aspect[1]); } } + else if (t->spacetype == SPACE_SEQ) { + if (t->options & CTX_CURSOR) { + SEQ_image_preview_unit_to_px(t->scene, r_aspect, r_aspect); + } + } else if (t->spacetype == SPACE_CLIP) { SpaceClip *sclip = t->area->spacedata.first; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 1be46c03f85..3076b3e207f 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -222,6 +222,7 @@ typedef enum { TC_POSE, TC_ARMATURE_VERTS, TC_CURSOR_IMAGE, + TC_CURSOR_SEQUENCER, TC_CURSOR_VIEW3D, TC_CURVE_VERTS, TC_GRAPH_EDIT_DATA, diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index 557fa79e7ac..00be756878b 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -945,6 +945,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) break; case TC_ARMATURE_VERTS: case TC_CURSOR_IMAGE: + case TC_CURSOR_SEQUENCER: case TC_CURSOR_VIEW3D: case TC_CURVE_VERTS: case TC_GPENCIL: @@ -1037,6 +1038,7 @@ static void init_proportional_edit(TransInfo *t) case TC_POSE: /* Disable PET, its not usable in pose mode yet T32444. */ case TC_ARMATURE_VERTS: case TC_CURSOR_IMAGE: + case TC_CURSOR_SEQUENCER: case TC_CURSOR_VIEW3D: case TC_NLA_DATA: case TC_OBJECT_TEXSPACE: @@ -1112,6 +1114,7 @@ static void init_TransDataContainers(TransInfo *t, case TC_ACTION_DATA: case TC_GRAPH_EDIT_DATA: case TC_CURSOR_IMAGE: + case TC_CURSOR_SEQUENCER: case TC_CURSOR_VIEW3D: case TC_MASKING_DATA: case TC_NLA_DATA: @@ -1223,6 +1226,7 @@ static eTFlag flags_from_data_type(eTConvertType data_type) case TC_MESH_UV: return T_EDIT | T_POINTS | T_2D_EDIT; case TC_CURSOR_IMAGE: + case TC_CURSOR_SEQUENCER: return T_2D_EDIT; case TC_PARTICLE_VERTS: return T_POINTS; @@ -1249,6 +1253,9 @@ static eTConvertType convert_type_get(const TransInfo *t, Object **r_obj_armatur if (t->spacetype == SPACE_IMAGE) { convert_type = TC_CURSOR_IMAGE; } + else if (t->spacetype == SPACE_SEQ) { + convert_type = TC_CURSOR_SEQUENCER; + } else { convert_type = TC_CURSOR_VIEW3D; } @@ -1396,6 +1403,9 @@ void createTransData(bContext *C, TransInfo *t) case TC_CURSOR_IMAGE: createTransCursor_image(t); break; + case TC_CURSOR_SEQUENCER: + createTransCursor_sequencer(t); + break; case TC_CURSOR_VIEW3D: createTransCursor_view3d(t); break; @@ -1714,8 +1724,11 @@ void recalcData(TransInfo *t) case TC_CURSOR_IMAGE: recalcData_cursor_image(t); break; + case TC_CURSOR_SEQUENCER: + recalcData_cursor_sequencer(t); + break; case TC_CURSOR_VIEW3D: - recalcData_cursor(t); + recalcData_cursor_view3d(t); break; case TC_GRAPH_EDIT_DATA: recalcData_graphedit(t); diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index 66d84bca2d2..e4f2ab05bec 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -85,9 +85,11 @@ void special_aftertrans_update__pose(bContext *C, TransInfo *t); /* transform_convert_cursor.c */ void createTransCursor_image(TransInfo *t); +void createTransCursor_sequencer(TransInfo *t); void createTransCursor_view3d(TransInfo *t); void recalcData_cursor_image(TransInfo *t); -void recalcData_cursor(TransInfo *t); +void recalcData_cursor_sequencer(TransInfo *t); +void recalcData_cursor_view3d(TransInfo *t); /* transform_convert_curve.c */ void createTransCurveVerts(TransInfo *t); diff --git a/source/blender/editors/transform/transform_convert_cursor.c b/source/blender/editors/transform/transform_convert_cursor.c index 1f3eff31205..8a4a13eb4db 100644 --- a/source/blender/editors/transform/transform_convert_cursor.c +++ b/source/blender/editors/transform/transform_convert_cursor.c @@ -19,6 +19,8 @@ /** \file * \ingroup edtransform + * + * Instead of transforming the selection, move the 2D/3D cursor. */ #include "DNA_space_types.h" @@ -35,18 +37,12 @@ #include "transform_convert.h" /* -------------------------------------------------------------------- */ -/** \name Cursor Transform Creation - * - * Instead of transforming the selection, move the 2D/3D cursor. - * +/** \name Shared 2D Cursor Utilities * \{ */ -void createTransCursor_image(TransInfo *t) +static void createTransCursor_2D_impl(TransInfo *t, float cursor_location[2]) { TransData *td; - SpaceImage *sima = t->area->spacedata.first; - float *cursor_location = sima->cursor; - { BLI_assert(t->data_container_len == 1); TransDataContainer *tc = t->data_container; @@ -57,7 +53,7 @@ void createTransCursor_image(TransInfo *t) td->flag = TD_SELECTED; - /* UV coords are scaled by aspects (see UVsToTransData). This also applies for the Cursor in the + /* UV coords are scaled by aspects (see #UVsToTransData). This also applies for the Cursor in the * UV Editor which also means that for display and when the cursor coords are flushed * (recalcData_cursor_image), these are converted each time. */ cursor_location[0] = cursor_location[0] * t->aspect[0]; @@ -74,6 +70,62 @@ void createTransCursor_image(TransInfo *t) copy_v3_v3(td->iloc, cursor_location); } +static void recalcData_cursor_2D_impl(TransInfo *t) +{ + TransDataContainer *tc = t->data_container; + TransData *td = tc->data; + float aspect_inv[2]; + + aspect_inv[0] = 1.0f / t->aspect[0]; + aspect_inv[1] = 1.0f / t->aspect[1]; + + td->loc[0] = td->loc[0] * aspect_inv[0]; + td->loc[1] = td->loc[1] * aspect_inv[1]; + + DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Image Cursor + * \{ */ + +void createTransCursor_image(TransInfo *t) +{ + SpaceImage *sima = t->area->spacedata.first; + createTransCursor_2D_impl(t, sima->cursor); +} + +void recalcData_cursor_image(TransInfo *t) +{ + recalcData_cursor_2D_impl(t); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sequencer Cursor + * \{ */ + +void createTransCursor_sequencer(TransInfo *t) +{ + SpaceSeq *sseq = t->area->spacedata.first; + + createTransCursor_2D_impl(t, sseq->cursor); +} + +void recalcData_cursor_sequencer(TransInfo *t) +{ + recalcData_cursor_2D_impl(t); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name View 3D Cursor + * \{ */ + void createTransCursor_view3d(TransInfo *t) { TransData *td; @@ -133,28 +185,7 @@ void createTransCursor_view3d(TransInfo *t) td->ext->rotOrder = cursor->rotation_mode; } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Recalc Cursor - * \{ */ - -void recalcData_cursor_image(TransInfo *t) -{ - TransDataContainer *tc = t->data_container; - TransData *td = tc->data; - float aspect_inv[2]; - - aspect_inv[0] = 1.0f / t->aspect[0]; - aspect_inv[1] = 1.0f / t->aspect[1]; - - td->loc[0] = td->loc[0] * aspect_inv[0]; - td->loc[1] = td->loc[1] * aspect_inv[1]; - - DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE); -} - -void recalcData_cursor(TransInfo *t) +void recalcData_cursor_view3d(TransInfo *t) { DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE); } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index fa323f0c1f7..09c338046ed 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -46,6 +46,8 @@ #include "BKE_modifier.h" #include "BKE_paint.h" +#include "SEQ_transform.h" + #include "ED_clip.h" #include "ED_image.h" #include "ED_object.h" @@ -885,12 +887,18 @@ void calculateCenterCursor(TransInfo *t, float r_center[3]) void calculateCenterCursor2D(TransInfo *t, float r_center[2]) { + float cursor_local_buf[2]; const float *cursor = NULL; if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)t->area->spacedata.first; cursor = sima->cursor; } + if (t->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)t->area->spacedata.first; + SEQ_image_preview_unit_to_px(t->scene, sseq->cursor, cursor_local_buf); + cursor = cursor_local_buf; + } else if (t->spacetype == SPACE_CLIP) { SpaceClip *space_clip = (SpaceClip *)t->area->spacedata.first; cursor = space_clip->cursor; @@ -1069,7 +1077,7 @@ static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[ calculateCenterMedian(t, r_center); break; case V3D_AROUND_CURSOR: - if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) { + if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP)) { calculateCenterCursor2D(t, r_center); } else if (t->spacetype == SPACE_GRAPH) { diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index aa4d5c03d74..b25a182926e 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -284,23 +284,25 @@ static bool gizmo2d_calc_center(const bContext *C, float r_center[2]) ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, sima->around, &has_select); } else if (area->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = area->spacedata.first; + const int pivot_point = scene->toolsettings->sequencer_tool_settings->pivot_point; ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); SEQ_filter_selected_strips(strips); + has_select = SEQ_collection_len(strips) != 0; - if (SEQ_collection_len(strips) <= 0) { - SEQ_collection_free(strips); - return false; + if (pivot_point == V3D_AROUND_CURSOR) { + SEQ_image_preview_unit_to_px(scene, sseq->cursor, r_center); } - - has_select = true; - Sequence *seq; - SEQ_ITERATOR_FOREACH (seq, strips) { - float origin[2]; - SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, origin); - add_v2_v2(r_center, origin); + else if (has_select) { + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, strips) { + float origin[2]; + SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, origin); + add_v2_v2(r_center, origin); + } + mul_v2_fl(r_center, 1.0f / SEQ_collection_len(strips)); } - mul_v2_fl(r_center, 1.0f / SEQ_collection_len(strips)); SEQ_collection_free(strips); } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index aa74e7712c0..bace73b88ba 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -647,6 +647,9 @@ typedef struct SpaceSeq { int draw_flag; char _pad[4]; + /** 2D cursor for transform. */ + float cursor[2]; + /** Grease-pencil data. */ struct bGPdata *gpd; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5b46dfa8210..3468cab9eea 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3539,7 +3539,9 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna) }; static const EnumPropertyItem pivot_points[] = { + {V3D_AROUND_CENTER_BOUNDS, "CENTER", ICON_PIVOT_BOUNDBOX, "Bounding Box Center", ""}, {V3D_AROUND_CENTER_MEDIAN, "MEDIAN", ICON_PIVOT_MEDIAN, "Median Point", ""}, + {V3D_AROUND_CURSOR, "CURSOR", ICON_PIVOT_CURSOR, "2D Cursor", "Pivot around the 2D cursor"}, {V3D_AROUND_LOCAL_ORIGINS, "INDIVIDUAL_ORIGINS", ICON_PIVOT_INDIVIDUAL, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 652d2545e67..9d8e06b3c56 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -5690,6 +5690,13 @@ static void rna_def_space_sequencer(BlenderRNA *brna) rna_def_space_sequencer_preview_overlay(brna); rna_def_space_sequencer_timeline_overlay(brna); + + /* transform */ + prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "cursor"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "2D Cursor Location", "2D cursor location for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); } static void rna_def_space_text(BlenderRNA *brna) diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index 328efb9424a..69db21d4c63 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -70,6 +70,13 @@ void SEQ_image_transform_final_quad_get(const struct Scene *scene, const struct Sequence *seq, float r_quad[4][2]); +void SEQ_image_preview_unit_to_px(const struct Scene *scene, + const float co_src[2], + float co_dst[2]); +void SEQ_image_preview_unit_from_px(const struct Scene *scene, + const float co_src[2], + float co_dst[2]); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 8c214f66b96..f014c7a312a 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -520,3 +520,15 @@ void SEQ_image_transform_final_quad_get(const Scene *scene, mul_v2_v2(r_quad[2], mirror); mul_v2_v2(r_quad[3], mirror); } + +void SEQ_image_preview_unit_to_px(const Scene *scene, const float co_src[2], float co_dst[2]) +{ + co_dst[0] = co_src[0] * scene->r.xsch; + co_dst[1] = co_src[1] * scene->r.ysch; +} + +void SEQ_image_preview_unit_from_px(const Scene *scene, const float co_src[2], float co_dst[2]) +{ + co_dst[0] = co_src[0] / scene->r.xsch; + co_dst[1] = co_src[1] / scene->r.ysch; +} |