Manipulator: target property definitions

Changes from custom-manipulator branch.

- use property type definitions.
- add property free callback.
- move properties into the wmManipulator struct (over alloc).
- use array length from property types instead of arg passing.
This commit is contained in:
Campbell Barton
2017-06-22 18:29:45 +10:00
parent 87adeb8dd9
commit f1824507e2
14 changed files with 276 additions and 132 deletions

View File

@@ -369,7 +369,7 @@ static void manipulator_arrow_invoke(
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
/* Some manipulators don't use properties. */
if (mpr_prop && WM_manipulator_target_property_is_valid(mpr_prop)) {
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
inter->init_value = WM_manipulator_target_property_value_get(mpr, mpr_prop);
}
@@ -424,8 +424,8 @@ void ED_manipulator_arrow3d_set_ui_range(wmManipulator *mpr, const float min, co
ArrowManipulator3D *arrow = (ArrowManipulator3D *)mpr;
BLI_assert(min < max);
BLI_assert(!(WM_manipulator_target_property_find(mpr, "offset") && "Make sure this function "
"is called before WM_manipulator_target_property_def_rna"));
BLI_assert(!(WM_manipulator_target_property_is_valid(WM_manipulator_target_property_find(mpr, "offset")) &&
"Make sure this function is called before WM_manipulator_target_property_def_rna"));
arrow->data.range = max - min;
arrow->data.min = min;
@@ -440,8 +440,8 @@ void ED_manipulator_arrow3d_set_ui_range(wmManipulator *mpr, const float min, co
void ED_manipulator_arrow3d_set_range_fac(wmManipulator *mpr, const float range_fac)
{
ArrowManipulator3D *arrow = (ArrowManipulator3D *)mpr;
BLI_assert(!(WM_manipulator_target_property_find(mpr, "offset") && "Make sure this function "
"is called before WM_manipulator_target_property_def_rna"));
BLI_assert(!(WM_manipulator_target_property_is_valid(WM_manipulator_target_property_find(mpr, "offset")) &&
"Make sure this function is called before WM_manipulator_target_property_def_rna"));
arrow->data.range_fac = range_fac;
}
@@ -484,6 +484,8 @@ static void MANIPULATOR_WT_arrow_3d(wmManipulatorType *wt)
RNA_def_float(wt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX);
RNA_def_float_vector(wt->srna, "aspect", 2, NULL, 0, FLT_MAX, "Aspect", "Cone/box style only", 0.0f, FLT_MAX);
WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 1);
}
void ED_manipulatortypes_arrow_3d(void)

View File

@@ -228,7 +228,7 @@ static void manipulator_rect_transform_draw(const bContext *UNUSED(C), wmManipul
aspy = w / h;
}
w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / scale[0]);
h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH /
h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH /
((transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) ? scale[0] : scale[1]));
/* corner manipulators */
@@ -303,7 +303,7 @@ static int manipulator_rect_transform_test_select(
aspy = w / h;
}
w = min_ff(aspx * w / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH / scale[0]);
h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH /
h = min_ff(aspy * h / MANIPULATOR_RESIZER_WIDTH, MANIPULATOR_RESIZER_WIDTH /
((transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) ? scale[0] : scale[1]));
@@ -383,14 +383,14 @@ static bool manipulator_rect_transform_get_prop_value(
return false;
}
else {
if (STREQ(mpr_prop->idname, "offset")) {
if (STREQ(mpr_prop->type->idname, "offset")) {
if (RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop) != 2) {
fprintf(stderr, "Rect Transform manipulator offset not only be bound to array float property");
return false;
}
RNA_property_float_get_array(&mpr_prop->ptr, mpr_prop->prop, value);
}
else if (STREQ(mpr_prop->idname, "scale")) {
else if (STREQ(mpr_prop->type->idname, "scale")) {
const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) {
*value = RNA_property_float_get(&mpr_prop->ptr, mpr_prop->prop);
@@ -533,10 +533,10 @@ static void manipulator_rect_transform_modal(
static void manipulator_rect_transform_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
{
if (STREQ(mpr_prop->idname, "offset")) {
if (STREQ(mpr_prop->type->idname, "offset")) {
manipulator_rect_transform_get_prop_value(mpr, mpr_prop, mpr->matrix_offset[3]);
}
else if (STREQ(mpr_prop->idname, "scale")) {
else if (STREQ(mpr_prop->type->idname, "scale")) {
float scale[2];
RNA_float_get_array(mpr->ptr, "scale", scale);
manipulator_rect_transform_get_prop_value(mpr, mpr_prop, scale);
@@ -610,6 +610,10 @@ static void MANIPULATOR_WT_cage_2d(wmManipulatorType *wt)
RNA_def_float_vector(wt->srna, "scale", 2, scale_default, 0, FLT_MAX, "Scale", "", 0.0f, FLT_MAX);
RNA_def_float_vector(wt->srna, "dimensions", 2, NULL, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX);
RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", "");
WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 1);
WM_manipulatortype_target_property_def(wt, "scale", PROP_FLOAT, 2);
WM_manipulatortype_target_property_def(wt, "scale_uniform", PROP_FLOAT, 1);
}
void ED_manipulatortypes_cage_2d(void)

View File

@@ -293,7 +293,7 @@ static void dial_draw_intern(
DialInteraction *inter = mpr->interaction_data;
/* XXX, View3D rotation manipulator doesn't call modal. */
if (mpr->target_properties.first == NULL) {
if (!WM_manipulator_target_property_is_valid_any(mpr)) {
wmWindow *win = CTX_wm_window(C);
manipulator_dial_modal((bContext *)C, mpr, win->eventstate, 0);
}
@@ -397,7 +397,7 @@ static void manipulator_dial_modal(bContext *C, wmManipulator *mpr, const wmEven
/* set the property for the operator and call its modal function */
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (mpr_prop && WM_manipulator_target_property_is_valid(mpr_prop)) {
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
WM_manipulator_target_property_value_set(C, mpr, mpr_prop, inter->init_prop_angle + angle_delta);
}
}
@@ -420,7 +420,7 @@ static void manipulator_dial_invoke(
inter->init_mval[1] = event->mval[1];
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (mpr_prop && WM_manipulator_target_property_is_valid(mpr_prop)) {
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
inter->init_prop_angle = WM_manipulator_target_property_value_get(mpr, mpr_prop);
}
@@ -457,6 +457,8 @@ static void MANIPULATOR_WT_dial_3d(wmManipulatorType *wt)
{0, NULL, 0, NULL, NULL}
};
RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 1);
}
void ED_manipulatortypes_dial_3d(void)

View File

@@ -197,8 +197,8 @@ static void manipulator_grab_modal(bContext *C, wmManipulator *mpr, const wmEven
/* set the property for the operator and call its modal function */
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (mpr_prop && WM_manipulator_target_property_is_valid(mpr_prop)) {
WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, inter->output.co_final, 3);
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, inter->output.co_final);
}
}
@@ -211,8 +211,8 @@ static void manipulator_grab_invoke(
inter->init_mval[1] = event->mval[1];
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (mpr_prop && WM_manipulator_target_property_is_valid(mpr_prop)) {
WM_manipulator_target_property_value_get_array(mpr, mpr_prop, inter->init_prop_co, 3);
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
WM_manipulator_target_property_value_get_array(mpr, mpr_prop, inter->init_prop_co);
}
mpr->interaction_data = inter;
@@ -250,6 +250,8 @@ static void MANIPULATOR_WT_grab_3d(wmManipulatorType *wt)
RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_MANIPULATOR_GRAB_STYLE_RING, "Draw Style", "");
RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 3);
}
void ED_manipulatortypes_grab_3d(void)

View File

@@ -456,14 +456,14 @@ static void manipulator_mesh_bisect_update_from_op(ManipulatorGroup *man)
/* depth callbacks */
static void manipulator_bisect_prop_depth_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_co[3], plane_no[3];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, plane_co);
@@ -473,14 +473,14 @@ static void manipulator_bisect_prop_depth_get(
}
static void manipulator_bisect_prop_depth_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_co[3], plane[4];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, plane_co);
@@ -499,24 +499,28 @@ static void manipulator_bisect_prop_depth_set(
/* translate callbacks */
static void manipulator_bisect_prop_translate_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 3);
BLI_assert(mpr_prop->type->array_length == 3);
UNUSED_VARS_NDEBUG(mpr_prop);
RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, value);
}
static void manipulator_bisect_prop_translate_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 3);
BLI_assert(mpr_prop->type->array_length == 3);
UNUSED_VARS_NDEBUG(mpr_prop);
RNA_property_float_set_array(op->ptr, man->data.prop_plane_co, value);
manipulator_bisect_exec(man);
@@ -524,14 +528,14 @@ static void manipulator_bisect_prop_translate_set(
/* angle callbacks */
static void manipulator_bisect_prop_angle_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no);
@@ -550,14 +554,14 @@ static void manipulator_bisect_prop_angle_get(
}
static void manipulator_bisect_prop_angle_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no);

