diff options
Diffstat (limited to 'source/blender/editors/gizmo_library/gizmo_group_types/value2d_gizmo_group.c')
-rw-r--r-- | source/blender/editors/gizmo_library/gizmo_group_types/value2d_gizmo_group.c | 176 |
1 files changed, 176 insertions, 0 deletions
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); +} + +/** \} */ |