diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-12-06 19:45:50 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-12-06 22:03:00 +0300 |
commit | 6ffcddc10afa07b073ce01c25884e23fc2b661df (patch) | |
tree | 86e7ddb017474083890bf16fac4876175a923e57 /source | |
parent | 7465078e637b729e8b36a4f4b73a50a347052df4 (diff) |
Tool System: experimental fallback tool support
Implement T66304 as an experimental option,
available under the preferences "Experimental" section.
- When enabled most tools in the 3D view have a gizmo.
- Dragging outside the gizmo uses the 'fallback' tool.
- The fallback tool can be changed or disabled in the tool options
or from a pie menu (Alt-W).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/space_view3d/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c | 236 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_gizmo_3d.c | 41 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_gizmo_extrude_3d.c | 66 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 11 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_workspace_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 11 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_workspace.c | 19 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_workspace_api.c | 14 | ||||
-rw-r--r-- | source/blender/windowmanager/gizmo/WM_gizmo_types.h | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 34 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_toolsystem.c | 19 |
16 files changed, 464 insertions, 14 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 7c75f0ea907..2feef9e0c9a 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -61,6 +61,7 @@ set(SRC view3d_gizmo_preselect.c view3d_gizmo_preselect_type.c view3d_gizmo_ruler.c + view3d_gizmo_tool_generic.c view3d_header.c view3d_iterators.c view3d_ops.c diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 5c7263d458d..7db1a6123e8 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -626,6 +626,8 @@ static void view3d_widgets(void) WM_gizmogrouptype_append(VIEW3D_GGT_xform_extrude); WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_elem); WM_gizmogrouptype_append(VIEW3D_GGT_mesh_preselect_edgering); + WM_gizmogrouptype_append(VIEW3D_GGT_tool_generic_handle_normal); + WM_gizmogrouptype_append(VIEW3D_GGT_tool_generic_handle_free); WM_gizmogrouptype_append(VIEW3D_GGT_ruler); WM_gizmotype_append(VIEW3D_GT_ruler_item); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c new file mode 100644 index 00000000000..838abe46616 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c @@ -0,0 +1,236 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup spview3d + */ + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" + +#include "ED_screen.h" +#include "ED_transform.h" +#include "ED_gizmo_library.h" +#include "ED_gizmo_utils.h" + +#include "UI_resources.h" + +#include "MEM_guardedalloc.h" + +#include "WM_toolsystem.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" +#include "WM_toolsystem.h" +#include "WM_message.h" + +#include "view3d_intern.h" /* own include */ + +static const char *handle_normal_id; +static const char *handle_free_id; + +/* -------------------------------------------------------------------- */ +/** \name Generic Tool + * \{ */ + +static bool WIDGETGROUP_tool_generic_poll(const bContext *C, wmGizmoGroupType *gzgt) +{ + if (!U.experimental.use_tool_fallback) { + return false; + } + + if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) { + return false; + } + + View3D *v3d = CTX_wm_view3d(C); + if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)) { + return false; + } + + return true; +} + +static wmGizmo *tool_generic_create_gizmo(const bContext *C, wmGizmoGroup *gzgroup) +{ + wmGizmo *gz; + + if (gzgroup->type->idname == handle_normal_id) { + gz = WM_gizmo_new("GIZMO_GT_button_2d", gzgroup, NULL); + + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); + + unit_m4(gz->matrix_offset); + + PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); + RNA_property_enum_set(gz->ptr, prop, ICON_NONE); + + gz->scale_basis = 0.12f; + gz->matrix_offset[3][2] -= 12.0; + RNA_enum_set(gz->ptr, + "draw_options", + (ED_GIZMO_BUTTON_SHOW_BACKDROP | ED_GIZMO_BUTTON_SHOW_HELPLINE | + ED_GIZMO_BUTTON_SHOW_OUTLINE)); + } + else { + gz = WM_gizmo_new("GIZMO_GT_button_2d", gzgroup, NULL); + + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); + + unit_m4(gz->matrix_offset); + gz->scale_basis = 0.16f * 3; + + PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); + RNA_property_enum_set(gz->ptr, prop, ICON_NONE); + + RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_BACKDROP); + + /* Make the center low alpha. */ + WM_gizmo_set_line_width(gz, 2.0f); + RNA_float_set(gz->ptr, "backdrop_fill_alpha", 0.125f); + } + + bToolRef *tref = WM_toolsystem_ref_from_context((bContext *)C); + wmWindowManager *wm = CTX_wm_manager(C); + struct wmKeyConfig *kc = wm->defaultconf; + + gz->keymap = WM_keymap_ensure(kc, tref->runtime->keymap, tref->space_type, RGN_TYPE_WINDOW); + return gz; +} + +static void WIDGETGROUP_tool_generic_setup(const bContext *C, wmGizmoGroup *gzgroup) +{ + wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); + wwrapper->gizmo = tool_generic_create_gizmo(C, gzgroup); + gzgroup->customdata = wwrapper; +} + +static void WIDGETGROUP_tool_generic_refresh(const bContext *C, wmGizmoGroup *gzgroup) +{ + wmGizmoWrapper *wwrapper = gzgroup->customdata; + wmGizmo *gz = wwrapper->gizmo; + + ToolSettings *ts = CTX_data_tool_settings(C); + if (ts->workspace_tool_type != SCE_WORKSPACE_TOOL_FALLBACK) { + gzgroup->use_fallback_keymap = false; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); + return; + } + else { + gzgroup->use_fallback_keymap = true; + } + + /* skip, we don't draw anything anyway */ + { + int orientation; + if (gzgroup->type->idname == handle_normal_id) { + orientation = V3D_ORIENT_NORMAL; + } + else { + orientation = V3D_ORIENT_GLOBAL; /* dummy, use view. */ + } + + struct TransformBounds tbounds; + const bool hide = ED_transform_calc_gizmo_stats(C, + &(struct TransformCalcParams){ + .use_only_center = true, + .orientation_type = orientation + 1, + }, + &tbounds) == 0; + + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, hide); + if (hide) { + return; + } + copy_m4_m3(gz->matrix_basis, tbounds.axis); + copy_v3_v3(gz->matrix_basis[3], tbounds.center); + negate_v3(gz->matrix_basis[2]); + } + + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true); +} + +static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C, + wmGizmoGroup *gzgroup, + struct wmMsgBus *mbus) +{ + ARegion *ar = CTX_wm_region(C); + + wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = { + .owner = ar, + .user_data = gzgroup->parent_gzmap, + .notify = WM_gizmo_do_msg_notify_tag_refresh, + }; + + { + extern PropertyRNA rna_ToolSettings_workspace_tool_type; + const PropertyRNA *props[] = { + &rna_ToolSettings_workspace_tool_type, + }; + + Scene *scene = CTX_data_scene(C); + PointerRNA toolsettings_ptr; + RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr); + + for (int i = 0; i < ARRAY_SIZE(props); i++) { + WM_msg_subscribe_rna( + mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); + } + } +} + +static const char *handle_normal_id = "VIEW3D_GGT_tool_generic_handle_normal"; +static const char *handle_free_id = "VIEW3D_GGT_tool_generic_handle_free"; + +void VIEW3D_GGT_tool_generic_handle_normal(wmGizmoGroupType *gzgt) +{ + gzgt->name = "Generic Tool Widget Normal"; + gzgt->idname = handle_normal_id; + + gzgt->flag |= (WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP); + + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; + + gzgt->poll = WIDGETGROUP_tool_generic_poll; + gzgt->setup = WIDGETGROUP_tool_generic_setup; + gzgt->refresh = WIDGETGROUP_tool_generic_refresh; + gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe; +} + +void VIEW3D_GGT_tool_generic_handle_free(wmGizmoGroupType *gzgt) +{ + gzgt->name = "Generic Tool Widget Free"; + gzgt->idname = handle_free_id; + + gzgt->flag |= (WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP); + + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; + + gzgt->poll = WIDGETGROUP_tool_generic_poll; + gzgt->setup = WIDGETGROUP_tool_generic_setup; + gzgt->refresh = WIDGETGROUP_tool_generic_refresh; + gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe; +} + +/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 6b5c27b68f4..ddbb64bf067 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -261,6 +261,8 @@ void VIEW3D_GGT_armature_spline(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_navigate(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_mesh_preselect_elem(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_mesh_preselect_edgering(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_tool_generic_handle_normal(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_tool_generic_handle_free(struct wmGizmoGroupType *gzgt); void VIEW3D_GGT_ruler(struct wmGizmoGroupType *gzgt); void VIEW3D_GT_ruler_item(struct wmGizmoType *gzt); diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 237bf50be7c..bb47f40d84f 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1322,6 +1322,17 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup, } } + { + extern PropertyRNA rna_ToolSettings_workspace_tool_type; + const PropertyRNA *props[] = { + &rna_ToolSettings_workspace_tool_type, + }; + for (int i = 0; i < ARRAY_SIZE(props); i++) { + WM_msg_subscribe_rna( + mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); + } + } + PointerRNA view3d_ptr; RNA_pointer_create(&screen->id, &RNA_SpaceView3D, sa->spacedata.first, &view3d_ptr); @@ -1818,6 +1829,13 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup) for (int i = MAN_AXIS_RANGE_ROT_START; i < MAN_AXIS_RANGE_ROT_END; i++) { ggd->gizmos[i]->select_bias = rotate_select_bias; } + + if (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK) { + gzgroup->use_fallback_keymap = true; + } + else { + gzgroup->use_fallback_keymap = false; + } } static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C, @@ -2028,7 +2046,7 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt) gzgt->name = "3D View: Transform Gizmo"; gzgt->idname = "VIEW3D_GGT_xform_gizmo"; - gzgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; @@ -2062,7 +2080,8 @@ void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt) gzgt->name = "3D View: Transform Gizmo Context"; gzgt->idname = "VIEW3D_GGT_xform_gizmo_context"; - gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_PERSISTENT; + gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_PERSISTENT | + WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP; gzgt->poll = WIDGETGROUP_gizmo_poll_context; gzgt->setup = WIDGETGROUP_gizmo_setup; @@ -2212,6 +2231,13 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgr /* Needed to test view orientation changes. */ copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv); + + if (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK) { + gzgroup->use_fallback_keymap = true; + } + else { + gzgroup->use_fallback_keymap = false; + } } static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C, @@ -2263,7 +2289,7 @@ void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt) gzgt->name = "Transform Cage"; gzgt->idname = "VIEW3D_GGT_xform_cage"; - gzgt->flag |= WM_GIZMOGROUPTYPE_3D; + gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; @@ -2385,6 +2411,13 @@ static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzg /* Needed to test view orientation changes. */ copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv); + + if (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK) { + gzgroup->use_fallback_keymap = true; + } + else { + gzgroup->use_fallback_keymap = false; + } } static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C, @@ -2446,7 +2479,7 @@ void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt) gzgt->name = "Transform Shear"; gzgt->idname = "VIEW3D_GGT_xform_shear"; - gzgt->flag |= WM_GIZMOGROUPTYPE_3D; + gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c index 513a8afa9b6..da6b0285a5c 100644 --- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c +++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c @@ -55,9 +55,10 @@ enum { static const float extrude_button_scale = 0.15f; static const float extrude_button_offset_scale = 1.5f; -static const float extrude_arrow_scale = 1.0f; -static const float extrude_arrow_xyz_axis_scale = 1.0f; -static const float extrude_arrow_normal_axis_scale = 1.0f; +static const float extrude_outer_scale = 1.2f; +static const float extrude_arrow_scale = 0.7f; +static const float extrude_arrow_xyz_axis_scale = 0.6666f; +static const float extrude_arrow_normal_axis_scale = 0.6666f; static const float extrude_dial_scale = 0.2; static const uchar shape_plus[] = { @@ -69,6 +70,8 @@ typedef struct GizmoExtrudeGroup { /* XYZ & normal. */ wmGizmo *invoke_xyz_no[4]; + /* Only visible when 'drag' tool option is disabled. */ + wmGizmo *invoke_view; /* Constrained & unconstrained (arrow & circle). */ wmGizmo *adjust[2]; int adjust_axis; @@ -126,12 +129,20 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup) ggd->adjust[0] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); ggd->adjust[1] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); + RNA_enum_set(ggd->adjust[1]->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT); + for (int i = 0; i < 4; i++) { ggd->invoke_xyz_no[i] = WM_gizmo_new_ptr(gzt_move, gzgroup, NULL); ggd->invoke_xyz_no[i]->flag |= WM_GIZMO_DRAW_OFFSET_SCALE; } { + ggd->invoke_view = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); + ggd->invoke_view->select_bias = -2.0f; + RNA_enum_set(ggd->invoke_view->ptr, "draw_options", ED_GIZMO_DIAL_DRAW_FLAG_FILL_SELECT); + } + + { PropertyRNA *prop = RNA_struct_find_property(ggd->invoke_xyz_no[3]->ptr, "shape"); for (int i = 0; i < 4; i++) { RNA_property_string_set_bytes( @@ -170,6 +181,8 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup) UI_GetThemeColor3fv(TH_AXIS_X + i, ggd->invoke_xyz_no[i]->color); } UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, ggd->invoke_xyz_no[3]->color); + ggd->invoke_view->color[3] = 0.5f; + for (int i = 0; i < 2; i++) { UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, ggd->adjust[i]->color); } @@ -177,6 +190,9 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup) for (int i = 0; i < 4; i++) { WM_gizmo_set_scale(ggd->invoke_xyz_no[i], extrude_button_scale); } + WM_gizmo_set_scale(ggd->invoke_view, extrude_outer_scale); + ggd->invoke_view->line_width = 2.0f; + WM_gizmo_set_scale(ggd->adjust[0], extrude_arrow_scale); WM_gizmo_set_scale(ggd->adjust[1], extrude_dial_scale); ggd->adjust[1]->line_width = 2.0f; @@ -193,6 +209,15 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup) } } + { + PointerRNA *ptr = WM_gizmo_operator_set(ggd->invoke_view, 0, ggd->ot_extrude, NULL); + PointerRNA macroptr = RNA_pointer_get(ptr, "TRANSFORM_OT_translate"); + RNA_boolean_set(¯optr, "release_confirm", true); + + bool constraint[3] = {0, 0, 0}; + RNA_boolean_set_array(¯optr, "constraint_axis", constraint); + } + /* Adjust extrude. */ for (int i = 0; i < 2; i++) { wmGizmo *gz = ggd->adjust[i]; @@ -211,6 +236,7 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup) for (int i = 0; i < 4; i++) { WM_gizmo_set_flag(ggd->invoke_xyz_no[i], WM_GIZMO_HIDDEN, true); } + WM_gizmo_set_flag(ggd->invoke_view, WM_GIZMO_HIDDEN, true); for (int i = 0; i < 2; i++) { WM_gizmo_set_flag(ggd->adjust[i], WM_GIZMO_HIDDEN, true); } @@ -303,6 +329,7 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup) for (int i = 0; i < axis_len_used; i++) { WM_gizmo_set_matrix_location(ggd->invoke_xyz_no[i], tbounds.center); } + WM_gizmo_set_matrix_location(ggd->invoke_view, tbounds.center); /* Un-hide. */ for (int i = 0; i < axis_len_used; i++) { WM_gizmo_set_flag(ggd->invoke_xyz_no[i], WM_GIZMO_HIDDEN, false); @@ -351,6 +378,15 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup) WM_gizmo_set_flag(ggd->invoke_xyz_no[3], WM_GIZMO_HIDDEN, true); break; } + + if (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK) { + WM_gizmo_set_flag(ggd->invoke_view, WM_GIZMO_HIDDEN, false); + gzgroup->use_fallback_keymap = true; + } + else { + WM_gizmo_set_flag(ggd->invoke_view, WM_GIZMO_HIDDEN, true); + gzgroup->use_fallback_keymap = false; + } } static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) @@ -380,6 +416,11 @@ static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *gzg copy_v3_v3(ggd->adjust[1]->matrix_basis[1], rv3d->viewinv[1]); copy_v3_v3(ggd->adjust[1]->matrix_basis[2], rv3d->viewinv[2]); } + if ((ggd->invoke_view->flag & WM_GIZMO_HIDDEN) == 0) { + copy_v3_v3(ggd->invoke_view->matrix_basis[0], rv3d->viewinv[0]); + copy_v3_v3(ggd->invoke_view->matrix_basis[1], rv3d->viewinv[1]); + copy_v3_v3(ggd->invoke_view->matrix_basis[2], rv3d->viewinv[2]); + } } } @@ -400,6 +441,9 @@ static void gizmo_mesh_extrude_invoke_prepare(const bContext *UNUSED(C), } RNA_float_set_array(¯optr, "value", ggd->redo_xform.value); } + else if (gz == ggd->invoke_view) { + /* pass */ + } else { /* Workaround for extrude action modifying normals. */ const int i = BLI_array_findindex(ggd->invoke_xyz_no, ARRAY_SIZE(ggd->invoke_xyz_no), &gz); @@ -449,6 +493,20 @@ static void gizmo_mesh_extrude_message_subscribe(const bContext *C, }, &msg_sub_value_gz_tag_refresh, __func__); + + { + Scene *scene = CTX_data_scene(C); + PointerRNA toolsettings_ptr; + RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr); + extern PropertyRNA rna_ToolSettings_workspace_tool_type; + const PropertyRNA *props[] = { + &rna_ToolSettings_workspace_tool_type, + }; + for (int i = 0; i < ARRAY_SIZE(props); i++) { + WM_msg_subscribe_rna( + mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); + } + } } void VIEW3D_GGT_xform_extrude(struct wmGizmoGroupType *gzgt) @@ -456,7 +514,7 @@ void VIEW3D_GGT_xform_extrude(struct wmGizmoGroupType *gzgt) gzgt->name = "3D View Extrude"; gzgt->idname = "VIEW3D_GGT_xform_extrude"; - gzgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 54ae38f608c..5336ea381c3 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1509,7 +1509,10 @@ typedef struct ToolSettings { /* XXX: these sculpt_paint_* fields are deprecated, use the * unified_paint_settings field instead! */ short sculpt_paint_settings DNA_DEPRECATED; - char _pad5[2]; + + char workspace_tool_type; + + char _pad5[1]; int sculpt_paint_unified_size DNA_DEPRECATED; float sculpt_paint_unified_unprojected_radius DNA_DEPRECATED; float sculpt_paint_unified_alpha DNA_DEPRECATED; @@ -2042,6 +2045,12 @@ enum { SCE_OBJECT_MODE_LOCK = (1 << 0), }; +/* ToolSettings.workspace_tool_flag */ +enum { + SCE_WORKSPACE_TOOL_FALLBACK = 0, + SCE_WORKSPACE_TOOL_DEFAULT = 1, +}; + /* ToolSettings.snap_flag */ #define SCE_SNAP (1 << 0) #define SCE_SNAP_ROTATE (1 << 1) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index eb1b3036767..c26eb58a8f9 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -607,7 +607,10 @@ typedef struct UserDef_FileSpaceData { typedef struct UserDef_Experimental { /** #eUserPref_Experimental_Flag options. */ int flag; - char _pad0[4]; + + char use_tool_fallback; + + char _pad0[3]; } UserDef_Experimental; typedef struct UserDef { diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index dbfb0cc6346..573b076542e 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -35,6 +35,10 @@ typedef struct bToolRef_Runtime { char gizmo_group[64]; char data_block[64]; + /** Optionally use these when not interacting directly with the primary tools gizmo. */ + char idname_fallback[64]; + char keymap_fallback[64]; + /** Use to infer primary operator to use when setting accelerator keys. */ char op[64]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index cca82abc9da..708dfb6c736 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2867,6 +2867,17 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Lock Object Modes", "Restrict select to the current mode"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + static const EnumPropertyItem workspace_tool_items[] = { + {SCE_WORKSPACE_TOOL_DEFAULT, "DEFAULT", 0, "Active Tool", ""}, + {SCE_WORKSPACE_TOOL_FALLBACK, "FALLBACK", 0, "Select", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + prop = RNA_def_property(srna, "workspace_tool_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "workspace_tool_type"); + RNA_def_property_enum_items(prop, workspace_tool_items); + RNA_def_property_ui_text(prop, "Drag", "Action when dragging in the viewport"); + /* Transform */ prop = RNA_def_property(srna, "use_proportional_edit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "proportional_edit", PROP_EDIT_USE); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 64bca38882f..aa69b49c391 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -5845,6 +5845,11 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) "All Experimental Features", "Expose all the experimental features in the user interface"); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "use_tool_fallback", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_tool_fallback", 1); + RNA_def_property_ui_text(prop, "Fallback Tool Support", "Allow selection with an active tool"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_workspace.c b/source/blender/makesrna/intern/rna_workspace.c index 47138653af1..7c6e3c2730b 100644 --- a/source/blender/makesrna/intern/rna_workspace.c +++ b/source/blender/makesrna/intern/rna_workspace.c @@ -192,6 +192,18 @@ static int rna_WorkSpaceTool_widget_length(PointerRNA *ptr) return tref->runtime ? strlen(tref->runtime->gizmo_group) : 0; } +static void rna_WorkSpaceTool_tool_fallback_get(PointerRNA *ptr, char *value) +{ + bToolRef *tref = ptr->data; + strcpy(value, tref->runtime ? tref->runtime->idname_fallback : ""); +} + +static int rna_WorkSpaceTool_tool_fallback_length(PointerRNA *ptr) +{ + bToolRef *tref = ptr->data; + return tref->runtime ? strlen(tref->runtime->idname_fallback) : 0; +} + #else /* RNA_RUNTIME */ static void rna_def_workspace_owner(BlenderRNA *brna) @@ -290,6 +302,13 @@ static void rna_def_workspace_tool(BlenderRNA *brna) prop, "rna_WorkSpaceTool_widget_get", "rna_WorkSpaceTool_widget_length", NULL); RNA_define_verify_sdna(1); + prop = RNA_def_property(srna, "tool_fallback", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Fallback", ""); + RNA_def_property_string_funcs( + prop, "rna_WorkSpaceTool_tool_fallback_get", "rna_WorkSpaceTool_tool_fallback_length", NULL); + RNA_define_verify_sdna(1); + RNA_api_workspace_tool(srna); } diff --git a/source/blender/makesrna/intern/rna_workspace_api.c b/source/blender/makesrna/intern/rna_workspace_api.c index 2d3b1e76b71..f244a674e57 100644 --- a/source/blender/makesrna/intern/rna_workspace_api.c +++ b/source/blender/makesrna/intern/rna_workspace_api.c @@ -43,14 +43,16 @@ static void rna_WorkSpaceTool_setup(ID *id, bToolRef *tref, bContext *C, - const char *tool_idname, + const char *idname, /* Args for: 'bToolRef_Runtime'. */ int cursor, const char *keymap, const char *gizmo_group, const char *data_block, const char *op_idname, - int index) + int index, + const char *idname_fallback, + const char *keymap_fallback) { bToolRef_Runtime tref_rt = {0}; @@ -61,7 +63,10 @@ static void rna_WorkSpaceTool_setup(ID *id, STRNCPY(tref_rt.op, op_idname); tref_rt.index = index; - WM_toolsystem_ref_set_from_runtime(C, (WorkSpace *)id, tref, &tref_rt, tool_idname); + STRNCPY(tref_rt.idname_fallback, idname_fallback ? idname_fallback : NULL); + STRNCPY(tref_rt.keymap_fallback, keymap_fallback ? keymap_fallback : NULL); + + WM_toolsystem_ref_set_from_runtime(C, (WorkSpace *)id, tref, &tref_rt, idname); } static void rna_WorkSpaceTool_refresh_from_context(ID *id, bToolRef *tref, Main *bmain) @@ -140,6 +145,9 @@ void RNA_api_workspace_tool(StructRNA *srna) RNA_def_string(func, "operator", NULL, MAX_NAME, "Operator", ""); RNA_def_int(func, "index", 0, INT_MIN, INT_MAX, "Index", "", INT_MIN, INT_MAX); + RNA_def_string(func, "idname_fallback", NULL, MAX_NAME, "Fallback Identifier", ""); + RNA_def_string(func, "keymap_fallback", NULL, KMAP_MAX_NAME, "Fallback Key Map", ""); + /* Access tool operator options (optionally create). */ func = RNA_def_function(srna, "operator_properties", "rna_WorkSpaceTool_operator_properties"); RNA_def_function_flag(func, FUNC_USE_REPORTS); diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h index 7bb77375934..d3aa333daea 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h @@ -120,6 +120,12 @@ typedef enum eWM_GizmoFlagGroupTypeFlag { * We could even move the options into the key-map item. * ~ campbell. */ WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 6), + + /** + * This gizmo type supports using the fallback tools keymap. + * #wmGizmoGroup.use_tool_fallback will need to be set too. + */ + WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP = (1 << 7), } eWM_GizmoFlagGroupTypeFlag; /** @@ -443,6 +449,8 @@ typedef struct wmGizmoGroup { bool tag_remove; + bool use_fallback_keymap; + void *customdata; /** For freeing customdata from above. */ void (*customdata_free)(void *); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 180a518de2b..d65cf2324a9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -3728,8 +3728,40 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, wmEventHandle handler->keymap_tool = NULL; bToolRef_Runtime *tref_rt = sa->runtime.tool ? sa->runtime.tool->runtime : NULL; if (tref_rt && tref_rt->keymap[0]) { + const char *keymap_id = tref_rt->keymap; + + /* Support for the gizmo owning the tool keymap. */ + if (U.experimental.use_tool_fallback) { + if (tref_rt->gizmo_group[0] != '\0') { + wmGizmoMap *gzmap = NULL; + wmGizmoGroup *gzgroup = NULL; + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->gizmo_map != NULL) { + gzmap = ar->gizmo_map; + gzgroup = WM_gizmomap_group_find(gzmap, tref_rt->gizmo_group); + if (gzgroup != NULL) { + break; + } + } + } + if (gzgroup != NULL) { + if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP) { + /* If all are hidden, don't override. */ + if (gzgroup->use_fallback_keymap) { + wmGizmo *highlight = wm_gizmomap_highlight_get(gzmap); + if (highlight == NULL) { + if (tref_rt->keymap_fallback[0]) { + keymap_id = tref_rt->keymap_fallback; + } + } + } + } + } + } + } + wmKeyMap *km = WM_keymap_list_find_spaceid_or_empty( - &wm->userconf->keymaps, tref_rt->keymap, sa->spacetype, RGN_TYPE_WINDOW); + &wm->userconf->keymaps, keymap_id, sa->spacetype, RGN_TYPE_WINDOW); /* We shouldn't use keymaps from unrelated spaces. */ if (km != NULL) { handler->keymap_tool = sa->runtime.tool; diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index f64acf20581..d714fdaa19e 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -351,6 +351,25 @@ void WM_toolsystem_ref_set_from_runtime(struct bContext *C, *tref->runtime = *tref_rt; } + /* FIXME: ideally Python could check this gizmo group flag and not + * pass in the argument to begin with. */ + bool use_fallback_keymap = false; + + if (U.experimental.use_tool_fallback) { + if (tref_rt->gizmo_group[0]) { + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(tref_rt->gizmo_group, false); + if (gzgt) { + if (gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP) { + use_fallback_keymap = true; + } + } + } + } + if (use_fallback_keymap == false) { + tref->runtime->idname_fallback[0] = '\0'; + tref->runtime->keymap_fallback[0] = '\0'; + } + toolsystem_ref_link(C, workspace, tref); toolsystem_refresh_screen_from_active_tool(bmain, workspace, tref); |