/* * 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 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->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag; gzgt->refresh = WIDGETGROUP_value_operator_redo_refresh; } /** \} */ /* -------------------------------------------------------------------- */ /** \name Public API * \{ */ void ED_gizmogrouptypes_value_2d(void) { WM_gizmogrouptype_append(WM_GGT_value_operator_redo); } /** \} */