Refactor: Cleanup VSE retiming selection code
Retiming selection was way more complicated than it needed to be, with lots of duplicate code between `sequencer_select_exec` and `sequencer_retiming_key_select_exec` and logic scattered all over the place. This patch standardizes retiming selection so that all of its logic is performed first. If it turns out that the cursor is not able to select any keys, it continues with strip selection. This decreases linecount and makes everything clearer. There should be no regressions user-side, but this patch does fix a couple bugs and makes retiming selection more robust: - Prior to this patch, if no retiming keys were selected, attempting to toggle any key with the tweak tool would select and deselect the key immediately. - Prior to this patch, retiming keys would still show if overlays were turned off, but "retiming display" was turned on. This patch also renames/changes some functions to make them clearer: - `retiming_keys_are_visible` -> `retiming_keys_can_be_displayed`, since having retiming keys on in the overlays does not guarantee that they are visible in any strips currently. Note that I've altered this function slightly too, this fixes the second bug mentioned above. - `try_to_realize_virtual_keys` -> `try_to_realize_fake_keys`, to make naming more consistent with existing functions. - Fix typo in `retiming_mousover_key_get` - Remove `use_retiming_mode` helper function since new code doesn't need it -- was confusingly named anyways - Add `key` and `key_owner` arguments to `sequencer_retiming_key_select_exec` and `sequencer_retiming_select_linked_time` to avoid having to recalculate the key at cursor position over and over again Pull Request: https://projects.blender.org/blender/blender/pulls/125468
This commit is contained in:
committed by
Aras Pranckevicius
parent
570ac3ebaa
commit
2314f59417
@@ -359,9 +359,15 @@ void SEQUENCER_OT_retiming_freeze_frame_add(wmOperatorType *ot);
|
||||
void SEQUENCER_OT_retiming_transition_add(wmOperatorType *ot);
|
||||
void SEQUENCER_OT_retiming_key_delete(wmOperatorType *ot);
|
||||
void SEQUENCER_OT_retiming_segment_speed_set(wmOperatorType *ot);
|
||||
int sequencer_retiming_key_select_exec(bContext *C, wmOperator *op);
|
||||
int sequencer_retiming_key_select_exec(bContext *C,
|
||||
wmOperator *op,
|
||||
SeqRetimingKey *key,
|
||||
const Sequence *key_owner);
|
||||
/* Select a key and all following keys. */
|
||||
int sequencer_retiming_select_linked_time(bContext *C, wmOperator *op);
|
||||
int sequencer_retiming_select_linked_time(bContext *C,
|
||||
wmOperator *op,
|
||||
SeqRetimingKey *key,
|
||||
const Sequence *key_owner);
|
||||
int sequencer_select_exec(bContext *C, wmOperator *op);
|
||||
int sequencer_retiming_select_all_exec(bContext *C, wmOperator *op);
|
||||
int sequencer_retiming_box_select_exec(bContext *C, wmOperator *op);
|
||||
@@ -373,11 +379,11 @@ void sequencer_retiming_keys_draw(const TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext &strip_ctx);
|
||||
void sequencer_retiming_speed_draw(const TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext &strip_ctx);
|
||||
SeqRetimingKey *try_to_realize_virtual_keys(const bContext *C, Sequence *seq, const int mval[2]);
|
||||
SeqRetimingKey *retiming_mousover_key_get(const bContext *C, const int mval[2], Sequence **r_seq);
|
||||
SeqRetimingKey *try_to_realize_fake_keys(const bContext *C, Sequence *seq, const int mval[2]);
|
||||
SeqRetimingKey *retiming_mouseover_key_get(const bContext *C, const int mval[2], Sequence **r_seq);
|
||||
int left_fake_key_frame_get(const bContext *C, const Sequence *seq);
|
||||
int right_fake_key_frame_get(const bContext *C, const Sequence *seq);
|
||||
bool retiming_keys_are_visible(const SpaceSeq *sseq);
|
||||
bool retiming_keys_can_be_displayed(const SpaceSeq *sseq);
|
||||
rctf seq_retiming_keys_box_get(const Scene *scene, const View2D *v2d, const Sequence *seq);
|
||||
|
||||
/* `sequencer_timeline_draw.cc` */
|
||||
|
||||
@@ -778,68 +778,50 @@ static bool select_key(const Editing *ed,
|
||||
return true;
|
||||
}
|
||||
|
||||
int sequencer_retiming_select_linked_time(bContext *C, wmOperator *op)
|
||||
int sequencer_retiming_select_linked_time(bContext *C,
|
||||
wmOperator *op,
|
||||
SeqRetimingKey *key,
|
||||
const Sequence *key_owner)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
const int mval[2] = {RNA_int_get(op->ptr, "mouse_x"), RNA_int_get(op->ptr, "mouse_y")};
|
||||
|
||||
Sequence *seq_key_owner = nullptr;
|
||||
SeqRetimingKey *key = retiming_mousover_key_get(C, mval, &seq_key_owner);
|
||||
|
||||
if (key == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (!RNA_boolean_get(op->ptr, "extend")) {
|
||||
SEQ_retiming_selection_clear(ed);
|
||||
}
|
||||
for (; key <= SEQ_retiming_last_key_get(seq_key_owner); key++) {
|
||||
for (; key <= SEQ_retiming_last_key_get(key_owner); key++) {
|
||||
select_key(ed, key, false, false);
|
||||
}
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
int sequencer_retiming_key_select_exec(bContext *C, wmOperator *op)
|
||||
int sequencer_retiming_key_select_exec(bContext *C,
|
||||
wmOperator *op,
|
||||
SeqRetimingKey *key,
|
||||
const Sequence *key_owner)
|
||||
{
|
||||
if (RNA_boolean_get(op->ptr, "linked_time")) {
|
||||
return sequencer_retiming_select_linked_time(C, op);
|
||||
return sequencer_retiming_select_linked_time(C, op, key, key_owner);
|
||||
}
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
const int mval[2] = {RNA_int_get(op->ptr, "mouse_x"), RNA_int_get(op->ptr, "mouse_y")};
|
||||
|
||||
eSeqHandle hand;
|
||||
Sequence *seq_key_owner = nullptr;
|
||||
SeqRetimingKey *key = retiming_mousover_key_get(C, mval, &seq_key_owner);
|
||||
|
||||
/* Try to realize "fake" key, since it is clicked on. */
|
||||
if (key == nullptr && seq_key_owner != nullptr) {
|
||||
key = try_to_realize_virtual_keys(C, seq_key_owner, mval);
|
||||
}
|
||||
|
||||
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
|
||||
const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
|
||||
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
|
||||
|
||||
/* Click on unselected key. */
|
||||
if (key != nullptr && !SEQ_retiming_selection_contains(ed, key) && !toggle) {
|
||||
if (!SEQ_retiming_selection_contains(ed, key) && !toggle) {
|
||||
select_key(ed, key, false, deselect_all);
|
||||
}
|
||||
|
||||
/* Clicked on any key, waiting to click release. */
|
||||
if (key != nullptr && wait_to_deselect_others && !toggle) {
|
||||
if (wait_to_deselect_others && !toggle) {
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
/* Click on strip, do strip selection. */
|
||||
const Sequence *seq_click_exact = find_nearest_seq(scene, UI_view2d_fromcontext(C), mval, &hand);
|
||||
if (seq_click_exact != nullptr && key == nullptr) {
|
||||
SEQ_retiming_selection_clear(ed);
|
||||
return sequencer_select_exec(C, op);
|
||||
}
|
||||
|
||||
/* Selection after click is released. */
|
||||
const bool changed = select_key(ed, key, toggle, deselect_all);
|
||||
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
#define KEY_SIZE (10 * U.pixelsize)
|
||||
#define KEY_CENTER (UI_view2d_view_to_region_y(v2d, strip_y_rescale(seq, 0.0f)) + 4 + KEY_SIZE / 2)
|
||||
|
||||
bool retiming_keys_are_visible(const SpaceSeq *sseq)
|
||||
bool retiming_keys_can_be_displayed(const SpaceSeq *sseq)
|
||||
{
|
||||
return (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_RETIMING) != 0;
|
||||
return (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_RETIMING) &&
|
||||
(sseq->flag & SEQ_SHOW_OVERLAY);
|
||||
}
|
||||
|
||||
static float strip_y_rescale(const Sequence *seq, const float y_value)
|
||||
@@ -140,7 +141,7 @@ static bool retiming_fake_key_is_clicked(const bContext *C,
|
||||
return distance < RETIME_KEY_MOUSEOVER_THRESHOLD;
|
||||
}
|
||||
|
||||
SeqRetimingKey *try_to_realize_virtual_keys(const bContext *C, Sequence *seq, const int mval[2])
|
||||
SeqRetimingKey *try_to_realize_fake_keys(const bContext *C, Sequence *seq, const int mval[2])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SeqRetimingKey *key = nullptr;
|
||||
@@ -203,7 +204,7 @@ static SeqRetimingKey *mouse_over_key_get_from_strip(const bContext *C,
|
||||
return best_key;
|
||||
}
|
||||
|
||||
SeqRetimingKey *retiming_mousover_key_get(const bContext *C, const int mval[2], Sequence **r_seq)
|
||||
SeqRetimingKey *retiming_mouseover_key_get(const bContext *C, const int mval[2], Sequence **r_seq)
|
||||
{
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
@@ -236,7 +237,7 @@ static bool can_draw_retiming(const TimelineDrawContext *timeline_ctx,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!retiming_keys_are_visible(timeline_ctx->sseq)) {
|
||||
if (!retiming_keys_can_be_displayed(timeline_ctx->sseq)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +466,8 @@ static int sequencer_de_select_all_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_are_visible(CTX_wm_space_seq(C))) {
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_can_be_displayed(CTX_wm_space_seq(C)))
|
||||
{
|
||||
return sequencer_retiming_select_all_exec(C, op);
|
||||
}
|
||||
|
||||
@@ -1129,12 +1130,6 @@ StripSelection ED_sequencer_pick_strip_and_handle(const Scene *scene,
|
||||
return selection;
|
||||
}
|
||||
|
||||
static bool use_retiming_mode(const bContext *C, const Sequence *seq_key_test)
|
||||
{
|
||||
return seq_key_test && SEQ_retiming_data_is_editable(seq_key_test) &&
|
||||
!sequencer_retiming_mode_is_active(C) && retiming_keys_are_visible(CTX_wm_space_seq(C));
|
||||
}
|
||||
|
||||
int sequencer_select_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
@@ -1156,8 +1151,34 @@ int sequencer_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_are_visible(CTX_wm_space_seq(C))) {
|
||||
return sequencer_retiming_key_select_exec(C, op);
|
||||
bool was_retiming = sequencer_retiming_mode_is_active(C);
|
||||
|
||||
MouseCoords mouse_co(v2d, RNA_int_get(op->ptr, "mouse_x"), RNA_int_get(op->ptr, "mouse_y"));
|
||||
|
||||
/* Check to see if the mouse cursor intersects with the retiming box; if so, `seq_key_owner` is
|
||||
* set. If the cursor intersects with a retiming key, `key` will be set too. */
|
||||
Sequence *seq_key_owner = nullptr;
|
||||
SeqRetimingKey *key = retiming_mouseover_key_get(C, mouse_co.region, &seq_key_owner);
|
||||
|
||||
/* If no key was found, the mouse cursor may still intersect with a "fake key" that has not been
|
||||
* realized yet. */
|
||||
if (seq_key_owner != nullptr && key == nullptr) {
|
||||
key = try_to_realize_fake_keys(C, seq_key_owner, mouse_co.region);
|
||||
}
|
||||
|
||||
if (key != nullptr && retiming_keys_can_be_displayed(CTX_wm_space_seq(C)) &&
|
||||
SEQ_retiming_data_is_editable(seq_key_owner))
|
||||
{
|
||||
if (!was_retiming) {
|
||||
ED_sequencer_deselect_all(scene);
|
||||
}
|
||||
return sequencer_retiming_key_select_exec(C, op, key, seq_key_owner);
|
||||
}
|
||||
|
||||
/* We should only reach here if no retiming selection is happening. */
|
||||
if (was_retiming) {
|
||||
SEQ_retiming_selection_clear(ed);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
}
|
||||
|
||||
bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
@@ -1166,8 +1187,6 @@ int sequencer_select_exec(bContext *C, wmOperator *op)
|
||||
bool toggle = RNA_boolean_get(op->ptr, "toggle");
|
||||
bool center = RNA_boolean_get(op->ptr, "center");
|
||||
|
||||
MouseCoords mouse_co(v2d, RNA_int_get(op->ptr, "mouse_x"), RNA_int_get(op->ptr, "mouse_y"));
|
||||
|
||||
StripSelection selection;
|
||||
if (region->regiontype == RGN_TYPE_PREVIEW) {
|
||||
selection.seq1 = seq_select_seq_from_preview(C, mouse_co.region, toggle, extend, center);
|
||||
@@ -1176,24 +1195,16 @@ int sequencer_select_exec(bContext *C, wmOperator *op)
|
||||
selection = ED_sequencer_pick_strip_and_handle(scene, v2d, mouse_co.view);
|
||||
}
|
||||
|
||||
Sequence *seq_key_test = nullptr;
|
||||
SeqRetimingKey *key = retiming_mousover_key_get(C, mouse_co.region, &seq_key_test);
|
||||
|
||||
/* NOTE: `side_of_frame` and `linked_time` functionality is designed to be shared on one
|
||||
* keymap, therefore both properties can be true at the same time. */
|
||||
if (selection.seq1 && RNA_boolean_get(op->ptr, "linked_time")) {
|
||||
if (use_retiming_mode(C, seq_key_test)) {
|
||||
return sequencer_retiming_select_linked_time(C, op);
|
||||
}
|
||||
else {
|
||||
if (!extend && !toggle) {
|
||||
ED_sequencer_deselect_all(scene);
|
||||
}
|
||||
select_linked_time(scene, selection, extend, deselect, toggle);
|
||||
sequencer_select_do_updates(C, scene);
|
||||
sequencer_select_set_active(scene, selection.seq1);
|
||||
return OPERATOR_FINISHED;
|
||||
if (!extend && !toggle) {
|
||||
ED_sequencer_deselect_all(scene);
|
||||
}
|
||||
select_linked_time(scene, selection, extend, deselect, toggle);
|
||||
sequencer_select_do_updates(C, scene);
|
||||
sequencer_select_set_active(scene, selection.seq1);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* Select left, right or overlapping the current frame. */
|
||||
@@ -1234,24 +1245,6 @@ int sequencer_select_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
if (use_retiming_mode(C, seq_key_test)) {
|
||||
|
||||
/* Realize "fake" key, if it is clicked on. */
|
||||
if (key == nullptr && seq_key_test != nullptr) {
|
||||
key = try_to_realize_virtual_keys(C, seq_key_test, mouse_co.region);
|
||||
}
|
||||
|
||||
bool retiming_key_clicked = (key != nullptr);
|
||||
|
||||
if (seq_key_test && retiming_key_clicked) {
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
ED_sequencer_deselect_all(scene);
|
||||
SEQ_retiming_selection_clear(ed);
|
||||
SEQ_retiming_selection_append(key);
|
||||
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
/* Deselect everything */
|
||||
@@ -1369,7 +1362,8 @@ static int sequencer_select_handle_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_are_visible(CTX_wm_space_seq(C))) {
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_can_be_displayed(CTX_wm_space_seq(C)))
|
||||
{
|
||||
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
@@ -1382,8 +1376,8 @@ static int sequencer_select_handle_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Ignore clicks on retiming keys. */
|
||||
Sequence *seq_key_test = nullptr;
|
||||
retiming_mousover_key_get(C, mouse_co.region, &seq_key_test);
|
||||
if (use_retiming_mode(C, seq_key_test) && seq_key_test != nullptr) {
|
||||
SeqRetimingKey *key = retiming_mouseover_key_get(C, mouse_co.region, &seq_key_test);
|
||||
if (key != nullptr) {
|
||||
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
@@ -2022,7 +2016,8 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_are_visible(CTX_wm_space_seq(C))) {
|
||||
if (sequencer_retiming_mode_is_active(C) && retiming_keys_can_be_displayed(CTX_wm_space_seq(C)))
|
||||
{
|
||||
return sequencer_retiming_box_select_exec(C, op);
|
||||
}
|
||||
|
||||
|
||||
@@ -645,7 +645,7 @@ static bool is_mouse_over_retiming_key(const Scene *scene,
|
||||
{
|
||||
const SpaceSeq *sseq = static_cast<SpaceSeq *>(area->spacedata.first);
|
||||
|
||||
if (!SEQ_retiming_data_is_editable(seq) || !retiming_keys_are_visible(sseq)) {
|
||||
if (!SEQ_retiming_data_is_editable(seq) || !retiming_keys_can_be_displayed(sseq)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user