forked from bartvdbraak/blender
Fix T59170: Box select ignores modifiers-keys once tool option is set
- Key-map items properties now override tool-options so modifier keys can have different behavior to the default action. - Box & circle select now have `wait_for_input` properties instead of detecting this based on selection options being set or not. This relied on the key-map setting properties which may need to be initialize from the tool settings.
This commit is contained in:
parent
49490e5cfb
commit
4ae68d6825
@ -235,8 +235,7 @@ def _template_items_tool_select(params, operator, cursor_operator):
|
||||
def _template_items_tool_select_actions(operator, *, type, value):
|
||||
kmi_args = {"type": type, "value": value}
|
||||
return [
|
||||
(operator, kmi_args,
|
||||
{"properties": [("mode", 'SET')]}),
|
||||
(operator, kmi_args, None),
|
||||
(operator, {**kmi_args, "shift": True},
|
||||
{"properties": [("mode", 'ADD')]}),
|
||||
(operator, {**kmi_args, "ctrl": True},
|
||||
@ -5135,9 +5134,9 @@ def km_3d_view_tool_object_select_circle(params):
|
||||
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
|
||||
{"items": [
|
||||
("view3d.select_circle", {"type": params.tool_mouse, "value": 'PRESS'},
|
||||
{"properties": [("deselect", False)]}),
|
||||
{"properties": [("wait_for_input", False)]}),
|
||||
("view3d.select_circle", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("deselect", True)]}),
|
||||
{"properties": [("wait_for_input", False), ("deselect", True)]}),
|
||||
]},
|
||||
)
|
||||
|
||||
|
@ -79,7 +79,7 @@ static void gesture_modal_end(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
static void gesture_modal_state_to_operator(wmOperator *op, int modal_state, bool check_is_set)
|
||||
static void gesture_modal_state_to_operator(wmOperator *op, int modal_state)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
@ -87,28 +87,22 @@ static void gesture_modal_state_to_operator(wmOperator *op, int modal_state, boo
|
||||
case GESTURE_MODAL_SELECT:
|
||||
case GESTURE_MODAL_DESELECT:
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
|
||||
if (!check_is_set || !RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT));
|
||||
}
|
||||
RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT));
|
||||
}
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "mode"))) {
|
||||
if (!check_is_set || !RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_enum_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT) ? SEL_OP_SUB : SEL_OP_ADD);
|
||||
}
|
||||
RNA_property_enum_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT) ? SEL_OP_SUB : SEL_OP_ADD);
|
||||
}
|
||||
break;
|
||||
case GESTURE_MODAL_IN:
|
||||
case GESTURE_MODAL_OUT:
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
|
||||
if (!check_is_set || !RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_OUT));
|
||||
}
|
||||
RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_OUT));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int gesture_modal_state_from_operator(wmOperator *op)
|
||||
static int UNUSED_FUNCTION(gesture_modal_state_from_operator)(wmOperator *op)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
@ -171,7 +165,9 @@ static bool gesture_box_apply(bContext *C, wmOperator *op)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gesture_modal_state_to_operator(op, gesture->modal_state, true);
|
||||
if (gesture->wait_for_input) {
|
||||
gesture_modal_state_to_operator(op, gesture->modal_state);
|
||||
}
|
||||
|
||||
retval = op->type->exec(C, op);
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
@ -181,23 +177,17 @@ static bool gesture_box_apply(bContext *C, wmOperator *op)
|
||||
|
||||
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int modal_state = gesture_modal_state_from_operator(op);
|
||||
|
||||
if (ISTWEAK(event->type) || (modal_state != GESTURE_MODAL_NOP)) {
|
||||
op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
|
||||
}
|
||||
else {
|
||||
const bool wait_for_input = !ISTWEAK(event->type) && RNA_boolean_get(op->ptr, "wait_for_input");
|
||||
if (wait_for_input) {
|
||||
op->customdata = WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
|
||||
}
|
||||
|
||||
/* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
|
||||
if (modal_state == GESTURE_MODAL_NOP) {
|
||||
wmGesture *gesture = op->customdata;
|
||||
gesture->wait_for_input = true;
|
||||
}
|
||||
else {
|
||||
op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
|
||||
}
|
||||
|
||||
{
|
||||
wmGesture *gesture = op->customdata;
|
||||
gesture->modal_state = modal_state;
|
||||
gesture->wait_for_input = wait_for_input;
|
||||
}
|
||||
|
||||
/* add modal handler */
|
||||
@ -290,7 +280,7 @@ static void gesture_circle_apply(bContext *C, wmOperator *op);
|
||||
|
||||
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int modal_state = gesture_modal_state_from_operator(op);
|
||||
const bool wait_for_input = !ISTWEAK(event->type) && RNA_boolean_get(op->ptr, "wait_for_input");
|
||||
|
||||
op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
|
||||
wmGesture *gesture = op->customdata;
|
||||
@ -299,13 +289,11 @@ int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
/* Default or previously stored value. */
|
||||
rect->xmax = RNA_int_get(op->ptr, "radius");
|
||||
|
||||
gesture->wait_for_input = wait_for_input;
|
||||
|
||||
/* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
|
||||
if (modal_state == GESTURE_MODAL_NOP) {
|
||||
gesture->wait_for_input = true;
|
||||
}
|
||||
else {
|
||||
if (gesture->wait_for_input == false) {
|
||||
gesture->is_active = true;
|
||||
gesture->modal_state = modal_state;
|
||||
gesture_circle_apply(C, op);
|
||||
}
|
||||
|
||||
@ -322,7 +310,9 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
|
||||
wmGesture *gesture = op->customdata;
|
||||
rcti *rect = gesture->customdata;
|
||||
|
||||
if (gesture->modal_state == GESTURE_MODAL_NOP) {
|
||||
if (gesture->wait_for_input &&
|
||||
(gesture->modal_state == GESTURE_MODAL_NOP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@ -333,7 +323,9 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
|
||||
|
||||
/* When 'wait_for_input' is false, use properties to get the selection state.
|
||||
* typically tool settings. This is done so executing as a mode can select & de-select, see: T58594. */
|
||||
gesture_modal_state_to_operator(op, gesture->modal_state, !gesture->wait_for_input);
|
||||
if (gesture->wait_for_input) {
|
||||
gesture_modal_state_to_operator(op, gesture->modal_state);
|
||||
}
|
||||
|
||||
if (op->type->exec) {
|
||||
int retval;
|
||||
|
@ -220,6 +220,9 @@ void WM_operator_properties_border(wmOperatorType *ot)
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
prop = RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
|
||||
@ -365,6 +368,9 @@ void WM_operator_properties_gesture_circle_ex(wmOperatorType *ot, bool deselect)
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
RNA_def_int(ot->srna, "radius", radius_default, 1, INT_MAX, "Radius", "", 1, INT_MAX);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
||||
if (deselect) {
|
||||
prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
@ -922,7 +922,14 @@ void WM_toolsystem_ref_properties_init_for_keymap(
|
||||
if (tref->properties != NULL) {
|
||||
IDProperty *prop = IDP_GetPropertyFromGroup(tref->properties, ot->idname);
|
||||
if (prop) {
|
||||
IDP_MergeGroup(dst_ptr->data, prop, true);
|
||||
/* Important key-map items properties don't get overwritten by the tools.
|
||||
* - When a key-map item doesn't set a property, the tool-systems is used.
|
||||
* - When it does, it overrides the tool-system.
|
||||
*
|
||||
* This way the default action can be to follow the top-bar tool-settings &
|
||||
* modifier keys can be used to perform different actions that aren't clobbered here.
|
||||
*/
|
||||
IDP_MergeGroup(dst_ptr->data, prop, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user