1
1

Compare commits

...

2 Commits

Author SHA1 Message Date
3aaf9521b9 Experimental support for select tool fallback actions
Differential Revision: https://developer.blender.org/D6301
2019-11-27 20:42:34 +11:00
b6d8746e30 Initial working tool + selection 2019-11-27 20:42:30 +11:00
18 changed files with 573 additions and 37 deletions

View File

@@ -162,7 +162,7 @@ class ToolActivePanelHelper:
layout.use_property_decorate = False
ToolSelectPanelHelper.draw_active_tool_header(
context,
layout,
layout.column(),
show_tool_name=True,
tool_key=ToolSelectPanelHelper._tool_key_from_context(context, space_type=self.bl_space_type),
)
@@ -633,6 +633,26 @@ class ToolSelectPanelHelper:
space_type = context.space_data.type
return ToolSelectPanelHelper._tool_active_from_context(context, space_type)
@staticmethod
def draw_active_tool_fallback(
context, layout, tool,
*,
show_tool_name=False,
is_horizontal_layout=False,
):
tool_fallback = tool.tool_fallback
space_type = tool.space_type
_cls, item_fallback, _index = ToolSelectPanelHelper._tool_get_by_id(context, space_type, tool_fallback)
if item_fallback is not None:
draw_settings = item_fallback.draw_settings
if draw_settings is not None:
icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item_fallback.icon)
layout.label(text=" " + item_fallback.label if show_tool_name else " ", icon_value=icon_value)
if not is_horizontal_layout:
layout.separator()
draw_settings(context, layout, tool)
@staticmethod
def draw_active_tool_header(
context, layout,
@@ -640,6 +660,7 @@ class ToolSelectPanelHelper:
show_tool_name=False,
tool_key=None,
):
is_horizontal_layout = layout.direction != 'VERTICAL'
if tool_key is None:
space_type, mode = ToolSelectPanelHelper._tool_key_from_context(context)
else:
@@ -658,6 +679,31 @@ class ToolSelectPanelHelper:
draw_settings = item.draw_settings
if draw_settings is not None:
draw_settings(context, layout, tool)
tool_fallback = tool.tool_fallback
if tool_fallback and tool_fallback != item.idname:
tool_settings = context.tool_settings
if not is_horizontal_layout:
row = layout.column(align=True)
row.prop(tool_settings, "workspace_tool_type",text="Drag")
if tool_settings.workspace_tool_type == 'FALLBACK':
ToolSelectPanelHelper.draw_active_tool_fallback(
context, row, tool,
show_tool_name=show_tool_name,
is_horizontal_layout=is_horizontal_layout,
)
else:
pass
else:
layout.context_pointer_set("tool", tool)
layout.prop_with_popover(
tool_settings,
"workspace_tool_type",
panel="TOPBAR_PT_tool_fallback",
)
return tool
@@ -702,6 +748,14 @@ class WM_MT_toolsystem_submenu(Menu):
def _activate_by_item(context, space_type, item, index):
# Find fallback keymap.
item_fallback = None
_cls, _item, select_index = ToolSelectPanelHelper._tool_get_by_id(context, space_type, "builtin.select")
if select_index != -1:
_cls, item_fallback, _index = ToolSelectPanelHelper._tool_get_by_index(context, space_type, select_index)
# End calculating fallback.
tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True)
tool.setup(
idname=item.idname,
@@ -711,6 +765,9 @@ def _activate_by_item(context, space_type, item, index):
data_block=item.data_block or "",
operator=item.operator or "",
index=index,
idname_fallback=item_fallback.idname if item_fallback else "",
keymap_fallback=(item_fallback.keymap[0] or "") if item_fallback else "",
)
WindowManager = bpy.types.WindowManager

View File

