Gizmo: add undo and name #104888
|
@ -173,6 +173,8 @@ static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgrou
|
|||
RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED);
|
||||
ED_gizmo_arrow3d_set_range_fac(gz, 4.0f);
|
||||
UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color);
|
||||
|
||||
WM_gizmo_enable_undo(gz, "Adjust");
|
||||
}
|
||||
|
||||
/* Spot blend gizmo. */
|
||||
|
@ -187,6 +189,10 @@ static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgrou
|
|||
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
|
||||
UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
|
||||
|
||||
/* FIXME: this should ideally use RNA with a way to intercept the value and transform it based
|
||||
* on the context (3D scene, viewport... etc), instead of using custom getter/setter and call
|
||||
* `WM_gizmo_target_property_def_rna()` separately. The same comment applies to spot radius
|
||||
* gizmo, light point gizmo and possibly light area gizmo. */
|
||||
WM_gizmo_target_property_def_func(gz,
|
||||
"matrix",
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
|
@ -195,6 +201,8 @@ static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgrou
|
|||
.range_get_fn = NULL,
|
||||
.user_data = (void *)C,
|
||||
});
|
||||
|
||||
WM_gizmo_enable_undo(gz, "Adjust");
|
||||
}
|
||||
|
||||
/* Spot radius gizmo. */
|
||||
|
@ -217,6 +225,8 @@ static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgrou
|
|||
.range_get_fn = NULL,
|
||||
.user_data = (void *)C,
|
||||
});
|
||||
|
||||
WM_gizmo_enable_undo(gz, "Adjust");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,11 +239,11 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr
|
|||
Object *ob = BKE_view_layer_active_object_get(view_layer);
|
||||
Light *la = ob->data;
|
||||
|
||||
PointerRNA lamp_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
|
||||
|
||||
/* Spot angle gizmo. */
|
||||
{
|
||||
PointerRNA lamp_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
|
||||
|
||||
wmGizmo *gz = ls_gzgroup->spot_angle;
|
||||
float dir[3];
|
||||
negate_v3_v3(dir, ob->object_to_world[2]);
|
||||
|
@ -255,6 +265,14 @@ static void WIDGETGROUP_light_spot_refresh(const bContext *C, wmGizmoGroup *gzgr
|
|||
negate_v3_v3(dir, ob->object_to_world[2]);
|
||||
mul_v3_fl(dir, CONE_SCALE * cosf(0.5f * la->spotsize));
|
||||
add_v3_v3(gz->matrix_basis[3], dir);
|
||||
|
||||
WM_gizmo_target_property_def_rna(gz, "matrix", &lamp_ptr, "spot_blend", -1);
|
||||
}
|
||||
|
||||
/* Spot radius gizmo. */
|
||||
{
|
||||
WM_gizmo_target_property_def_rna(
|
||||
ls_gzgroup->spot_radius, "matrix", &lamp_ptr, "shadow_soft_size", -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,6 +361,8 @@ static void WIDGETGROUP_light_point_setup(const bContext *C, wmGizmoGroup *gzgro
|
|||
.range_get_fn = NULL,
|
||||
.user_data = (void *)C,
|
||||
});
|
||||
|
||||
WM_gizmo_enable_undo(gz, "Adjust");
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_light_point_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
|
@ -362,6 +382,20 @@ static void WIDGETGROUP_light_point_draw_prepare(const bContext *C, wmGizmoGroup
|
|||
WM_gizmo_set_matrix_location(gz, ob->object_to_world[3]);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_light_point_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
wmGizmoWrapper *wwrapper = gzgroup->customdata;
|
||||
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer);
|
||||
Light *la = BKE_view_layer_active_object_get(view_layer)->data;
|
||||
|
||||
PointerRNA lamp_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
|
||||
|
||||
WM_gizmo_target_property_def_rna(wwrapper->gizmo, "matrix", &lamp_ptr, "shadow_soft_size", -1);
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_light_point(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
gzgt->name = "Point Light Widgets";
|
||||
|
@ -372,6 +406,7 @@ void VIEW3D_GGT_light_point(wmGizmoGroupType *gzgt)
|
|||
gzgt->poll = WIDGETGROUP_light_point_poll;
|
||||
gzgt->setup = WIDGETGROUP_light_point_setup;
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
|
||||
gzgt->refresh = WIDGETGROUP_light_point_refresh;
|
||||
gzgt->draw_prepare = WIDGETGROUP_light_point_draw_prepare;
|
||||
}
|
||||
|
||||
|
@ -452,6 +487,8 @@ static void WIDGETGROUP_light_area_setup(const bContext *UNUSED(C), wmGizmoGroup
|
|||
|
||||
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
|
||||
UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
|
||||
|
||||
WM_gizmo_enable_undo(gz, "Resize");
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
|
@ -472,7 +509,7 @@ static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgr
|
|||
}
|
||||
RNA_enum_set(gz->ptr, "transform", flag);
|
||||
|
||||
/* need to set property here for undo. TODO: would prefer to do this in _init. */
|
||||
/* Need to set property here for `la`. TODO: would prefer to do this in _init. */
|
||||
WM_gizmo_target_property_def_func(gz,
|
||||
"matrix",
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
|
|
|
@ -269,6 +269,7 @@ void WM_gizmo_target_property_clear_rna(struct wmGizmo *gz, const char *idname);
|
|||
|
||||
bool WM_gizmo_target_property_is_valid_any(struct wmGizmo *gz);
|
||||
bool WM_gizmo_target_property_is_valid(const struct wmGizmoProperty *gz_prop);
|
||||
struct wmGizmoProperty *WM_gizmo_target_property_get_unique(struct wmGizmo *gz);
|
||||
float WM_gizmo_target_property_float_get(const struct wmGizmo *gz,
|
||||
struct wmGizmoProperty *gz_prop);
|
||||
void WM_gizmo_target_property_float_set(struct bContext *C,
|
||||
|
@ -508,6 +509,8 @@ void WM_gizmo_group_remove_by_tool(struct bContext *C,
|
|||
|
||||
void WM_gizmo_group_tag_remove(struct wmGizmoGroup *gzgroup);
|
||||
|
||||
void WM_gizmo_enable_undo(struct wmGizmo *gz, const char *name);
|
||||
|
||||
/* Wrap Group Type Callbacks. */
|
||||
|
||||
bool WM_gizmo_group_type_poll(const struct bContext *C, const struct wmGizmoGroupType *gzgt);
|
||||
|
|
|
@ -82,6 +82,9 @@ typedef enum eWM_GizmoFlag {
|
|||
|
||||
/** Don't use tool-tips for this gizmo (can be distracting). */
|
||||
WM_GIZMO_NO_TOOLTIP = (1 << 12),
|
||||
|
||||
/** Do an undo push after gizmo tweaking is finished.*/
|
||||
WM_GIZMO_UNDO = (1 << 13),
|
||||
} eWM_GizmoFlag;
|
||||
|
||||
ENUM_OPERATORS(eWM_GizmoFlag, WM_GIZMO_NO_TOOLTIP);
|
||||
|
@ -206,6 +209,9 @@ typedef struct wmGizmoOpElem {
|
|||
struct wmGizmo {
|
||||
struct wmGizmo *next, *prev;
|
||||
|
||||
/** Text for tooltip, undo. */
|
||||
const char *name;
|
||||
|
||||
/** While we don't have a real type, use this to put type-like vars. */
|
||||
const struct wmGizmoType *type;
|
||||
|
||||
|
|
|
@ -738,4 +738,13 @@ bool WM_gizmo_context_check_drawstep(const struct bContext *C, eWM_GizmoFlagMapD
|
|||
return true;
|
||||
}
|
||||
|
||||
void WM_gizmo_enable_undo(wmGizmo *gz, const char *name)
|
||||
{
|
||||
/* Operators handle undo themselves. */
|
||||
BLI_assert(gz->op_data == NULL);
|
||||
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_UNDO, true);
|
||||
gz->name = name;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "ED_screen.h"
|
||||
#include "ED_undo.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
/* own includes */
|
||||
#include "wm_gizmo_intern.h"
|
||||
#include "wm_gizmo_wmapi.h"
|
||||
|
@ -451,8 +453,25 @@ static bool gizmo_tweak_start_and_finish(
|
|||
static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal)
|
||||
{
|
||||
GizmoTweakData *mtweak = op->customdata;
|
||||
if (mtweak->gz_modal->type->exit) {
|
||||
mtweak->gz_modal->type->exit(C, mtweak->gz_modal, cancel);
|
||||
wmGizmo *gz = mtweak->gz_modal;
|
||||
if (gz->type->exit) {
|
||||
/* Push undo if needed. */
|
||||
if ((gz->flag & WM_GIZMO_UNDO) && !cancel) {
|
||||
const wmGizmoProperty *gz_prop = WM_gizmo_target_property_get_unique(gz);
|
||||
|
||||
if (!gz_prop || RNA_struct_undo_check(gz_prop->ptr.type)) {
|
||||
/* Use the name of `wmGizmoGroupType` if we don't know which RNA property this gizmo is
|
||||
* editting. */
|
||||
const char *prop_name = gz_prop ? RNA_property_ui_name(gz_prop->prop) :
|
||||
N_(gz->parent_gzgroup->type->name);
|
||||
char *undo_str = (gz->name && gz->name[0]) ?
|
||||
BLI_sprintfN("%s: %s", TIP_(gz->name), prop_name) :
|
||||
BLI_strdup(prop_name);
|
||||
|
||||
ED_undo_push(C, undo_str);
|
||||
MEM_freeN(undo_str);
|
||||
}
|
||||
}
|
||||
gz->type->exit(C, mtweak->gz_modal, cancel);
|
||||
}
|
||||
if (clear_modal) {
|
||||
/* The gizmo may have been removed. */
|
||||
|
@ -606,12 +625,6 @@ void GIZMOGROUP_OT_gizmo_tweak(wmOperatorType *ot)
|
|||
/* api callbacks */
|
||||
ot->invoke = gizmo_tweak_invoke;
|
||||
ot->modal = gizmo_tweak_modal;
|
||||
|
||||
/* TODO(@ideasman42): This causes problems tweaking settings for operators,
|
||||
* need to find a way to support this. */
|
||||
#if 0
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
#endif
|
||||
}
|
||||
|
||||
wmKeyMap *wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf)
|
||||
|
|
|
@ -156,6 +156,28 @@ bool WM_gizmo_target_property_is_valid_any(wmGizmo *gz)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Get the `*wmGizmoProperty` with valid `PropertyRNA`. If there is none or multiple, returns
|
||||
* `NULL`. */
|
||||
wmGizmoProperty *WM_gizmo_target_property_get_unique(wmGizmo *gz)
|
||||
{
|
||||
int count = 0;
|
||||
wmGizmoProperty *gz_unique_prop;
|
||||
|
||||
wmGizmoProperty *gz_prop_array = wm_gizmo_target_property_array(gz);
|
||||
for (int i = 0; i < gz->type->target_property_defs_len; i++) {
|
||||
wmGizmoProperty *gz_prop = &gz_prop_array[i];
|
||||
if (gz_prop->prop != NULL) {
|
||||
count++;
|
||||
gz_unique_prop = gz_prop;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
return gz_unique_prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop)
|
||||
{
|
||||
return ((gz_prop->prop != NULL) ||
|
||||
|
|
Loading…
Reference in New Issue
I find this
get_unique
concept quite strange, it is here because gizmos are allowed to have multiple properties, and if there are multiple I don't know which one just got edited, and could it be that only one of them has undo.