Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-09-13 02:04:50 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-09-13 02:10:19 +0300
commit1f1802307f9a3b1a09b9eb8d70dadc7c849c5e2c (patch)
tree75a1859bba472bc01d3801ce027d290adfdc8629 /source/blender
parent26a6e58e9a259327fd5125095f052a42a9405320 (diff)
Gizmo: value2d utility to adjust operator values
This allows any operator to interactively redo without having to manually make each operator modal.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/gizmo_library/CMakeLists.txt2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_group_types/value2d_gizmo_group.c176
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/value2d_gizmo.c145
-rw-r--r--source/blender/editors/include/ED_gizmo_library.h4
-rw-r--r--source/blender/editors/space_api/spacetypes.c4
-rw-r--r--source/blender/makesrna/intern/rna_wm_gizmo.c2
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c20
-rw-r--r--source/blender/windowmanager/intern/wm_toolsystem.c4
9 files changed, 357 insertions, 2 deletions
diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt
index f89c3c27522..0e7b2a8be0f 100644
--- a/source/blender/editors/gizmo_library/CMakeLists.txt
+++ b/source/blender/editors/gizmo_library/CMakeLists.txt
@@ -45,6 +45,7 @@ set(SRC
geometry/geom_arrow_gizmo.c
geometry/geom_cube_gizmo.c
geometry/geom_dial_gizmo.c
+ gizmo_group_types/value2d_gizmo_group.c
gizmo_types/arrow2d_gizmo.c
gizmo_types/arrow3d_gizmo.c
gizmo_types/blank3d_gizmo.c
@@ -54,6 +55,7 @@ set(SRC
gizmo_types/dial3d_gizmo.c
gizmo_types/move3d_gizmo.c
gizmo_types/primitive3d_gizmo.c
+ gizmo_types/value2d_gizmo.c
)
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/gizmo_library/gizmo_group_types/value2d_gizmo_group.c b/source/blender/editors/gizmo_library/gizmo_group_types/value2d_gizmo_group.c
new file mode 100644
index 00000000000..274d35269d1
--- /dev/null
+++ b/source/blender/editors/gizmo_library/gizmo_group_types/value2d_gizmo_group.c
@@ -0,0 +1,176 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file value2d_gizmo_group.c
+ * \ingroup edgizmolib
+ *
+ * \name 2D Value Gizmo
+ *
+ * \brief Gizmo that edits a value for operator redo.
+ */
+
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+
+#include "ED_undo.h"
+#include "ED_screen.h"
+#include "ED_gizmo_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Value Gizmo
+ * \{ */
+
+struct ValueOpRedoGroup {
+ wmGizmo *gizmo;
+ struct {
+ const bContext *context; /* needed for redo. */
+ wmOperator *op;
+ } state;
+};
+
+static void gizmo_op_redo_exec(struct ValueOpRedoGroup *igzgroup)
+{
+ wmOperator *op = igzgroup->state.op;
+ if (op == WM_operator_last_redo((bContext *)igzgroup->state.context)) {
+ ED_undo_operator_repeat((bContext *)igzgroup->state.context, op);
+ }
+}
+
+/* translate callbacks */
+static void gizmo_value_operator_redo_value_get(
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
+ void *value_p)
+{
+ float *value = value_p;
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
+
+ struct ValueOpRedoGroup *igzgroup = gz->parent_gzgroup->customdata;
+ wmOperator *op = igzgroup->state.op;
+ *value = RNA_property_float_get(op->ptr, op->type->prop);
+}
+
+static void gizmo_value_operator_redo_value_set(
+ const wmGizmo *gz, wmGizmoProperty *gz_prop,
+ const void *value_p)
+{
+ const float *value = value_p;
+ BLI_assert(gz_prop->type->array_length == 1);
+ UNUSED_VARS_NDEBUG(gz_prop);
+
+ struct ValueOpRedoGroup *igzgroup = gz->parent_gzgroup->customdata;
+ wmOperator *op = igzgroup->state.op;
+ RNA_property_float_set(op->ptr, op->type->prop, *value);
+ gizmo_op_redo_exec(igzgroup);
+}
+
+static void WIDGETGROUP_value_operator_redo_modal_from_setup(
+ const bContext *C, wmGizmoGroup *gzgroup)
+{
+ /* Start off dragging. */
+ wmWindow *win = CTX_wm_window(C);
+ wmGizmo *gz = gzgroup->gizmos.first;
+ wmGizmoMap *gzmap = gzgroup->parent_gzmap;
+ WM_gizmo_modal_set_from_setup(
+ gzmap, (bContext *)C, gz, 0, win->eventstate);
+}
+
+static void WIDGETGROUP_value_operator_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
+{
+ struct ValueOpRedoGroup *igzgroup = MEM_mallocN(sizeof(struct ValueOpRedoGroup), __func__);
+
+ igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_value_2d", gzgroup, NULL);
+ wmGizmo *gz = igzgroup->gizmo;
+
+ igzgroup->state.context = C;
+ igzgroup->state.op = WM_operator_last_redo(C);
+
+ gzgroup->customdata = igzgroup;
+
+ UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
+ UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
+
+ WM_gizmo_target_property_def_func(
+ gz, "offset",
+ &(const struct wmGizmoPropertyFnParams) {
+ .value_get_fn = gizmo_value_operator_redo_value_get,
+ .value_set_fn = gizmo_value_operator_redo_value_set,
+ .range_get_fn = NULL,
+ .user_data = igzgroup,
+ });
+
+ /* Become modal as soon as it's started. */
+ WIDGETGROUP_value_operator_redo_modal_from_setup(C, gzgroup);
+}
+
+static void WIDGETGROUP_value_operator_redo_refresh(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+{
+ struct ValueOpRedoGroup *igzgroup = gzgroup->customdata;
+ wmGizmo *gz = igzgroup->gizmo;
+ wmOperator *op = WM_operator_last_redo((bContext *)igzgroup->state.context);
+ wmGizmoMap *gzmap = gzgroup->parent_gzmap;
+
+ /* FIXME */
+ extern struct wmGizmo *wm_gizmomap_modal_get(struct wmGizmoMap *gzmap);
+ if ((op != igzgroup->state.op) ||
+ (wm_gizmomap_modal_get(gzmap) != gz))
+ {
+ WM_gizmo_group_type_unlink_delayed_ptr(gzgroup->type);
+ }
+}
+
+static void WM_GGT_value_operator_redo(wmGizmoGroupType *gzgt)
+{
+ gzgt->name = "Value Operator Redo";
+ gzgt->idname = "WM_GGT_value_operator_redo";
+
+ /* FIXME, allow multiple. */
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_INIT;
+
+ gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
+ gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
+
+
+ gzgt->setup = WIDGETGROUP_value_operator_redo_setup;
+ gzgt->refresh = WIDGETGROUP_value_operator_redo_refresh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Public API
+ * \{ */
+
+void ED_gizmogrouptypes_value_2d(void)
+{
+ WM_gizmogrouptype_append(WM_GGT_value_operator_redo);
+}
+
+/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_types/value2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/value2d_gizmo.c
new file mode 100644
index 00000000000..c0c53523ea9
--- /dev/null
+++ b/source/blender/editors/gizmo_library/gizmo_types/value2d_gizmo.c
@@ -0,0 +1,145 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file value2d_gizmo.c
+ * \ingroup edgizmolib
+ *
+ * \name Value Gizmo
+ *
+ * \brief Gizmo that can be used to click and drag a value.
+ *
+ * Use this in cases where it may be useful to have a tool,
+ * but the tool doesn't relate to an on-screen handle.
+ * eg: smooth or randomize.
+ *
+ * Exactly how this maps X/Y axis, and draws - may change.
+ * The purpose here is to avoid having to write custom modal handlers for each operator.
+ *
+ * So we can use a single gizmo to make redoing an operator seem modal.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+
+#include "ED_gizmo_library.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+/* own includes */
+#include "../gizmo_geometry.h"
+#include "../gizmo_library_intern.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Value Gizmo
+ *
+ * \{ */
+
+typedef struct ValueInteraction {
+ float init_mval[2];
+ float init_prop_value;
+ float range[2];
+} ValueInteraction;
+
+static void gizmo_value_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
+{
+ /* pass */
+}
+
+static int gizmo_value_modal(
+ bContext *C, wmGizmo *gz, const wmEvent *event,
+ eWM_GizmoFlagTweak UNUSED(tweak_flag))
+{
+ ARegion *ar = CTX_wm_region(C);
+ ValueInteraction *inter = gz->interaction_data;
+ const float value_scale = 4.0f; /* Could be option. */
+ const float value_range = inter->range[1] - inter->range[0];
+ const float value_delta = (
+ inter->init_prop_value +
+ (((event->mval[0] - inter->init_mval[0]) / ar->winx) * value_range)) * value_scale;
+
+ /* set the property for the operator and call its modal function */
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init_prop_value + value_delta);
+ }
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+static int gizmo_value_invoke(
+ bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event)
+{
+ ValueInteraction *inter = MEM_callocN(sizeof(ValueInteraction), __func__);
+
+ inter->init_mval[0] = event->mval[0];
+ inter->init_mval[1] = event->mval[1];
+
+ wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset");
+ if (WM_gizmo_target_property_is_valid(gz_prop)) {
+ inter->init_prop_value = WM_gizmo_target_property_float_get(gz, gz_prop);
+ if (!WM_gizmo_target_property_float_range_get(gz, gz_prop, inter->range)) {
+ inter->range[0] = 0.0f;
+ inter->range[1] = 1.0f;
+ }
+ }
+
+ gz->interaction_data = inter;
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int gizmo_value_test_select(
+ bContext *UNUSED(C), wmGizmo *UNUSED(gz), const int UNUSED(mval[2]))
+{
+ return 0;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Value Gizmo API
+ *
+ * \{ */
+
+static void GIZMO_GT_value_2d(wmGizmoType *gzt)
+{
+ /* identifiers */
+ gzt->idname = "GIZMO_GT_value_2d";
+
+ /* api callbacks */
+ gzt->draw = gizmo_value_draw;
+ gzt->invoke = gizmo_value_invoke;
+ gzt->modal = gizmo_value_modal;
+ gzt->test_select = gizmo_value_test_select;
+
+ gzt->struct_size = sizeof(wmGizmo);
+
+ WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 1);
+ /* Options: relative / absolute */
+}
+
+void ED_gizmotypes_value_2d(void)
+{
+ WM_gizmotype_append(GIZMO_GT_value_2d);
+}
+
+/** \} */
diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h
index 02c5a80bf62..faf0040779f 100644
--- a/source/blender/editors/include/ED_gizmo_library.h
+++ b/source/blender/editors/include/ED_gizmo_library.h
@@ -42,6 +42,10 @@ void ED_gizmotypes_facemap_3d(void);
void ED_gizmotypes_preselect_3d(void);
void ED_gizmotypes_primitive_3d(void);
void ED_gizmotypes_blank_3d(void);
+void ED_gizmotypes_value_2d(void);
+
+/* gizmo group types */
+void ED_gizmogrouptypes_value_2d(void);
struct bContext;
struct Object;
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index c811e127cfe..91dff98f906 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -140,6 +140,10 @@ void ED_spacetypes_init(void)
ED_gizmotypes_blank_3d();
ED_gizmotypes_cage_2d();
ED_gizmotypes_cage_3d();
+ ED_gizmotypes_value_2d();
+
+ /* gizmo group types */
+ ED_gizmogrouptypes_value_2d();
/* register types for operators and gizmos */
spacetypes = BKE_spacetypes_list();
diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c
index 4cb682df05d..6a1d00b13ae 100644
--- a/source/blender/makesrna/intern/rna_wm_gizmo.c
+++ b/source/blender/makesrna/intern/rna_wm_gizmo.c
@@ -1241,6 +1241,8 @@ static void rna_def_gizmogroup(BlenderRNA *brna)
""},
{WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL, "SHOW_MODAL_ALL", 0, "Show Modal All",
"Show all while interacting"},
+ {WM_GIZMOGROUPTYPE_TOOL_INIT, "TOOL_INIT", 0, "Tool Init",
+ "Postpone running until tool operator run (when used with a tool)"},
{0, NULL, 0, NULL, NULL}
};
prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
index 46b6b85e8f2..2ab536752c3 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
@@ -106,6 +106,8 @@ typedef enum eWM_GizmoFlagGroupTypeFlag {
WM_GIZMOGROUPTYPE_PERSISTENT = (1 << 4),
/* Show all other gizmos when interacting. */
WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL = (1 << 5),
+ /* When used with tool, only run when activating the tool. */
+ WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 6),
} eWM_GizmoFlagGroupTypeFlag;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index cd1357e85b1..d9c8028c9bb 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2031,7 +2031,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
if (ot && wm_operator_check_locked_interface(C, ot)) {
bool use_last_properties = true;
PointerRNA tool_properties = {{0}};
- bool use_tool_properties = (handler->keymap_tool != NULL);
+ const bool is_tool = (handler->keymap_tool != NULL);
+ const bool use_tool_properties = is_tool;
if (use_tool_properties) {
WM_toolsystem_ref_properties_init_for_keymap(handler->keymap_tool, &tool_properties, properties, ot);
@@ -2044,6 +2045,23 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
if (use_tool_properties) {
WM_operator_properties_free(&tool_properties);
}
+
+ /* Link gizmo if 'WM_GIZMOGROUPTYPE_TOOL_INIT' is set. */
+ if (retval & OPERATOR_FINISHED) {
+ if (is_tool) {
+ bToolRef_Runtime *tref_rt = handler->keymap_tool->runtime;
+ if (tref_rt->gizmo_group[0]) {
+ const char *idname = tref_rt->gizmo_group;
+ wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
+ if (gzgt != NULL) {
+ if ((gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_INIT) != 0) {
+ WM_gizmo_group_type_ensure_ptr(gzgt);
+ }
+ }
+ }
+ }
+ }
+ /* Done linking gizmo. */
}
}
/* Finished and pass through flag as handled */
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index 0aa5e16a519..15b29902eb1 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -176,7 +176,9 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre
const char *idname = tref_rt->gizmo_group;
wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
if (gzgt != NULL) {
- WM_gizmo_group_type_ensure_ptr(gzgt);
+ if ((gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_INIT) == 0) {
+ WM_gizmo_group_type_ensure_ptr(gzgt);
+ }
}
else {
CLOG_WARN(WM_LOG_TOOLS, "'%s' widget not found", idname);