@@ -472,7 +472,7 @@ class _defs_edit_mesh:
idname="builtin.rip_region",
label="Rip Region",
icon="ops.mesh.rip",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
draw_settings=draw_settings,
)
@@ -512,7 +512,7 @@ class _defs_edit_mesh:
idname="builtin.edge_slide",
label="Edge Slide",
icon="ops.transform.edge_slide",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@@ -527,7 +527,7 @@ class _defs_edit_mesh:
idname="builtin.vertex_slide",
label="Vertex Slide",
icon="ops.transform.vert_slide",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
draw_settings=draw_settings,
)
@@ -579,7 +579,7 @@ class _defs_edit_mesh:
idname="builtin.inset_faces",
label="Inset Faces",
icon="ops.mesh.inset",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@@ -597,7 +597,7 @@ class _defs_edit_mesh:
idname="builtin.bevel",
label="Bevel",
icon="ops.mesh.bevel",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@@ -629,7 +629,7 @@ class _defs_edit_mesh:
idname="builtin.extrude_along_normals",
label="Extrude Along Normals",
icon="ops.mesh.extrude_region_shrink_fatten",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
operator="mesh.extrude_region_shrink_fatten",
keymap=(),
draw_settings=draw_settings,
@@ -641,7 +641,7 @@ class _defs_edit_mesh:
idname="builtin.extrude_individual",
label="Extrude Individual",
icon="ops.mesh.extrude_faces_move",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
)
@@ -698,7 +698,7 @@ class _defs_edit_mesh:
idname="builtin.smooth",
label="Smooth",
icon="ops.mesh.vertices_smooth",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@@ -714,7 +714,7 @@ class _defs_edit_mesh:
idname="builtin.randomize",
label="Randomize",
icon="ops.transform.vertex_random",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@@ -753,7 +753,7 @@ class _defs_edit_mesh:
idname="builtin.shrink_fatten",
label="Shrink/Fatten",
icon="ops.transform.shrink_fatten",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@@ -764,7 +764,7 @@ class _defs_edit_mesh:
idname="builtin.push_pull",
label="Push/Pull",
icon="ops.transform.push_pull",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
)
@@ -890,7 +890,7 @@ class _defs_edit_curve:
idname="builtin.randomize",
label="Randomize",
icon="ops.curve.vertex_random",
widget=None,
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)

View File

@@ -78,6 +78,27 @@ class TOPBAR_HT_upper_bar(Header):
unlink="scene.view_layer_remove")
class TOPBAR_PT_tool_fallback(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Layers"
bl_ui_units_x = 8
def draw(self, context):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
layout = self.layout
tool_settings = context.tool_settings
layout.column().prop(tool_settings, "workspace_tool_type", expand=True)
if tool_settings.workspace_tool_type == 'FALLBACK':
tool = context.tool
ToolSelectPanelHelper.draw_active_tool_fallback(
context, layout, tool,
show_tool_name=True,
)
class TOPBAR_PT_gpencil_layers(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@@ -772,6 +793,7 @@ classes = (
TOPBAR_MT_render,
TOPBAR_MT_window,
TOPBAR_MT_help,
TOPBAR_PT_tool_fallback,
TOPBAR_PT_gpencil_layers,
TOPBAR_PT_gpencil_primitive,
TOPBAR_PT_gpencil_fill,

View File

@@ -71,29 +71,45 @@ typedef struct ButtonGizmo2D {
/* -------------------------------------------------------------------- */
static void button2d_geom_draw_backdrop(const wmGizmo *gz, const float color[4], const bool select)
static void button2d_geom_draw_backdrop(const wmGizmo *gz,
const float color[4],
const float fill_alpha,
const bool select)
{
GPU_line_width(gz->line_width);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
/* TODO, other draw styles */
if (color[3] == 1.0 && select == false) {
if (color[3] == 1.0 && fill_alpha == 1.0 && select == false) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
GPU_polygon_smooth(0);
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
GPU_polygon_smooth(1);
immUnbindProgram();
}
else {
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
}
/* Draw fill. */
if ((fill_alpha != 0.0f) || (select == true)) {
float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]};
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(fill_color);
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
}
immUnbindProgram();
/* Draw outline. */
if ((fill_alpha != 1.0f) && (select == false)) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
GPU_line_width(gz->line_width);
imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
}
}
UNUSED_VARS(select);
}
@@ -167,14 +183,15 @@ static void button2d_draw_intern(const bContext *C,
if (select) {
BLI_assert(is_3d);
button2d_geom_draw_backdrop(gz, color, select);
button2d_geom_draw_backdrop(gz, color, 1.0, select);
}
else {
GPU_blend(true);
if (draw_options & ED_GIZMO_BUTTON_SHOW_BACKDROP) {
button2d_geom_draw_backdrop(gz, color, select);
const float fill_alpha = RNA_float_get(gz->ptr, "backdrop_fill_alpha");
button2d_geom_draw_backdrop(gz, color, fill_alpha, select);
}
if (button->shape_batch[0] != NULL) {
@@ -336,6 +353,16 @@ static void GIZMO_GT_button_2d(wmGizmoType *gzt)
/* Currently only used for cursor display. */
RNA_def_boolean(gzt->srna, "show_drag", true, "Show Drag", "");
RNA_def_float(gzt->srna,
"backdrop_fill_alpha",
1.0f,
0.0f,
1.0,
"When below 1.0, draw the interior with a reduced alpha compared to the outline",
"",
0.0f,
1.0f);
}
void ED_gizmotypes_button_2d(void)

View File

@@ -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

View File

@@ -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);

View File

@@ -0,0 +1,233 @@
/*
* 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_listbase.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 (!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_steal_keymap = false;
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
return;
}
else {
gzgroup->use_steal_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_STEAL_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_STEAL_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;
}
/** \} */

View File

@@ -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);