View File

@@ -890,14 +890,14 @@ static void manipulator_mesh_spin_update_from_op(ManipulatorSpinGroup *man)
/* depth callbacks */
static void manipulator_spin_prop_depth_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_co[3], plane_no[3];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, plane_co);
@@ -907,14 +907,14 @@ static void manipulator_spin_prop_depth_get(
}
static void manipulator_spin_prop_depth_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_co[3], plane[4];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, plane_co);
@@ -933,24 +933,28 @@ static void manipulator_spin_prop_depth_set(
/* translate callbacks */
static void manipulator_spin_prop_translate_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 3);
BLI_assert(mpr_prop->type->array_length == 3);
UNUSED_VARS_NDEBUG(mpr_prop);
RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, value);
}
static void manipulator_spin_prop_translate_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 3);
BLI_assert(mpr_prop->type->array_length == 3);
UNUSED_VARS_NDEBUG(mpr_prop);
RNA_property_float_set_array(op->ptr, man->data.prop_axis_co, value);
manipulator_spin_exec(man);
@@ -958,14 +962,14 @@ static void manipulator_spin_prop_translate_set(
/* angle callbacks */
static void manipulator_spin_prop_axis_angle_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no);
@@ -984,14 +988,14 @@ static void manipulator_spin_prop_axis_angle_get(
}
static void manipulator_spin_prop_axis_angle_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
UNUSED_VARS_NDEBUG(value_len);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
float plane_no[4];
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no);
@@ -1018,22 +1022,24 @@ static void manipulator_spin_prop_axis_angle_set(
/* angle callbacks */
static void manipulator_spin_prop_angle_get(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
value[0] = RNA_property_float_get(op->ptr, man->data.prop_angle);
}
static void manipulator_spin_prop_angle_set(
const wmManipulator *mpr, wmManipulatorProperty *UNUSED(mpr_prop), void *UNUSED(user_data),
const float *value, uint value_len)
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value)
{
ManipulatorSpinGroup *man = mpr->parent_mgroup->customdata;
wmOperator *op = man->data.op;
BLI_assert(value_len == 1);
BLI_assert(mpr_prop->type->array_length == 1);
UNUSED_VARS_NDEBUG(mpr_prop);
RNA_property_float_set(op->ptr, man->data.prop_angle, value[0]);
manipulator_spin_exec(man);

View File

@@ -489,8 +489,6 @@ void WM_exit_ext(bContext *C, const bool do_python)
wm_dropbox_free();
WM_menutype_free();
WM_uilisttype_free();
wm_manipulatorgrouptype_free();
wm_manipulatortype_free();
/* all non-screen and non-space stuff editors did, like editmode */
if (C)
@@ -535,6 +533,8 @@ void WM_exit_ext(bContext *C, const bool do_python)
/* free manipulator-maps after freeing blender, so no deleted data get accessed during cleaning up of areas */
wm_manipulatormaptypes_free();
wm_manipulatorgrouptype_free();
wm_manipulatortype_free();
BLF_exit();

View File

@@ -39,9 +39,11 @@
struct ARegion;
struct GHashIterator;
struct Main;
struct PropertyRNA;
struct wmKeyConfig;
struct wmManipulator;
struct wmManipulatorProperty;
struct wmManipulatorPropertyType;
struct wmManipulatorType;
struct wmManipulatorGroup;
struct wmManipulatorGroupType;
@@ -132,16 +134,27 @@ void WM_manipulatorconfig_update(struct Main *bmain);
/* wm_maniulator_target_props.c */
struct wmManipulatorProperty *WM_manipulator_target_property_array(struct wmManipulator *mpr);
struct wmManipulatorProperty *WM_manipulator_target_property_at_index(
struct wmManipulator *mpr, int index);
struct wmManipulatorProperty *WM_manipulator_target_property_find(
struct wmManipulator *mpr, const char *idname);
void WM_manipulator_target_property_def_rna_ptr(
struct wmManipulator *mpr, const struct wmManipulatorPropertyType *mpr_prop_type,
struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
void WM_manipulator_target_property_def_rna(
struct wmManipulator *mpr, const char *idname,
struct PointerRNA *ptr, const char *propname, int index);
void WM_manipulator_target_property_def_func_ptr(
struct wmManipulator *mpr, const struct wmManipulatorPropertyType *mpr_prop_type,
const struct wmManipulatorPropertyFnParams *params);
void WM_manipulator_target_property_def_func(
struct wmManipulator *mpr, const char *idname,
const struct wmManipulatorPropertyFnParams *params);
bool WM_manipulator_target_property_is_valid_any(struct wmManipulator *mpr);
bool WM_manipulator_target_property_is_valid(
const struct wmManipulatorProperty *mpr_prop);
float WM_manipulator_target_property_value_get(
@@ -152,15 +165,22 @@ void WM_manipulator_target_property_value_set(
void WM_manipulator_target_property_value_get_array(
const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop,
float *value, const int value_len);
float *value);
void WM_manipulator_target_property_value_set_array(
struct bContext *C, const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop,
const float *value, const int value_len);
const float *value);
void WM_manipulator_target_property_range_get(
const struct wmManipulator *mpr, struct wmManipulatorProperty *mpr_prop,
float range[2]);
/* definitions */
const struct wmManipulatorPropertyType *WM_manipulatortype_target_property_find(
const struct wmManipulatorType *wt, const char *idname);
void WM_manipulatortype_target_property_def(
struct wmManipulatorType *wt, const char *idname, int type, int array_length);
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */

View File

@@ -110,15 +110,9 @@ struct wmManipulator {
PointerRNA ptr;
} op_data;
/* Properties 'wmManipulatorProperty' attached to various manipulator parameters.
* As the manipulator is interacted with, those properties get updated.
*
* Public API's should use string names,
* private API's can pass 'wmManipulatorProperty' directly.
*/
ListBase target_properties;
struct IDProperty *properties;
/* over alloc target_properties after 'wmManipulatorType.struct_size' */
};
typedef void (*wmManipulatorGroupFnInit)(
@@ -126,23 +120,38 @@ typedef void (*wmManipulatorGroupFnInit)(
/* Similar to PropertyElemRNA, but has an identifier. */
typedef struct wmManipulatorProperty {
struct wmManipulatorProperty *next, *prev;
const struct wmManipulatorPropertyType *type;
PointerRNA ptr;
PropertyRNA *prop;
int index;
/* Optional functions for converting to/from RNA */
struct {
wmManipulatorPropertyFnGet value_get_fn;
wmManipulatorPropertyFnSet value_set_fn;
wmManipulatorPropertyFnRangeGet range_get_fn;
wmManipulatorPropertyFnFree free_fn;
const struct bContext *context;
void *user_data;
} custom_func;
} wmManipulatorProperty;
typedef struct wmManipulatorPropertyType {
struct wmManipulatorPropertyType *next, *prev;
/* PropertyType, typically 'PROP_FLOAT' */
int type;
int array_length;
/* index within 'wmManipulatorType' */
int index_in_type;
/* over alloc */
char idname[0];
} wmManipulatorProperty;
} wmManipulatorPropertyType;
/**
* Simple utility wrapper for storing a single manipulator as wmManipulatorGroup.customdata (which gets freed).
@@ -233,6 +242,10 @@ typedef struct wmManipulatorType {
/* RNA integration */
ExtensionRNA ext;
ListBase target_property_defs;
int target_property_defs_len;
} wmManipulatorType;

View File

@@ -77,7 +77,8 @@ static wmManipulator *wm_manipulator_create(
BLI_assert(wt != NULL);
BLI_assert(wt->struct_size >= sizeof(wmManipulator));
wmManipulator *mpr = MEM_callocN(wt->struct_size, __func__);
wmManipulator *mpr = MEM_callocN(
wt->struct_size + (sizeof(wmManipulatorProperty) * wt->target_property_defs_len), __func__);
mpr->type = wt;
/* initialize properties, either copy or create */
@@ -197,13 +198,22 @@ void WM_manipulator_free(ListBase *manipulatorlist, wmManipulatorMap *mmap, wmMa
if (mpr->op_data.ptr.data) {
WM_operator_properties_free(&mpr->op_data.ptr);
}
BLI_freelistN(&mpr->target_properties);
if (mpr->ptr != NULL) {
WM_manipulator_properties_free(mpr->ptr);
MEM_freeN(mpr->ptr);
}
if (mpr->type->target_property_defs_len != 0) {
wmManipulatorProperty *mpr_prop_array = WM_manipulator_target_property_array(mpr);
for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
if (mpr_prop->custom_func.free_fn) {
mpr_prop->custom_func.free_fn(mpr, mpr_prop);
}
}
}
if (manipulatorlist) {
BLI_remlink(manipulatorlist, mpr);
}
@@ -461,8 +471,10 @@ void wm_manipulator_calculate_scale(wmManipulator *mpr, const bContext *C)
static void manipulator_update_prop_data(wmManipulator *mpr)
{
/* manipulator property might have been changed, so update manipulator */
if (mpr->type->property_update && !BLI_listbase_is_empty(&mpr->target_properties)) {
for (wmManipulatorProperty *mpr_prop = mpr->target_properties.first; mpr_prop; mpr_prop = mpr_prop->next) {
if (mpr->type->property_update) {
wmManipulatorProperty *mpr_prop_array = WM_manipulator_target_property_array(mpr);
for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
mpr->type->property_update(mpr, mpr_prop);
}

View File

@@ -182,4 +182,5 @@ void wm_manipulatorgrouptype_init(void)
global_manipulatorgrouptype_hash = BLI_ghash_str_new_ex("wm_manipulatorgrouptype_init gh", 128);
}
/** \} */
/** \} */

View File

@@ -53,37 +53,81 @@
/** \name Property Definition
* \{ */
wmManipulatorProperty *WM_manipulator_target_property_find(wmManipulator *mpr, const char *idname)
BLI_INLINE wmManipulatorProperty *wm_manipulator_target_property_array(wmManipulator *mpr)
{
return BLI_findstring(&mpr->target_properties, idname, offsetof(wmManipulatorProperty, idname));
return (wmManipulatorProperty *)(POINTER_OFFSET(mpr, mpr->type->struct_size));
}
static wmManipulatorProperty *wm_manipulator_target_property_def_internal(
wmManipulator *mpr, const char *idname)
wmManipulatorProperty *WM_manipulator_target_property_array(wmManipulator *mpr)
{
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, idname);
return wm_manipulator_target_property_array(mpr);
}
if (mpr_prop == NULL) {
const uint idname_size = strlen(idname) + 1;
mpr_prop = MEM_callocN(sizeof(wmManipulatorProperty) + idname_size, __func__);
memcpy(mpr_prop->idname, idname, idname_size);
BLI_addtail(&mpr->target_properties, mpr_prop);
wmManipulatorProperty *WM_manipulator_target_property_at_index(wmManipulator *mpr, int index)
{
BLI_assert(index < mpr->type->target_property_defs_len);
BLI_assert(index != -1);
wmManipulatorProperty *mpr_prop_array = wm_manipulator_target_property_array(mpr);
return &mpr_prop_array[index];
}
wmManipulatorProperty *WM_manipulator_target_property_find(wmManipulator *mpr, const char *idname)
{
int index = BLI_findstringindex(
&mpr->type->target_property_defs, idname, offsetof(wmManipulatorPropertyType, idname));
if (index != -1) {
return WM_manipulator_target_property_at_index(mpr, index);
}
else {
return NULL;
}
}
void WM_manipulator_target_property_def_rna_ptr(
wmManipulator *mpr, const wmManipulatorPropertyType *mpr_prop_type,
PointerRNA *ptr, PropertyRNA *prop, int index)
{
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type);
/* if manipulator evokes an operator we cannot use it for property manipulation */
mpr->op_data.type = NULL;
mpr_prop->type = mpr_prop_type;
mpr_prop->ptr = *ptr;
mpr_prop->prop = prop;
mpr_prop->index = index;
if (mpr->type->property_update) {
mpr->type->property_update(mpr, mpr_prop);
}
return mpr_prop;
}
void WM_manipulator_target_property_def_rna(
wmManipulator *mpr, const char *idname,
PointerRNA *ptr, const char *propname, int index)
{
wmManipulatorProperty *mpr_prop = wm_manipulator_target_property_def_internal(mpr, idname);
const wmManipulatorPropertyType *mpr_prop_type = WM_manipulatortype_target_property_find(mpr->type, idname);
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
WM_manipulator_target_property_def_rna_ptr(mpr, mpr_prop_type, ptr, prop, index);
}
void WM_manipulator_target_property_def_func_ptr(
wmManipulator *mpr, const wmManipulatorPropertyType *mpr_prop_type,
const wmManipulatorPropertyFnParams *params)
{
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type);
/* if manipulator evokes an operator we cannot use it for property manipulation */
mpr->op_data.type = NULL;
mpr_prop->ptr = *ptr;
mpr_prop->prop = RNA_struct_find_property(ptr, propname);
mpr_prop->index = index;
mpr_prop->type = mpr_prop_type;
mpr_prop->custom_func.value_get_fn = params->value_get_fn;
mpr_prop->custom_func.value_set_fn = params->value_set_fn;
mpr_prop->custom_func.range_get_fn = params->range_get_fn;
mpr_prop->custom_func.free_fn = params->free_fn;
mpr_prop->custom_func.user_data = params->user_data;
if (mpr->type->property_update) {
mpr->type->property_update(mpr, mpr_prop);
@@ -94,19 +138,8 @@ void WM_manipulator_target_property_def_func(
wmManipulator *mpr, const char *idname,
const wmManipulatorPropertyFnParams *params)
{
wmManipulatorProperty *mpr_prop = wm_manipulator_target_property_def_internal(mpr, idname);
/* if manipulator evokes an operator we cannot use it for property manipulation */
mpr->op_data.type = NULL;
mpr_prop->custom_func.value_get_fn = params->value_get_fn;
mpr_prop->custom_func.value_set_fn = params->value_set_fn;
mpr_prop->custom_func.range_get_fn = params->range_get_fn;
mpr_prop->custom_func.user_data = params->user_data;
if (mpr->type->property_update) {
mpr->type->property_update(mpr, mpr_prop);
}
const wmManipulatorPropertyType *mpr_prop_type = WM_manipulatortype_target_property_find(mpr->type, idname);
WM_manipulator_target_property_def_func_ptr(mpr, mpr_prop_type, params);
}
/** \} */
@@ -117,6 +150,18 @@ void WM_manipulator_target_property_def_func(
/** \name Property Access
* \{ */
bool WM_manipulator_target_property_is_valid_any(wmManipulator *mpr)
{
wmManipulatorProperty *mpr_prop_array = wm_manipulator_target_property_array(mpr);
for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
return true;
}
}
return false;
}
bool WM_manipulator_target_property_is_valid(const wmManipulatorProperty *mpr_prop)
{
return ((mpr_prop->prop != NULL) ||
@@ -128,7 +173,8 @@ float WM_manipulator_target_property_value_get(
{
if (mpr_prop->custom_func.value_get_fn) {
float value = 0.0f;
mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, &value, 1);
BLI_assert(mpr_prop->type->array_length == 1);
mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, &value);
return value;
}
@@ -145,7 +191,8 @@ void WM_manipulator_target_property_value_set(
wmManipulatorProperty *mpr_prop, const float value)
{
if (mpr_prop->custom_func.value_set_fn) {
mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, &value, 1);
BLI_assert(mpr_prop->type->array_length == 1);
mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, &value);
return;
}
@@ -161,27 +208,23 @@ void WM_manipulator_target_property_value_set(
void WM_manipulator_target_property_value_get_array(
const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
float *value, const int value_len)
float *value)
{
if (mpr_prop->custom_func.value_get_fn) {
mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, value, value_len);
mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, value);
return;
}
BLI_assert(RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop) == value_len);
return RNA_property_float_get_array(&mpr_prop->ptr, mpr_prop->prop, value);
}
void WM_manipulator_target_property_value_set_array(
bContext *C, const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
const float *value, const int value_len)
const float *value)
{
if (mpr_prop->custom_func.value_set_fn) {
mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, value, value_len);
mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, value);
return;
}
BLI_assert(RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop) == value_len);
RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, value);
RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop);
@@ -192,7 +235,7 @@ void WM_manipulator_target_property_range_get(
float range[2])
{
if (mpr_prop->custom_func.range_get_fn) {
mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, mpr_prop->custom_func.user_data, range);
mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, range);
return;
}
@@ -201,3 +244,34 @@ void WM_manipulator_target_property_range_get(
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Property Define
* \{ */
const wmManipulatorPropertyType *WM_manipulatortype_target_property_find(
const wmManipulatorType *wt, const char *idname)
{
return BLI_findstring(&wt->target_property_defs, idname, offsetof(wmManipulatorPropertyType, idname));
}
void WM_manipulatortype_target_property_def(
wmManipulatorType *wt, const char *idname, int type, int array_length)
{
wmManipulatorPropertyType *mpt;
BLI_assert(WM_manipulatortype_target_property_find(wt, idname) == NULL);
const uint idname_size = strlen(idname) + 1;
mpt = MEM_callocN(sizeof(wmManipulatorPropertyType) + idname_size, __func__);
memcpy(mpt->idname, idname, idname_size);
mpt->type = type;
mpt->array_length = array_length;
mpt->index_in_type = wt->target_property_defs_len;
wt->target_property_defs_len += 1;
BLI_addtail(&wt->target_property_defs, mpt);
}
/** \} */

View File

@@ -119,6 +119,7 @@ void WM_manipulatortype_append_ptr(void (*wtfunc)(struct wmManipulatorType *, vo
*/
static void manipulatortype_free(wmManipulatorType *wt)
{
BLI_freelistN(&wt->target_property_defs);
MEM_freeN(wt);
}
@@ -162,4 +163,4 @@ void wm_manipulatortype_init(void)
global_manipulatortype_hash = BLI_ghash_str_new_ex("wm_manipulatortype_init gh", 128);
}
/** \} */
/** \} */

View File

@@ -60,19 +60,22 @@ typedef void (*wmManipulatorFnSelect)(struct bContext *, struct wmManipulator
/* wmManipulatorProperty */
typedef void (*wmManipulatorPropertyFnGet)(
const struct wmManipulator *, struct wmManipulatorProperty *, void *user_data,
float *value, uint value_len);
const struct wmManipulator *, struct wmManipulatorProperty *,
float *value);
typedef void (*wmManipulatorPropertyFnSet)(
const struct wmManipulator *, struct wmManipulatorProperty *, void *user_data,
const float *value, uint value_len);
const struct wmManipulator *, struct wmManipulatorProperty *,
const float *value);
typedef void (*wmManipulatorPropertyFnRangeGet)(
const struct wmManipulator *, struct wmManipulatorProperty *, void *user_data,
const struct wmManipulator *, struct wmManipulatorProperty *,
float range[2]);
typedef void (*wmManipulatorPropertyFnFree)(
const struct wmManipulator *, struct wmManipulatorProperty *);
typedef struct wmManipulatorPropertyFnParams {
wmManipulatorPropertyFnGet value_get_fn;
wmManipulatorPropertyFnSet value_set_fn;
wmManipulatorPropertyFnRangeGet range_get_fn;
wmManipulatorPropertyFnFree free_fn;
void *user_data;
} wmManipulatorPropertyFnParams;