Gizmo: add undo and name #104888
@ -1078,12 +1078,30 @@ static int gizmo_cage2d_modal(bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
/* Get properties. */
|
||||
{
|
||||
wmGizmoProperty *gz_prop;
|
||||
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "size");
|
||||
if (gz_prop->type != NULL) {
|
||||
float size[2];
|
||||
if (WM_gizmo_target_property_array_length(gz, gz_prop) == 2) {
|
||||
WM_gizmo_target_property_float_get_array(gz, gz_prop, size);
|
||||
gz->matrix_offset[0][0] = size[0];
|
||||
gz->matrix_offset[1][1] = size[1];
|
||||
}
|
||||
else {
|
||||
gz->matrix_offset[0][0] = gz->matrix_offset[1][1] = WM_gizmo_target_property_float_get(
|
||||
gz, gz_prop);
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite if other properties exist. */
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
|
||||
if (gz_prop->type != NULL) {
|
||||
WM_gizmo_target_property_float_get_array(gz, gz_prop, &gz->matrix_offset[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
|
||||
/* do this to prevent clamping from changing size */
|
||||
@ -1215,9 +1233,28 @@ static int gizmo_cage2d_modal(bContext *C,
|
||||
mul_m4_m4_post(gz->matrix_offset, matrix_scale);
|
||||
}
|
||||
|
||||
/* Set properties. */
|
||||
{
|
||||
wmGizmoProperty *gz_prop;
|
||||
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "size");
|
||||
if (gz_prop->type != NULL) {
|
||||
float size[2];
|
||||
size[0] = gz->matrix_offset[0][0];
|
||||
if (WM_gizmo_target_property_array_length(gz, gz_prop) == 2) {
|
||||
size[1] = gz->matrix_offset[1][1];
|
||||
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, size);
|
||||
}
|
||||
else {
|
||||
WM_gizmo_target_property_float_set(C, gz, gz_prop, size[0]);
|
||||
}
|
||||
}
|
||||
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
|
||||
if (gz_prop->type != NULL) {
|
||||
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* tag the region for redraw */
|
||||
ED_region_tag_redraw_editor_overlays(CTX_wm_region(C));
|
||||
@ -1236,6 +1273,24 @@ static void gizmo_cage2d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
else if (STREQ(gz_prop->type->idname, "size")) {
|
||||
if (WM_gizmo_target_property_array_length(gz, gz_prop) == 2) {
|
||||
float size[2];
|
||||
WM_gizmo_target_property_float_get_array(gz, gz_prop, size);
|
||||
gz->matrix_offset[0][0] = size[0];
|
||||
int flag = RNA_enum_get(gz->ptr, "transform");
|
||||
if (flag & ED_GIZMO_CAGE_XFORM_FLAG_SHAPE_UNIFORM) {
|
||||
gz->matrix_offset[1][1] = size[0];
|
||||
}
|
||||
else {
|
||||
gz->matrix_offset[1][1] = size[1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
gz->matrix_offset[0][0] = gz->matrix_offset[1][1] = WM_gizmo_target_property_float_get(
|
||||
gz, gz_prop);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
@ -1253,7 +1308,15 @@ static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel)
|
||||
|
||||
wmGizmoProperty *gz_prop;
|
||||
|
||||
/* reset properties */
|
||||
/* Reset properties. */
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "size");
|
||||
if (gz_prop->type != NULL) {
|
||||
float size[2];
|
||||
size[0] = data->orig_matrix_offset[0][0];
|
||||
size[1] = data->orig_matrix_offset[1][1];
|
||||
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, size);
|
||||
}
|
||||
|
||||
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
|
||||
if (gz_prop->type != NULL) {
|
||||
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]);
|
||||
@ -1320,6 +1383,7 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
|
||||
"");
|
||||
|
||||
WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16);
|
||||
WM_gizmotype_target_property_def(gzt, "size", PROP_FLOAT, 2);
|
||||
}
|
||||
|
||||
void ED_gizmotypes_cage_2d(void)
|
||||
|
@ -102,6 +102,7 @@ enum {
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE = (1 << 2), /* Scales */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM = (1 << 3), /* Scales uniformly */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED = (1 << 4), /* Negative scale allowed */
|
||||
ED_GIZMO_CAGE_XFORM_FLAG_SHAPE_UNIFORM = (1 << 5), /* Equal size along all axes */
|
||||
};
|
||||
|
||||
/* draw_style */
|
||||
|
@ -996,8 +996,6 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
|
||||
{
|
||||
uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__);
|
||||
|
||||
/* TODO(@ideasman42): a way for gizmos to have their own descriptions (low priority). */
|
||||
|
||||
/* Operator Actions */
|
||||
{
|
||||
const bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part;
|
||||
@ -1054,6 +1052,13 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
|
||||
}
|
||||
}
|
||||
|
||||
/* Gizmo description. */
|
||||
if (gz->name && gz->name[0]) {
|
||||
uiTooltipField *field = text_field_add(
|
||||
data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Value, true);
|
||||
field->text = BLI_strdup(TIP_(gz->name));
|
||||
|
||||
}
|
||||
|
||||
/* Property Actions */
|
||||
if (gz->type->target_property_defs_len) {
|
||||
wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz);
|
||||
|
@ -45,17 +45,11 @@ typedef struct LightSpotWidgetGroup {
|
||||
wmGizmo *spot_radius;
|
||||
} LightSpotWidgetGroup;
|
||||
|
||||
static void gizmo_spot_blend_prop_matrix_get(const wmGizmo *UNUSED(gz),
|
||||
wmGizmoProperty *gz_prop,
|
||||
void *value_p)
|
||||
static void gizmo_spot_blend_prop_size_get(wmGizmoProperty *gz_prop, void *value)
|
||||
{
|
||||
BLI_assert(gz_prop->type->array_length == 16);
|
||||
float(*matrix)[4] = value_p;
|
||||
float *blend = value;
|
||||
|
||||
const bContext *C = gz_prop->custom_func.user_data;
|
||||
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;
|
||||
Light *la = gz_prop->ptr.data;
|
||||
|
||||
float a = cosf(la->spotsize * 0.5f);
|
||||
float b = la->spotblend;
|
||||
@ -64,76 +58,33 @@ static void gizmo_spot_blend_prop_matrix_get(const wmGizmo *UNUSED(gz),
|
||||
/* Tangent. */
|
||||
float t = sqrtf(1.0f - c * c) / c;
|
||||
|
||||
matrix[0][0] = 2.0f * CONE_SCALE * t * a;
|
||||
matrix[1][1] = 2.0f * CONE_SCALE * t * a;
|
||||
*blend = 2.0f * CONE_SCALE * t * a;
|
||||
}
|
||||
|
||||
static void gizmo_spot_blend_prop_matrix_set(const wmGizmo *UNUSED(gz),
|
||||
wmGizmoProperty *gz_prop,
|
||||
const void *value_p)
|
||||
static void gizmo_spot_blend_prop_size_set(wmGizmoProperty *gz_prop, void *value)
|
||||
{
|
||||
const float(*matrix)[4] = value_p;
|
||||
BLI_assert(gz_prop->type->array_length == 16);
|
||||
float *blend = value;
|
||||
|
||||
const bContext *C = gz_prop->custom_func.user_data;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
Light *la = BKE_view_layer_active_object_get(view_layer)->data;
|
||||
Light *la = gz_prop->ptr.data;
|
||||
|
||||
float a = cosf(la->spotsize * 0.5f);
|
||||
float t = matrix[0][0] * 0.5f * INV_CONE_SCALE / a;
|
||||
float t = *blend * 0.5f * INV_CONE_SCALE / a;
|
||||
float c = 1.0f / sqrt(t * t + 1.0f);
|
||||
|
||||
float spot_blend = safe_divide(clamp_f(c - a, 0.0f, 1.0f - a), 1.0f - a);
|
||||
|
||||
PointerRNA light_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &light_ptr);
|
||||
PropertyRNA *spot_blend_prop = RNA_struct_find_property(&light_ptr, "spot_blend");
|
||||
RNA_property_float_set(&light_ptr, spot_blend_prop, spot_blend);
|
||||
|
||||
RNA_property_update_main(CTX_data_main(C), scene, &light_ptr, spot_blend_prop);
|
||||
*blend = safe_divide(clamp_f(c - a, 0.0f, 1.0f - a), 1.0f - a);
|
||||
}
|
||||
|
||||
/* Used by spot light and point light. */
|
||||
static void gizmo_light_radius_prop_matrix_get(const wmGizmo *UNUSED(gz),
|
||||
wmGizmoProperty *gz_prop,
|
||||
void *value_p)
|
||||
static void gizmo_light_radius_prop_size_get(wmGizmoProperty *UNUSED(gz_prop), void *radius)
|
||||
{
|
||||
BLI_assert(gz_prop->type->array_length == 16);
|
||||
float(*matrix)[4] = value_p;
|
||||
|
||||
const bContext *C = gz_prop->custom_func.user_data;
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(CTX_data_scene(C), view_layer);
|
||||
const Light *la = BKE_view_layer_active_object_get(view_layer)->data;
|
||||
|
||||
const float diameter = 2.0f * la->radius;
|
||||
matrix[0][0] = diameter;
|
||||
matrix[1][1] = diameter;
|
||||
float *diameter = radius;
|
||||
*diameter = 2.0f * (*(float *)radius);
|
||||
}
|
||||
|
||||
static void gizmo_light_radius_prop_matrix_set(const wmGizmo *UNUSED(gz),
|
||||
wmGizmoProperty *gz_prop,
|
||||
const void *value_p)
|
||||
static void gizmo_light_radius_prop_size_set(wmGizmoProperty *UNUSED(gz_prop), void *diameter)
|
||||
{
|
||||
const float(*matrix)[4] = value_p;
|
||||
BLI_assert(gz_prop->type->array_length == 16);
|
||||
|
||||
const bContext *C = gz_prop->custom_func.user_data;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
Light *la = BKE_view_layer_active_object_get(view_layer)->data;
|
||||
|
||||
const float radius = 0.5f * len_v3(matrix[0]);
|
||||
|
||||
PointerRNA light_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &light_ptr);
|
||||
PropertyRNA *radius_prop = RNA_struct_find_property(&light_ptr, "shadow_soft_size");
|
||||
RNA_property_float_set(&light_ptr, radius_prop, radius);
|
||||
|
||||
RNA_property_update_main(CTX_data_main(C), scene, &light_ptr, radius_prop);
|
||||
float *radius = diameter;
|
||||
*radius = 0.5f * (*(float *)diameter);
|
||||
}
|
||||
|
||||
static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
|
||||
@ -160,7 +111,7 @@ static bool WIDGETGROUP_light_spot_poll(const bContext *C, wmGizmoGroupType *UNU
|
||||
return false;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
static void WIDGETGROUP_light_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
||||
{
|
||||
LightSpotWidgetGroup *ls_gzgroup = MEM_mallocN(sizeof(LightSpotWidgetGroup), __func__);
|
||||
|
||||
@ -173,6 +124,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,14 +140,7 @@ 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);
|
||||
|
||||
WM_gizmo_target_property_def_func(gz,
|
||||
"matrix",
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.value_get_fn = gizmo_spot_blend_prop_matrix_get,
|
||||
.value_set_fn = gizmo_spot_blend_prop_matrix_set,
|
||||
.range_get_fn = NULL,
|
||||
.user_data = (void *)C,
|
||||
});
|
||||
WM_gizmo_enable_undo(gz, "Adjust");
|
||||
}
|
||||
|
||||
/* Spot radius gizmo. */
|
||||
@ -209,14 +155,7 @@ 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);
|
||||
|
||||
WM_gizmo_target_property_def_func(gz,
|
||||
"matrix",
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.value_get_fn = gizmo_light_radius_prop_matrix_get,
|
||||
.value_set_fn = gizmo_light_radius_prop_matrix_set,
|
||||
.range_get_fn = NULL,
|
||||
.user_data = (void *)C,
|
||||
});
|
||||
WM_gizmo_enable_undo(gz, "Adjust");
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,11 +168,13 @@ 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;
|
||||
|
||||
/* Spot angle gizmo. */
|
||||
{
|
||||
PointerRNA lamp_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
|
||||
|
||||
/* Need to set property here for `lamp_ptr`. TODO: would prefer to do this in _init. */
|
||||
|
||||
/* Spot angle gizmo. */
|
||||
{
|
||||
wmGizmo *gz = ls_gzgroup->spot_angle;
|
||||
float dir[3];
|
||||
negate_v3_v3(dir, ob->object_to_world[2]);
|
||||
@ -255,6 +196,30 @@ 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_func(gz,
|
||||
"size",
|
||||
&lamp_ptr,
|
||||
"spot_blend",
|
||||
-1,
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.transform_get_fn = gizmo_spot_blend_prop_size_get,
|
||||
.transform_set_fn = gizmo_spot_blend_prop_size_set,
|
||||
});
|
||||
}
|
||||
|
||||
/* Spot radius gizmo. */
|
||||
{
|
||||
wmGizmo *gz = ls_gzgroup->spot_radius;
|
||||
WM_gizmo_target_property_def_rna_func(gz,
|
||||
"size",
|
||||
&lamp_ptr,
|
||||
"shadow_soft_size",
|
||||
-1,
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.transform_get_fn = gizmo_light_radius_prop_size_get,
|
||||
.transform_set_fn = gizmo_light_radius_prop_size_set,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,7 +284,7 @@ static bool WIDGETGROUP_light_point_poll(const bContext *C, wmGizmoGroupType *UN
|
||||
return false;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_light_point_setup(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
static void WIDGETGROUP_light_point_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
||||
{
|
||||
wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__);
|
||||
wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL);
|
||||
@ -335,14 +300,7 @@ static void WIDGETGROUP_light_point_setup(const bContext *C, wmGizmoGroup *gzgro
|
||||
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
|
||||
UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);
|
||||
|
||||
WM_gizmo_target_property_def_func(gz,
|
||||
"matrix",
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.value_get_fn = gizmo_light_radius_prop_matrix_get,
|
||||
.value_set_fn = gizmo_light_radius_prop_matrix_set,
|
||||
.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 +320,29 @@ 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);
|
||||
|
||||
/* Need to set property here for `lamp_ptr`. TODO: would prefer to do this in _init. */
|
||||
WM_gizmo_target_property_def_rna_func(wwrapper->gizmo,
|
||||
"size",
|
||||
&lamp_ptr,
|
||||
"shadow_soft_size",
|
||||
-1,
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.transform_get_fn = gizmo_light_radius_prop_size_get,
|
||||
.transform_set_fn = gizmo_light_radius_prop_size_set,
|
||||
});
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_light_point(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
gzgt->name = "Point Light Widgets";
|
||||
@ -372,6 +353,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;
|
||||
}
|
||||
|
||||
@ -381,40 +363,6 @@ void VIEW3D_GGT_light_point(wmGizmoGroupType *gzgt)
|
||||
/** \name Area Light Gizmos
|
||||
* \{ */
|
||||
|
||||
/* scale callbacks */
|
||||
static void gizmo_area_light_prop_matrix_get(const wmGizmo *UNUSED(gz),
|
||||
wmGizmoProperty *gz_prop,
|
||||
void *value_p)
|
||||
{
|
||||
BLI_assert(gz_prop->type->array_length == 16);
|
||||
float(*matrix)[4] = value_p;
|
||||
const Light *la = gz_prop->custom_func.user_data;
|
||||
|
||||
matrix[0][0] = la->area_size;
|
||||
matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey :
|
||||
la->area_size;
|
||||
}
|
||||
|
||||
static void gizmo_area_light_prop_matrix_set(const wmGizmo *UNUSED(gz),
|
||||
wmGizmoProperty *gz_prop,
|
||||
const void *value_p)
|
||||
{
|
||||
const float(*matrix)[4] = value_p;
|
||||
BLI_assert(gz_prop->type->array_length == 16);
|
||||
Light *la = gz_prop->custom_func.user_data;
|
||||
|
||||
if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
|
||||
la->area_size = len_v3(matrix[0]);
|
||||
la->area_sizey = len_v3(matrix[1]);
|
||||
}
|
||||
else {
|
||||
la->area_size = len_v3(matrix[0]);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&la->id, ID_RECALC_COPY_ON_WRITE);
|
||||
WM_main_add_notifier(NC_LAMP | ND_LIGHTING_DRAW, la);
|
||||
}
|
||||
|
||||
static bool WIDGETGROUP_light_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
@ -452,6 +400,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)
|
||||
@ -469,18 +419,15 @@ static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgr
|
||||
int flag = ED_GIZMO_CAGE_XFORM_FLAG_SCALE;
|
||||
if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
|
||||
flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM;
|
||||
flag |= ED_GIZMO_CAGE_XFORM_FLAG_SHAPE_UNIFORM;
|
||||
}
|
||||
RNA_enum_set(gz->ptr, "transform", flag);
|
||||
|
||||
/* need to set property here for undo. TODO: would prefer to do this in _init. */
|
||||
WM_gizmo_target_property_def_func(gz,
|
||||
"matrix",
|
||||
&(const struct wmGizmoPropertyFnParams){
|
||||
.value_get_fn = gizmo_area_light_prop_matrix_get,
|
||||
.value_set_fn = gizmo_area_light_prop_matrix_set,
|
||||
.range_get_fn = NULL,
|
||||
.user_data = la,
|
||||
});
|
||||
PointerRNA lamp_ptr;
|
||||
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
|
||||
|
||||
/* Need to set property here for `lamp_ptr`. TODO: would prefer to do this in _init. */
|
||||
WM_gizmo_target_property_def_rna(gz, "size", &lamp_ptr, "size_xy", -1);
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_light_area(wmGizmoGroupType *gzgt)
|
||||
|
@ -88,6 +88,20 @@ static void rna_Light_use_nodes_update(bContext *C, PointerRNA *ptr)
|
||||
rna_Light_update(CTX_data_main(C), CTX_data_scene(C), ptr);
|
||||
}
|
||||
|
||||
static void rna_area_light_size_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
Light *la = (Light *)ptr->data;
|
||||
values[0] = la->area_size;
|
||||
values[1] = la->area_sizey;
|
||||
}
|
||||
|
||||
static void rna_area_light_size_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
Light *la = (Light *)ptr->data;
|
||||
la->area_size = values[0];
|
||||
la->area_sizey = values[1];
|
||||
}
|
||||
|
||||
#else
|
||||
/* Don't define icons here, so they don't show up in the Light UI (properties Editor) - DingTo */
|
||||
const EnumPropertyItem rna_enum_light_type_items[] = {
|
||||
@ -452,6 +466,7 @@ static void rna_def_area_light(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Shape", "Shape of the area Light");
|
||||
RNA_def_property_update(prop, 0, "rna_Light_draw_update");
|
||||
|
||||
/* TODO: deprecate `size` and `size_y`, rename `size_xy` to `size`. */
|
||||
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "area_size");
|
||||
RNA_def_property_range(prop, 0.0f, FLT_MAX);
|
||||
@ -470,6 +485,14 @@ static void rna_def_area_light(BlenderRNA *brna)
|
||||
"Size of the area of the area light in the Y direction for rectangle shapes");
|
||||
RNA_def_property_update(prop, 0, "rna_Light_draw_update");
|
||||
|
||||
prop = RNA_def_property(srna, "size_xy", PROP_FLOAT, PROP_DISTANCE);
|
||||
RNA_def_property_array(prop, 2);
|
||||
RNA_def_property_range(prop, 0.0f, FLT_MAX);
|
||||
RNA_def_property_ui_range(prop, 0, 100, 0.1, 3);
|
||||
RNA_def_property_float_funcs(prop, "rna_area_light_size_get", "rna_area_light_size_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Area Size", "Size of the area light");
|
||||
RNA_def_property_update(prop, 0, "rna_Light_draw_update");
|
||||
|
||||
prop = RNA_def_property(srna, "spread", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "area_spread");
|
||||
RNA_def_property_range(prop, DEG2RADF(0.0f), DEG2RADF(180.0f));
|
||||
|
@ -266,9 +266,16 @@ void WM_gizmo_target_property_def_func(struct wmGizmo *gz,
|
||||
void WM_gizmo_target_property_clear_rna_ptr(struct wmGizmo *gz,
|
||||
const struct wmGizmoPropertyType *gz_prop_type);
|
||||
void WM_gizmo_target_property_clear_rna(struct wmGizmo *gz, const char *idname);
|
||||
void WM_gizmo_target_property_def_rna_func(struct wmGizmo *gz,
|
||||
const char *idname,
|
||||
struct PointerRNA *ptr,
|
||||
const char *propname,
|
||||
int index,
|
||||
const wmGizmoPropertyFnParams *params);
|
||||
|
||||
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 +515,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;
|
||||
|
||||
@ -298,13 +304,8 @@ typedef struct wmGizmoProperty {
|
||||
int index;
|
||||
|
||||
/* Optional functions for converting to/from RNA. */
|
||||
struct {
|
||||
wmGizmoPropertyFnGet value_get_fn;
|
||||
wmGizmoPropertyFnSet value_set_fn;
|
||||
wmGizmoPropertyFnRangeGet range_get_fn;
|
||||
wmGizmoPropertyFnFree free_fn;
|
||||
void *user_data;
|
||||
} custom_func;
|
||||
wmGizmoPropertyFnParams custom_func;
|
||||
|
||||
} wmGizmoProperty;
|
||||
|
||||
typedef struct wmGizmoPropertyType {
|
||||
|
@ -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);
|
||||
Weizhen Huang
commented
I find this 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.
|
||||
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)
|
||||
|
@ -103,12 +103,7 @@ void WM_gizmo_target_property_def_func_ptr(wmGizmo *gz,
|
||||
BLI_assert(gz->op_data == NULL);
|
||||
|
||||
gz_prop->type = gz_prop_type;
|
||||
|
||||
gz_prop->custom_func.value_get_fn = params->value_get_fn;
|
||||
gz_prop->custom_func.value_set_fn = params->value_set_fn;
|
||||
gz_prop->custom_func.range_get_fn = params->range_get_fn;
|
||||
gz_prop->custom_func.free_fn = params->free_fn;
|
||||
gz_prop->custom_func.user_data = params->user_data;
|
||||
gz_prop->custom_func = *params;
|
||||
|
||||
if (gz->type->property_update) {
|
||||
gz->type->property_update(gz, gz_prop);
|
||||
@ -123,6 +118,17 @@ void WM_gizmo_target_property_def_func(wmGizmo *gz,
|
||||
WM_gizmo_target_property_def_func_ptr(gz, gz_prop_type, params);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_def_rna_func(wmGizmo *gz,
|
||||
const char *idname,
|
||||
PointerRNA *ptr,
|
||||
const char *propname,
|
||||
int index,
|
||||
const wmGizmoPropertyFnParams *params)
|
||||
{
|
||||
WM_gizmo_target_property_def_rna(gz, idname, ptr, propname, index);
|
||||
WM_gizmo_target_property_def_func(gz, idname, params);
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_clear_rna_ptr(wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type)
|
||||
{
|
||||
wmGizmoProperty *gz_prop = WM_gizmo_target_property_at_index(gz, gz_prop_type->index_in_type);
|
||||
@ -161,6 +167,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) ||
|
||||
@ -169,23 +197,32 @@ bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop)
|
||||
|
||||
float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_prop)
|
||||
{
|
||||
if (gz_prop->custom_func.value_get_fn) {
|
||||
float value = 0.0f;
|
||||
|
||||
if (gz_prop->custom_func.value_get_fn) {
|
||||
BLI_assert(gz_prop->type->array_length == 1);
|
||||
gz_prop->custom_func.value_get_fn(gz, gz_prop, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
if (gz_prop->index == -1) {
|
||||
return RNA_property_float_get(&gz_prop->ptr, gz_prop->prop);
|
||||
value = RNA_property_float_get(&gz_prop->ptr, gz_prop->prop);
|
||||
}
|
||||
return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
|
||||
else {
|
||||
value = RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
|
||||
}
|
||||
|
||||
if (gz_prop->custom_func.transform_get_fn) {
|
||||
gz_prop->custom_func.transform_get_fn(gz_prop, &value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_float_set(bContext *C,
|
||||
const wmGizmo *gz,
|
||||
wmGizmoProperty *gz_prop,
|
||||
const float value)
|
||||
float value)
|
||||
{
|
||||
if (gz_prop->custom_func.value_set_fn) {
|
||||
BLI_assert(gz_prop->type->array_length == 1);
|
||||
@ -193,7 +230,11 @@ void WM_gizmo_target_property_float_set(bContext *C,
|
||||
return;
|
||||
}
|
||||
|
||||
/* reset property */
|
||||
if (gz_prop->custom_func.transform_set_fn) {
|
||||
gz_prop->custom_func.transform_set_fn(gz_prop, &value);
|
||||
}
|
||||
|
||||
/* Set property. */
|
||||
if (gz_prop->index == -1) {
|
||||
RNA_property_float_set(&gz_prop->ptr, gz_prop->prop, value);
|
||||
}
|
||||
@ -212,6 +253,10 @@ void WM_gizmo_target_property_float_get_array(const wmGizmo *gz,
|
||||
return;
|
||||
}
|
||||
RNA_property_float_get_array(&gz_prop->ptr, gz_prop->prop, value);
|
||||
|
||||
if (gz_prop->custom_func.transform_get_fn) {
|
||||
gz_prop->custom_func.transform_get_fn(gz_prop, value);
|
||||
}
|
||||
}
|
||||
|
||||
void WM_gizmo_target_property_float_set_array(bContext *C,
|
||||
@ -223,7 +268,21 @@ void WM_gizmo_target_property_float_set_array(bContext *C,
|
||||
gz_prop->custom_func.value_set_fn(gz, gz_prop, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gz_prop->custom_func.transform_set_fn) {
|
||||
/* Copy array. */
|
||||
int length = WM_gizmo_target_property_array_length(gz, gz_prop);
|
||||
float *transformed = MEM_malloc_arrayN(length, sizeof(float), __func__);
|
||||
memcpy(transformed, value, sizeof(float) * length);
|
||||
|
||||
gz_prop->custom_func.transform_set_fn(gz_prop, transformed);
|
||||
RNA_property_float_set_array(&gz_prop->ptr, gz_prop->prop, transformed);
|
||||
|
||||
MEM_freeN(transformed);
|
||||
}
|
||||
else {
|
||||
RNA_property_float_set_array(&gz_prop->ptr, gz_prop->prop, value);
|
||||
}
|
||||
|
||||
RNA_property_update(C, &gz_prop->ptr, gz_prop->prop);
|
||||
}
|
||||
|
@ -63,6 +63,15 @@ typedef void (*wmGizmoPropertyFnSet)(const struct wmGizmo *,
|
||||
struct wmGizmoProperty *,
|
||||
/* typically 'const float *' */
|
||||
const void *value);
|
||||
|
||||
/* Used for transforming the RNA properties. */
|
||||
typedef void (*wmGizmoPropertyFnTransformGet)(struct wmGizmoProperty *,
|
||||
/* typically 'float *' */
|
||||
void *value);
|
||||
typedef void (*wmGizmoPropertyFnTransformSet)(struct wmGizmoProperty *,
|
||||
/* typically 'float *' */
|
||||
void *value);
|
||||
|
||||
typedef void (*wmGizmoPropertyFnRangeGet)(const struct wmGizmo *,
|
||||
struct wmGizmoProperty *,
|
||||
/* typically 'float[2]' */
|
||||
@ -72,6 +81,8 @@ typedef void (*wmGizmoPropertyFnFree)(const struct wmGizmo *, struct wmGizmoProp
|
||||
typedef struct wmGizmoPropertyFnParams {
|
||||
wmGizmoPropertyFnGet value_get_fn;
|
||||
wmGizmoPropertyFnSet value_set_fn;
|
||||
wmGizmoPropertyFnTransformGet transform_get_fn;
|
||||
wmGizmoPropertyFnTransformSet transform_set_fn;
|
||||
Weizhen Huang
commented
I find it a bit confusing that there are two groups of getter/setters. The new I find it a bit confusing that there are two groups of getter/setters. The new `transform_set_fn` could modify the value, and I don't want to drop the `const` specifier for `value_set_fn`. Or could there be better function names?
|
||||
wmGizmoPropertyFnRangeGet range_get_fn;
|
||||
wmGizmoPropertyFnFree free_fn;
|
||||
void *user_data;
|
||||
|
Loading…
Reference in New Issue
Block a user
Usually
description
is used here, but looks rather lengthy if there is already description for RNA properties, so I usename
instead.