View File

@@ -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_steal_keymap = true;
}
else {
gzgroup->use_steal_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_STEAL_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_STEAL_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_steal_keymap = true;
}
else {
gzgroup->use_steal_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_STEAL_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_steal_keymap = true;
}
else {
gzgroup->use_steal_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_STEAL_KEYMAP;
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;

View File

@@ -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,11 +129,19 @@ 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++) {
@@ -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(&macroptr, "release_confirm", true);
bool constraint[3] = {0, 0, 0};
RNA_boolean_set_array(&macroptr, "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_steal_keymap = true;
}
else {
WM_gizmo_set_flag(ggd->invoke_view, WM_GIZMO_HIDDEN, true);
gzgroup->use_steal_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(&macroptr, "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_STEAL_KEYMAP;
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;

View File

@@ -1502,7 +1502,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;
@@ -2035,6 +2038,12 @@ enum {
SCE_OBJECT_MODE_LOCK = (1 << 0),
};
/* ToolSettings.workspace_tool_flag */
enum {
SCE_WORKSPACE_TOOL_DEFAULT = 0,
SCE_WORKSPACE_TOOL_FALLBACK = 1,
};
/* ToolSettings.snap_flag */
#define SCE_SNAP (1 << 0)
#define SCE_SNAP_ROTATE (1 << 1)

View File

@@ -35,6 +35,10 @@ typedef struct bToolRef_Runtime {
char gizmo_group[64];
char data_block[64];
/** TODO: document. */
char idname_fallback[64];
char keymap_fallback[64];
/** Use to infer primary operator to use when setting accelerator keys. */
char op[64];

View File

@@ -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, "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);

View File

@@ -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);
}

View File

@@ -43,14 +43,16 @@
static void rna_WorkSpaceTool_setup(ID *id,
bToolRef *tref,
bContext *C,
const char *tool_idname,
const char *name,
/* 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, name);
}
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);

View File

@@ -120,6 +120,8 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
* We could even move the options into the key-map item.
* ~ campbell. */
WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 6),
WM_GIZMOGROUPTYPE_TOOL_STEAL_KEYMAP = (1 << 7),
} eWM_GizmoFlagGroupTypeFlag;
/**
@@ -443,6 +445,8 @@ typedef struct wmGizmoGroup {
bool tag_remove;
bool use_steal_keymap;
void *customdata;
/** For freeing customdata from above. */
void (*customdata_free)(void *);

View File

@@ -3728,8 +3728,38 @@ 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 (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_STEAL_KEYMAP) {
/* If all are hidden, don't override. */
if (gzgroup->use_steal_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;

View File

@@ -351,6 +351,22 @@ 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 steal_keymap = false;
if (tref_rt->gizmo_group[0]) {
wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(tref_rt->gizmo_group, false);
if (gzgt) {
if (gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_STEAL_KEYMAP) {
steal_keymap = true;
}
}
}
if (steal_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);