Page MenuHome
Paste P1123

Sequencer: Drag-all-selected experiment (V2)
ActivePublic

Authored by Julian Eisel (Severin) on Oct 1 2019, 8:19 PM.
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 1839dd5f322..2a8231ed1d2 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -2394,7 +2394,10 @@ def km_sequencer(params):
),
("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'},
{"properties": [("extend", False), ("deselect_all", True),
- ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False)]}),
+ ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False), ("exit_if_selected", True)]}),
+ ("sequencer.select", {"type": params.select_mouse, "value": 'RELEASE'},
+ {"properties": [("extend", False), ("deselect_all", True),
+ ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False), ("exit_if_selected", False)]}),
("sequencer.select", {"type": params.select_mouse, "value": 'PRESS', "shift": True},
{"properties": [("extend", True), ("linked_handle", False), ("left_right", 'NONE'), ("linked_time", False)]}),
("sequencer.select", {"type": params.select_mouse, "value": 'PRESS', "alt": True},
@@ -2429,7 +2432,8 @@ def km_sequencer(params):
("wm.context_set_int", {"type": 'O', "value": 'PRESS'},
{"properties": [("data_path", 'scene.sequence_editor.overlay_frame'), ("value", 0)]}),
("transform.seq_slide", {"type": 'G', "value": 'PRESS'}, None),
- ("transform.seq_slide", {"type": params.select_tweak, "value": 'ANY'}, None),
+ ("transform.seq_slide", {"type": params.select_mouse, "value": 'PRESS'},
+ {"properties": [("wait_for_tweak", True)]}),
("transform.transform", {"type": 'E', "value": 'PRESS'},
{"properties": [("mode", 'TIME_EXTEND')]}),
("marker.add", {"type": 'M', "value": 'PRESS'}, None),
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index affb6d3fd88..39cc353e197 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -328,6 +328,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle");
const bool linked_time = RNA_boolean_get(op->ptr, "linked_time");
+ const bool exit_if_selected = RNA_boolean_get(op->ptr, "exit_if_selected");
int left_right = RNA_enum_get(op->ptr, "left_right");
Sequence *seq, *neighbor, *act_orig;
@@ -342,6 +343,44 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
seq = find_nearest_seq(scene, v2d, &hand, event->mval);
+ if (exit_if_selected && seq && (seq->flag & SELECT)) {
+ /* Allow tweaks. */
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+ if (seq && (seq->flag & SELECT)) {
+ Sequence *iter_seq;
+ bool any_other_selected = false;
+
+ SEQP_BEGIN (ed, iter_seq) {
+ if ((iter_seq->flag & SELECT) && (iter_seq != seq)) {
+ any_other_selected = true;
+ break;
+ }
+ }
+ SEQ_END;
+
+ /* All we would do is selecting an item that is already selected. Exit. */
+ if (any_other_selected == false) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+ }
+ if (!seq) {
+ Sequence *iter_seq;
+ bool any_selected = false;
+
+ SEQP_BEGIN (ed, iter_seq) {
+ if (iter_seq->flag & SELECT) {
+ any_selected = true;
+ break;
+ }
+ }
+ SEQ_END;
+
+ if (any_selected == false) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+ }
+
// XXX - not nice, Ctrl+RMB needs to do left_right only when not over a strip
if (seq && linked_time && (left_right == SEQ_SELECT_LR_MOUSE)) {
left_right = SEQ_SELECT_LR_NONE;
@@ -598,6 +637,12 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
"Select based on the current frame side the cursor is on");
RNA_def_boolean(
ot->srna, "linked_time", 0, "Linked Time", "Select other strips at the same time");
+ RNA_def_boolean(
+ ot->srna,
+ "exit_if_selected",
+ false,
+ "Exit if selected",
+ "Do not perform any selection change if the strip to be selected already is selected");
}
/* run recursively to select linked */
@@ -1038,7 +1083,8 @@ static const EnumPropertyItem sequencer_prop_select_grouped_types[] = {
"EFFECT_LINK",
0,
"Effect/Linked",
- "Other strips affected by the active one (sharing some time, and below or effect-assigned)"},
+ "Other strips affected by the active one (sharing some time, and below or "
+ "effect-assigned)"},
{SEQ_SELECT_GROUP_OVERLAP, "OVERLAP", 0, "Overlap", "Overlapping time"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 67ea0f255fc..bff4d6fe71a 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -54,6 +54,7 @@
#include "BKE_editmesh_bvh.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
+#include "BKE_global.h"
#include "BKE_particle.h"
#include "BKE_unit.h"
#include "BKE_scene.h"
@@ -832,13 +833,18 @@ enum {
TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
};
-static bool transform_modal_item_poll(const wmOperator *op, int value)
+static int transform_modal_item_poll(const wmOperator *op, int value)
{
const TransInfo *t = op->customdata;
+
+ if (t->state == TRANS_WAITING) {
+ return KEYMAP_MODAL_RUN_ONLY;
+ }
+
switch (value) {
case TFM_MODAL_CANCEL: {
if ((t->flag & T_RELEASE_CONFIRM) && ISMOUSE(t->launch_event)) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
@@ -846,20 +852,20 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
case TFM_MODAL_PROPSIZE_UP:
case TFM_MODAL_PROPSIZE_DOWN: {
if ((t->flag & T_PROP_EDIT) == 0) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
case TFM_MODAL_ADD_SNAP:
case TFM_MODAL_REMOVE_SNAP: {
if (t->spacetype != SPACE_VIEW3D) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
else if (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
else if (!validSnap(t)) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
@@ -870,43 +876,43 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
case TFM_MODAL_PLANE_Y:
case TFM_MODAL_PLANE_Z: {
if (t->flag & T_NO_CONSTRAINT) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
if (!ELEM(value, TFM_MODAL_AXIS_X, TFM_MODAL_AXIS_Y)) {
if (t->flag & T_2D_EDIT) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
}
break;
}
case TFM_MODAL_CONS_OFF: {
if ((t->con.mode & CON_APPLY) == 0) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
case TFM_MODAL_EDGESLIDE_UP:
case TFM_MODAL_EDGESLIDE_DOWN: {
if (t->mode != TFM_EDGE_SLIDE) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
case TFM_MODAL_INSERTOFS_TOGGLE_DIR: {
if (t->spacetype != SPACE_NODE) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
case TFM_MODAL_AUTOIK_LEN_INC:
case TFM_MODAL_AUTOIK_LEN_DEC: {
if ((t->flag & T_AUTOIK) == 0) {
- return false;
+ return KEYMAP_MODAL_SKIP;
}
break;
}
}
- return true;
+ return KEYMAP_MODAL_RUN_AND_DRAW;
}
/* called in transform_ops.c, on each regeneration of keymaps */
@@ -1044,13 +1050,30 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
}
}
-int transformEvent(TransInfo *t, const wmEvent *event)
+int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
{
char cmode = constraintModeToChar(t);
bool handled = false;
const int modifiers_prev = t->modifiers;
const int mode_prev = t->mode;
+ if (t->state == TRANS_WAITING) {
+ if ((event->type == t->launch_event) && (event->val == KM_RELEASE)) {
+ t->state = TRANS_CANCEL;
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+ else if (ISTWEAK(event->type)) {
+ bContext *C = t->context;
+ initTransform(C, t, op, event, t->mode);
+ t->context = C;
+ G.moving = special_transform_moving(t);
+ }
+ else {
+ t->state = TRANS_WAITING;
+ return OPERATOR_PASS_THROUGH;
+ }
+ }
+
t->redraw |= handleMouseInput(t, &t->mouse, event);
/* Handle modal numinput events first, if already activated. */
@@ -1625,7 +1648,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
WM_window_status_area_tag_redraw(CTX_wm_window(t->context));
}
- if (handled || t->redraw) {
+ if (handled || t->redraw || ELEM(t->state, TRANS_CONFIRM, TRANS_CANCEL)) {
return 0;
}
else {
@@ -2323,6 +2346,17 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* added initialize, for external calls to set stuff in TransInfo, like undo string */
+ if (op && (t->state != TRANS_WAITING) &&
+ ((prop = RNA_struct_find_property(op->ptr, "wait_for_tweak")) &&
+ RNA_property_is_set(op->ptr, prop))) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ t->mode = mode;
+ t->state = TRANS_WAITING;
+ t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
+ return true;
+ }
+ }
+
t->state = TRANS_STARTING;
if ((prop = RNA_struct_find_property(op->ptr, "cursor_transform")) &&
@@ -2785,7 +2819,10 @@ int transformEnd(bContext *C, TransInfo *t)
t->context = C;
- if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING) {
+ if (t->state == TRANS_WAITING) {
+ exit_code = 0;
+ }
+ else if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING) {
/* handle restoring objects */
if (t->state == TRANS_CANCEL) {
/* exception, edge slide transformed UVs too */
@@ -2797,7 +2834,10 @@ int transformEnd(bContext *C, TransInfo *t)
}
exit_code = OPERATOR_CANCELLED;
- restoreTransObjects(t); // calls recalcData()
+ if (t->depsgraph) { /* Just some silly NULL-check to ensure this is only called after correct
+ initialization */
+ restoreTransObjects(t); // calls recalcData()
+ }
}
else {
if (t->flag & T_CLNOR_REBUILD) {
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index ff2afbc0cd7..ba9172cb55f 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -714,6 +714,7 @@ typedef struct TransInfo {
/* transinfo->state */
enum {
+ TRANS_WAITING = -1,
TRANS_STARTING = 0,
TRANS_RUNNING = 1,
TRANS_CONFIRM = 2,
@@ -879,7 +880,7 @@ bool initTransform(struct bContext *C,
const struct wmEvent *event,
int mode);
void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op);
-int transformEvent(TransInfo *t, const struct wmEvent *event);
+int transformEvent(TransInfo *t, struct wmOperator *op, const struct wmEvent *event);
void transformApply(struct bContext *C, TransInfo *t);
int transformEnd(struct bContext *C, TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 5862faaf667..2e3af5d9418 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -2332,7 +2332,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
int special_transform_moving(TransInfo *t)
{
- if (t->spacetype == SPACE_SEQ) {
+ if (t->state == TRANS_WAITING) {
+ /* Pass. */
+ }
+ else if (t->spacetype == SPACE_SEQ) {
return G_TRANSFORM_SEQ;
}
else if (t->spacetype == SPACE_GRAPH) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index b2d8671fbce..e9b3c476f2a 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -413,7 +413,8 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* XXX insert keys are called here, and require context */
t->context = C;
- exit_code = transformEvent(t, event);
+ exit_code = transformEvent(t, op, event);
+ BLI_assert((t->state != TRANS_WAITING) || (exit_code & OPERATOR_PASS_THROUGH));
t->context = NULL;
/* XXX, workaround: active needs to be calculated before transforming,
@@ -430,9 +431,12 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
exit_code |= transformEnd(C, t);
- if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
+ if (t->state == TRANS_WAITING) {
+ /* pass */
+ }
+ else if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
transformops_exit(C, op);
- exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
+ // exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
}
else {
if (mode_prev != t->mode) {
@@ -1159,6 +1163,16 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
WM_operatortype_props_advanced_begin(ot);
+ /* Might want to support this in Transform_Properties(). */
+ prop = RNA_def_boolean(
+ ot->srna,
+ "wait_for_tweak",
+ 0,
+ "Wait for Tweak Event",
+ "Let events pass to other operators and only start applying transformations when a tweak "
+ "event from the initial event source is recognized");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+
Transform_Properties(ot, P_SNAP);
}
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 57c0a29382d..3a8807d92b7 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -406,7 +406,7 @@ typedef struct wmKeyMap {
/* runtime */
/** Verify if enabled in the current context, use #WM_keymap_poll instead of direct calls. */
bool (*poll)(struct bContext *);
- bool (*poll_modal_item)(const struct wmOperator *op, int value);
+ int (*poll_modal_item)(const struct wmOperator *op, int value);
/** For modal, #EnumPropertyItem for now. */
const void *modal_items;
@@ -424,6 +424,12 @@ enum {
KEYMAP_TOOL = (1 << 7), /* keymap for active tool system */
};
+enum {
+ KEYMAP_MODAL_SKIP = 0,
+ KEYMAP_MODAL_RUN_AND_DRAW = 1,
+ KEYMAP_MODAL_RUN_ONLY = 2,
+};
+
/**
* This is similar to addon-preferences,
* however unlike add-ons key-config's aren't saved to disk.
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 6b4327d5f44..92aeb1ce985 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2065,7 +2065,8 @@ static wmKeyMapItem *wm_eventmatch_modal_keymap_items(const wmKeyMap *keymap,
{
for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
if (wm_eventmatch(event, kmi)) {
- if ((keymap->poll_modal_item == NULL) || (keymap->poll_modal_item(op, kmi->propvalue))) {
+ if ((keymap->poll_modal_item == NULL) ||
+ (keymap->poll_modal_item(op, kmi->propvalue) != KEYMAP_MODAL_SKIP)) {
return kmi;
}
}
@@ -5276,6 +5277,7 @@ bool WM_window_modal_keymap_status_draw(bContext *UNUSED(C), wmWindow *win, uiLa
return false;
}
const EnumPropertyItem *items = keymap->modal_items;
+ bool any_drawn = false;
uiLayout *row = uiLayoutRow(layout, true);
for (int i = 0; items[i].identifier; i++) {
@@ -5283,9 +5285,10 @@ bool WM_window_modal_keymap_status_draw(bContext *UNUSED(C), wmWindow *win, uiLa
continue;
}
if ((keymap->poll_modal_item != NULL) &&
- (keymap->poll_modal_item(op, items[i].value) == false)) {
+ (keymap->poll_modal_item(op, items[i].value) != KEYMAP_MODAL_RUN_AND_DRAW)) {
continue;
}
+ any_drawn = true;
bool show_text = true;
@@ -5330,7 +5333,7 @@ bool WM_window_modal_keymap_status_draw(bContext *UNUSED(C), wmWindow *win, uiLa
}
}
}
- return true;
+ return any_drawn;
}
/** \} */