UI: Bring back hover shortcuts for mesh modifiers

Earlier last year, the shortcuts on hover were built as a way to regain
speed lost by removing the "Apply" and "Copy" buttons from the panel.
For the active modifier concept introduced for geometry nodes, the
shortcuts were changed to only affect the active modifier.

Based on feedback, this change slowed down many people's interaction
with the modifier stack so the UI team decided to return hover shortcuts
for modifier panels.

The downside of this change is that it looks like the active modifier is
"selected" and it could be confusing that the modifier shortcuts don't
apply to it. We can explore different ways to display the active status
to address this.

Ref T87012
This commit is contained in:
Hans Goudey 2021-03-30 09:56:04 -05:00
parent 1f58a0ea3c
commit 9f323e9bf7
Notes: blender-bot 2023-02-14 12:01:57 +01:00
Referenced by commit 6f761c7110, Fix T87392: Copy modifier to selected does not do anything
Referenced by commit 02a7289fe3, Fix T87264: Button to remove physics modifier doesn't work
Referenced by issue #87401, Modifier menu always uses modifier under cursor
Referenced by issue #87392, Modifier: Copy to selected does not do anything
Referenced by issue #87264, Physics (Collision, Cloth, Dynamic Paint, Soft Body, Fluid) cannot be removed (X button disfunctional)
Referenced by issue #87012, Return hover shortcuts for mesh modifiers
1 changed files with 65 additions and 79 deletions

View File

@ -1115,6 +1115,38 @@ bool edit_modifier_invoke_properties(bContext *C, wmOperator *op)
return false;
}
/**
* If the "modifier" property is not set,fill the modifier property with the name of the modifier
* with a UI panel below the mouse cursor, without checking the context pointer. Used in order to
* apply modifier operators on hover over their panels. If this checked the context pointer then it
* would always use the active modifier, which isn't desired.
*/
bool edit_modifier_invoke_properties_with_hover_no_active(bContext *C,
wmOperator *op,
const wmEvent *event,
int *r_retval)
{
if (RNA_struct_property_is_set(op->ptr, "modifier")) {
return true;
}
PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
if ((panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
*r_retval = OPERATOR_CANCELLED;
return false;
}
if (!RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) {
/* Work around multiple operators using the same shortcut. */
*r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return false;
}
const ModifierData *md = panel_ptr->data;
RNA_string_set(op->ptr, "modifier", md->name);
return true;
}
ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
{
char modifier_name[MAX_NAME];
@ -1174,14 +1206,13 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_remove_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
void OBJECT_OT_modifier_remove(wmOperatorType *ot)
@ -1221,13 +1252,13 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_move_up_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
@ -1266,13 +1297,13 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_move_down_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
@ -1309,12 +1340,13 @@ static int modifier_move_to_index_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_move_to_index_exec(C, op);
}
return OPERATOR_CANCELLED;
return retval;
}
void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
@ -1421,13 +1453,13 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_DATA, false);
}
static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_apply_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
void OBJECT_OT_modifier_apply(wmOperatorType *ot)
@ -1465,15 +1497,13 @@ static int modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op)
return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_SHAPE, keep);
}
static int modifier_apply_as_shapekey_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_apply_as_shapekey_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C),
@ -1579,13 +1609,13 @@ static int modifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_copy_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
void OBJECT_OT_modifier_copy(wmOperatorType *ot)
@ -1622,54 +1652,12 @@ static int modifier_set_active_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
/**
* Get the modifier below the mouse cursor modifier without checking the context pointer.
* Used in order to set the active modifier on mouse click. If this checked the context
* pointer then it would always set the active modifier to the already active modifier.
*
* \param event: If this isn't NULL, the operator will also look for panels underneath
* the cursor with custom-data set to a modifier.
* \param r_retval: This should be used if #event is used in order to return
* #OPERATOR_PASS_THROUGH to check other operators with the same key set.
*/
bool edit_modifier_invoke_properties_with_hover_no_active(bContext *C,
wmOperator *op,
const wmEvent *event,
int *r_retval)
{
if (RNA_struct_property_is_set(op->ptr, "modifier")) {
return true;
}
PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
if (RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) {
ModifierData *md = panel_ptr->data;
RNA_string_set(op->ptr, "modifier", md->name);
return true;
}
BLI_assert(r_retval != NULL); /* We need the return value in this case. */
if (r_retval != NULL) {
*r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
}
return false;
}
if (r_retval != NULL) {
*r_retval = OPERATOR_CANCELLED;
}
return false;
}
static int modifier_set_active_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_set_active_exec(C, op);
}
return retval;
}
@ -1756,15 +1744,13 @@ static int modifier_copy_to_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int modifier_copy_to_selected_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
static int modifier_copy_to_selected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (edit_modifier_invoke_properties(C, op)) {
return modifier_copy_to_selected_exec(C, op);
int retval;
if (edit_modifier_invoke_properties_with_hover_no_active(C, op, event, &retval)) {
return modifier_set_active_exec(C, op);
}
/* Work around multiple operators using the same shortcut. */
return (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
return retval;
}
static bool modifier_copy_to_selected_poll(bContext *C)