WM: add wmManipulatorType, from wmManipulator

Having the type in mixed in with each instance
made it hard to expose types to RNA/Python.
This commit is contained in:
2017-06-08 05:27:14 +10:00
parent 8ff1bce40f
commit 575db256db
16 changed files with 412 additions and 179 deletions

View File

@@ -125,6 +125,22 @@ void ED_spacetypes_init(void)
ED_operatortypes_view2d();
ED_operatortypes_ui();
/* manipulator types */
/* FIXME */
extern void ED_manipulatortypes_dial(void);
extern void ED_manipulatortypes_arrow_2d(void);
extern void ED_manipulatortypes_arrow_3d(void);
extern void ED_manipulatortypes_facemap(void);
extern void ED_manipulatortypes_primitive(void);
extern void ED_manipulatortypes_cage(void);
ED_manipulatortypes_dial();
ED_manipulatortypes_arrow_2d();
ED_manipulatortypes_arrow_3d();
ED_manipulatortypes_primitive();
ED_manipulatortypes_cage();
/* register types for operators and manipulators */
spacetypes = BKE_spacetypes_list();
for (type = spacetypes->first; type; type = type->next) {

View File

@@ -1149,7 +1149,7 @@ static void WIDGETGROUP_manipulator_init(const bContext *UNUSED(C), wmManipulato
manipulator_get_axis_constraint(axis_idx, constraint_axis);
/* custom handler! */
WM_manipulator_set_fn_handler(axis, manipulator_handler);
WM_manipulator_set_fn_custom_handler(axis, manipulator_handler);
switch(axis_idx) {
case MAN_AXIS_TRANS_X:

View File

@@ -165,6 +165,7 @@ void WM_init(bContext *C, int argc, const char **argv)
wm_operatortype_init();
WM_menutype_init();
WM_uilisttype_init();
wm_manipulatortype_init();
BKE_undo_callback_wm_kill_jobs_set(wm_undo_kill_callback);
@@ -487,6 +488,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
wm_dropbox_free();
WM_menutype_free();
WM_uilisttype_free();
wm_manipulatortype_free();
/* all non-screen and non-space stuff editors did, like editmode */
if (C)

View File

@@ -37,9 +37,11 @@
#define __WM_MANIPULATOR_API_H__
struct ARegion;
struct GHashIterator;
struct Main;
struct wmKeyConfig;
struct wmManipulator;
struct wmManipulatorType;
struct wmManipulatorGroup;
struct wmManipulatorGroupType;
struct wmManipulatorMap;
@@ -52,6 +54,7 @@ struct wmManipulatorMapType_Params;
/* wmManipulator */
struct wmManipulator *WM_manipulator_new(
const struct wmManipulatorType *mpt,
struct wmManipulatorGroup *mgroup, const char *name);
void WM_manipulator_delete(
ListBase *manipulatorlist, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator,
@@ -62,16 +65,7 @@ void WM_manipulator_set_property(struct wmManipulator *, int slot, struct Pointe
struct PointerRNA *WM_manipulator_set_operator(struct wmManipulator *, const char *opname);
/* callbacks */
void WM_manipulator_set_fn_draw(struct wmManipulator *manipulator, wmManipulatorFnDraw fn);
void WM_manipulator_set_fn_draw_select(struct wmManipulator *manipulator, wmManipulatorFnDrawSelect fn);
void WM_manipulator_set_fn_intersect(struct wmManipulator *manipulator, wmManipulatorFnIntersect fn);
void WM_manipulator_set_fn_handler(struct wmManipulator *manipulator, wmManipulatorFnHandler fn);
void WM_manipulator_set_fn_prop_data_update(struct wmManipulator *mpr, wmManipulatorFnPropDataUpdate fn);
void WM_manipulator_set_fn_final_position_get(struct wmManipulator *mpr, wmManipulatorFnFinalPositionGet fn);
void WM_manipulator_set_fn_invoke(struct wmManipulator *mpr, wmManipulatorFnInvoke fn);
void WM_manipulator_set_fn_exit(struct wmManipulator *mpr, wmManipulatorFnExit fn);
void WM_manipulator_set_fn_cursor_get(struct wmManipulator *mpr, wmManipulatorFnCursorGet fn);
void WM_manipulator_set_fn_select(struct wmManipulator *manipulator, wmManipulatorFnSelect fn);
void WM_manipulator_set_fn_custom_handler(struct wmManipulator *manipulator, wmManipulatorFnHandler fn);
void WM_manipulator_set_origin(struct wmManipulator *manipulator, const float origin[3]);
void WM_manipulator_set_offset(struct wmManipulator *manipulator, const float offset[3]);
@@ -84,6 +78,15 @@ void WM_manipulator_set_color(struct wmManipulator *manipulator, const float col
void WM_manipulator_get_color_highlight(const struct wmManipulator *manipulator, float col_hi[4]);
void WM_manipulator_set_color_highlight(struct wmManipulator *manipulator, const float col[4]);
/* manipulator_library_presets.c */
void WM_manipulator_draw_preset_box(const struct wmManipulator *manipulator, float mat[4][4], int select_id);
/* wm_manipulator.c */
const struct wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet);
void WM_manipulatortype_append(void (*mnpfunc)(struct wmManipulatorType *));
void WM_manipulatortype_append_ptr(void (*mnpfunc)(struct wmManipulatorType *, void *), void *userdata);
void WM_manipulatortype_iter(struct GHashIterator *ghi);
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */

View File

@@ -124,5 +124,12 @@ struct wmManipulator *MANIPULATOR_primitive_new(struct wmManipulatorGroup *mgrou
void MANIPULATOR_primitive_set_direction(struct wmManipulator *manipulator, const float direction[3]);
void MANIPULATOR_primitive_set_up_vector(struct wmManipulator *manipulator, const float direction[3]);
extern void ED_manipulatortypes_dial(void);
extern void ED_manipulatortypes_arrow_2d(void);
extern void ED_manipulatortypes_arrow_3d(void);
extern void ED_manipulatortypes_facemap(void);
extern void ED_manipulatortypes_primitive(void);
extern void ED_manipulatortypes_cage(void);
#endif /* __WM_MANIPULATOR_LIBRARY_H__ */

View File

@@ -64,6 +64,51 @@ enum {
WM_MANIPULATOR_HIDDEN = (1 << 3),
};
typedef struct wmManipulatorType {
struct wmManipulatorGroupType *next, *prev;
const char *idname; /* MAX_NAME */
uint size;
/* could become wmManipulatorType */
/* draw manipulator */
wmManipulatorFnDraw draw;
/* determines 3d intersection by rendering the manipulator in a selection routine. */
wmManipulatorFnDrawSelect draw_select;
/* determine if the mouse intersects with the manipulator. The calculation should be done in the callback itself */
wmManipulatorFnIntersect intersect;
/* handler used by the manipulator. Usually handles interaction tied to a manipulator type */
wmManipulatorFnHandler handler;
/* manipulator-specific handler to update manipulator attributes based on the property value */
wmManipulatorFnPropDataUpdate prop_data_update;
/* returns the final position which may be different from the origin, depending on the manipulator.
* used in calculations of scale */
wmManipulatorFnFinalPositionGet position_get;
/* activate a manipulator state when the user clicks on it */
wmManipulatorFnInvoke invoke;
/* called when manipulator tweaking is done - used to free data and reset property when cancelling */
wmManipulatorFnExit exit;
wmManipulatorFnCursorGet cursor_get;
/* called when manipulator selection state changes */
wmManipulatorFnSelect select;
/* maximum number of properties attached to the manipulator */
int prop_len_max;
/* RNA integration */
ExtensionRNA ext;
} wmManipulatorType;
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */

View File

@@ -55,6 +55,7 @@
#include "WM_types.h"
/* own includes */
#include "WM_manipulator_api.h"
#include "WM_manipulator_types.h"
#include "wm_manipulator_wmapi.h"
#include "WM_manipulator_library.h"
@@ -191,21 +192,14 @@ static int manipulator_arrow2d_intersect(
struct wmManipulator *MANIPULATOR_arrow2d_new(wmManipulatorGroup *mgroup, const char *name)
{
ArrowManipulator2D *arrow = MEM_callocN(sizeof(ArrowManipulator2D), __func__);
const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_arrow_2d", false);
ArrowManipulator2D *arrow = (ArrowManipulator2D *)WM_manipulator_new(mpt, mgroup, name);
arrow->manipulator.type.draw = manipulator_arrow2d_draw;
arrow->manipulator.type.invoke = manipulator_arrow2d_invoke;
// arrow->manipulator.type.bind_to_prop = manipulator_arrow2d_bind_to_prop;
// arrow->manipulator.type.handler = manipulator_arrow2d_handler;
arrow->manipulator.type.intersect = manipulator_arrow2d_intersect;
// arrow->manipulator.type.exit = manipulator_arrow2d_exit;
arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
arrow->line_len = 1.0f;
wm_manipulator_register(mgroup, &arrow->manipulator, name);
return (struct wmManipulator *)arrow;
return &arrow->manipulator;
}
void MANIPULATOR_arrow2d_set_angle(struct wmManipulator *manipulator, const float angle)
@@ -220,6 +214,24 @@ void MANIPULATOR_arrow2d_set_line_len(struct wmManipulator *manipulator, const f
arrow->line_len = len;
}
static void MANIPULATOR_WT_arrow_2d(wmManipulatorType *wt)
{
/* identifiers */
wt->idname = "MANIPULATOR_WT_arrow_2d";
/* api callbacks */
wt->draw = manipulator_arrow2d_draw;
wt->invoke = manipulator_arrow2d_invoke;
wt->intersect = manipulator_arrow2d_intersect;
wt->size = sizeof(ArrowManipulator2D);
}
void ED_manipulatortypes_arrow_2d(void)
{
WM_manipulatortype_append(MANIPULATOR_WT_arrow_2d);
}
/** \} */ /* Arrow Manipulator API */

View File

@@ -74,7 +74,7 @@ enum {
ARROW_CUSTOM_RANGE_SET = (1 << 1),
};
typedef struct ArrowManipulator {
typedef struct ArrowManipulator3D {
wmManipulator manipulator;
ManipulatorCommonData data;
@@ -86,20 +86,20 @@ typedef struct ArrowManipulator {
float direction[3];
float up[3];
float aspect[2]; /* cone style only */
} ArrowManipulator;
} ArrowManipulator3D;
/* -------------------------------------------------------------------- */
static void manipulator_arrow_get_final_pos(wmManipulator *manipulator, float r_pos[3])
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
mul_v3_v3fl(r_pos, arrow->direction, arrow->data.offset);
add_v3_v3(r_pos, arrow->manipulator.origin);
}
static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, const float color[4])
static void arrow_draw_geom(const ArrowManipulator3D *arrow, const bool select, const float color[4])
{
unsigned int pos = VertexFormat_add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
bool unbind_shader = true;
@@ -186,7 +186,7 @@ static void arrow_draw_geom(const ArrowManipulator *arrow, const bool select, co
}
}
static void arrow_draw_intern(ArrowManipulator *arrow, const bool select, const bool highlight)
static void arrow_draw_intern(ArrowManipulator3D *arrow, const bool select, const bool highlight)
{
const float up[3] = {0.0f, 0.0f, 1.0f};
float col[4];
@@ -244,12 +244,12 @@ static void manipulator_arrow_render_3d_intersect(
int selectionbase)
{
GPU_select_load_id(selectionbase);
arrow_draw_intern((ArrowManipulator *)manipulator, true, false);
arrow_draw_intern((ArrowManipulator3D *)manipulator, true, false);
}
static void manipulator_arrow_draw(const bContext *UNUSED(C), wmManipulator *manipulator)
{
arrow_draw_intern((ArrowManipulator *)manipulator, false, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
arrow_draw_intern((ArrowManipulator3D *)manipulator, false, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
}
/**
@@ -258,7 +258,7 @@ static void manipulator_arrow_draw(const bContext *UNUSED(C), wmManipulator *man
*/
static void manipulator_arrow_handler(bContext *C, wmManipulator *manipulator, const wmEvent *event, const int flag)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
ManipulatorInteraction *inter = manipulator->interaction_data;
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
@@ -372,7 +372,7 @@ static void manipulator_arrow_handler(bContext *C, wmManipulator *manipulator, c
static void manipulator_arrow_invoke(
bContext *UNUSED(C), wmManipulator *manipulator, const wmEvent *event)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
PointerRNA ptr = manipulator->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
PropertyRNA *prop = manipulator->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
@@ -395,11 +395,11 @@ static void manipulator_arrow_invoke(
static void manipulator_arrow_prop_data_update(wmManipulator *manipulator, const int slot)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
manipulator_property_data_update(
manipulator, &arrow->data, slot,
arrow->style & MANIPULATOR_ARROW_STYLE_CONSTRAINED,
arrow->style & MANIPULATOR_ARROW_STYLE_INVERTED);
manipulator, &arrow->data, slot,
(arrow->style & MANIPULATOR_ARROW_STYLE_CONSTRAINED) != 0,
(arrow->style & MANIPULATOR_ARROW_STYLE_INVERTED) != 0);
}
static void manipulator_arrow_exit(bContext *C, wmManipulator *manipulator, const bool cancel)
@@ -407,7 +407,7 @@ static void manipulator_arrow_exit(bContext *C, wmManipulator *manipulator, cons
if (!cancel)
return;
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
ManipulatorCommonData *data = &arrow->data;
ManipulatorInteraction *inter = manipulator->interaction_data;
@@ -423,6 +423,9 @@ static void manipulator_arrow_exit(bContext *C, wmManipulator *manipulator, cons
wmManipulator *MANIPULATOR_arrow_new(wmManipulatorGroup *mgroup, const char *name, const int style)
{
const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_arrow_3d", false);
ArrowManipulator3D *arrow = (ArrowManipulator3D *)WM_manipulator_new(mpt, mgroup, name);
int real_style = style;
/* inverted only makes sense in a constrained arrow */
@@ -430,18 +433,8 @@ wmManipulator *MANIPULATOR_arrow_new(wmManipulatorGroup *mgroup, const char *nam
real_style |= MANIPULATOR_ARROW_STYLE_CONSTRAINED;
}
ArrowManipulator *arrow = MEM_callocN(sizeof(ArrowManipulator), name);
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
arrow->manipulator.type.draw = manipulator_arrow_draw;
arrow->manipulator.type.draw_select = manipulator_arrow_render_3d_intersect;
arrow->manipulator.type.final_position_get = manipulator_arrow_get_final_pos;
arrow->manipulator.type.intersect = NULL;
arrow->manipulator.type.handler = manipulator_arrow_handler;
arrow->manipulator.type.invoke = manipulator_arrow_invoke;
arrow->manipulator.type.prop_data_update = manipulator_arrow_prop_data_update;
arrow->manipulator.type.exit = manipulator_arrow_exit;
arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
arrow->style = real_style;
@@ -449,9 +442,7 @@ wmManipulator *MANIPULATOR_arrow_new(wmManipulatorGroup *mgroup, const char *nam
arrow->data.range_fac = 1.0f;
copy_v3_v3(arrow->direction, dir_default);
wm_manipulator_register(mgroup, &arrow->manipulator, name);
return (wmManipulator *)arrow;
return &arrow->manipulator;
}
/**
@@ -459,7 +450,7 @@ wmManipulator *MANIPULATOR_arrow_new(wmManipulatorGroup *mgroup, const char *nam
*/
void MANIPULATOR_arrow_set_direction(wmManipulator *manipulator, const float direction[3])
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
copy_v3_v3(arrow->direction, direction);
normalize_v3(arrow->direction);
@@ -470,7 +461,7 @@ void MANIPULATOR_arrow_set_direction(wmManipulator *manipulator, const float dir
*/
void MANIPULATOR_arrow_set_up_vector(wmManipulator *manipulator, const float direction[3])
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
if (direction) {
copy_v3_v3(arrow->up, direction);
@@ -487,7 +478,7 @@ void MANIPULATOR_arrow_set_up_vector(wmManipulator *manipulator, const float dir
*/
void MANIPULATOR_arrow_set_line_len(wmManipulator *manipulator, const float len)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
arrow->len = len;
}
@@ -498,7 +489,7 @@ void MANIPULATOR_arrow_set_line_len(wmManipulator *manipulator, const float len)
*/
void MANIPULATOR_arrow_set_ui_range(wmManipulator *manipulator, const float min, const float max)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
BLI_assert(min < max);
BLI_assert(!(arrow->manipulator.props[0] && "Make sure this function "
@@ -516,7 +507,7 @@ void MANIPULATOR_arrow_set_ui_range(wmManipulator *manipulator, const float min,
*/
void MANIPULATOR_arrow_set_range_fac(wmManipulator *manipulator, const float range_fac)
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
BLI_assert(!(arrow->manipulator.props[0] && "Make sure this function "
"is called before WM_manipulator_set_property"));
@@ -529,11 +520,34 @@ void MANIPULATOR_arrow_set_range_fac(wmManipulator *manipulator, const float ran
*/
void MANIPULATOR_arrow_cone_set_aspect(wmManipulator *manipulator, const float aspect[2])
{
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
ArrowManipulator3D *arrow = (ArrowManipulator3D *)manipulator;
copy_v2_v2(arrow->aspect, aspect);
}
static void MANIPULATOR_WT_arrow_3d(wmManipulatorType *wt)
{
/* identifiers */
wt->idname = "MANIPULATOR_WT_arrow_3d";
/* api callbacks */
wt->draw = manipulator_arrow_draw;
wt->draw_select = manipulator_arrow_render_3d_intersect;
wt->position_get = manipulator_arrow_get_final_pos;
wt->intersect = NULL;
wt->handler = manipulator_arrow_handler;
wt->invoke = manipulator_arrow_invoke;
wt->prop_data_update = manipulator_arrow_prop_data_update;
wt->exit = manipulator_arrow_exit;
wt->size = sizeof(ArrowManipulator3D);
}
void ED_manipulatortypes_arrow_3d(void)
{
WM_manipulatortype_append(MANIPULATOR_WT_arrow_3d);
}
/** \} */ /* Arrow Manipulator API */

View File

@@ -553,23 +553,14 @@ static void manipulator_rect_transform_exit(bContext *C, wmManipulator *manipula
wmManipulator *MANIPULATOR_rect_transform_new(wmManipulatorGroup *mgroup, const char *name, const int style)
{
RectTransformManipulator *cage = MEM_callocN(sizeof(RectTransformManipulator), name);
const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_cage", false);
RectTransformManipulator *cage = (RectTransformManipulator *)WM_manipulator_new(mpt, mgroup, name);
cage->manipulator.type.draw = manipulator_rect_transform_draw;
cage->manipulator.type.invoke = manipulator_rect_transform_invoke;
cage->manipulator.type.prop_data_update = manipulator_rect_transform_prop_data_update;
cage->manipulator.type.handler = manipulator_rect_transform_handler;
cage->manipulator.type.intersect = manipulator_rect_transform_intersect;
cage->manipulator.type.exit = manipulator_rect_transform_exit;
cage->manipulator.type.cursor_get = manipulator_rect_transform_get_cursor;
cage->manipulator.max_prop = 2;
cage->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
cage->scale[0] = cage->scale[1] = 1.0f;
cage->style = style;
wm_manipulator_register(mgroup, &cage->manipulator, name);
return (wmManipulator *)cage;
return &cage->manipulator;
}
void MANIPULATOR_rect_transform_set_dimensions(wmManipulator *manipulator, const float width, const float height)
@@ -579,6 +570,30 @@ void MANIPULATOR_rect_transform_set_dimensions(wmManipulator *manipulator, const
cage->h = height;
}
static void MANIPULATOR_WT_cage(wmManipulatorType *wt)
{
/* identifiers */
wt->idname = "MANIPULATOR_WT_cage";
/* api callbacks */
wt->draw = manipulator_rect_transform_draw;
wt->invoke = manipulator_rect_transform_invoke;
wt->prop_data_update = manipulator_rect_transform_prop_data_update;
wt->handler = manipulator_rect_transform_handler;
wt->intersect = manipulator_rect_transform_intersect;
wt->exit = manipulator_rect_transform_exit;
wt->cursor_get = manipulator_rect_transform_get_cursor;
wt->prop_len_max = 2;
wt->size = sizeof(RectTransformManipulator);
}
void ED_manipulatortypes_cage(void)
{
WM_manipulatortype_append(MANIPULATOR_WT_cage);
}
/** \} */ // Cage Manipulator API

View File

@@ -334,21 +334,16 @@ static void manipulator_dial_invoke(
wmManipulator *MANIPULATOR_dial_new(wmManipulatorGroup *mgroup, const char *name, const int style)
{
DialManipulator *dial = MEM_callocN(sizeof(DialManipulator), name);
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_dial", false);
DialManipulator *dial = (DialManipulator *)WM_manipulator_new(mpt, mgroup, name);
dial->manipulator.type.draw = manipulator_dial_draw;
dial->manipulator.type.draw_select = manipulator_dial_render_3d_intersect;
dial->manipulator.type.intersect = NULL;
dial->manipulator.type.invoke = manipulator_dial_invoke;
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
dial->style = style;
/* defaults */
copy_v3_v3(dial->direction, dir_default);
wm_manipulator_register(mgroup, &dial->manipulator, name);
return (wmManipulator *)dial;
}
@@ -363,8 +358,25 @@ void MANIPULATOR_dial_set_up_vector(wmManipulator *manipulator, const float dire
normalize_v3(dial->direction);
}
/** \} */ // Dial Manipulator API
static void MANIPULATOR_WT_dial(wmManipulatorType *wt)
{
/* identifiers */
wt->idname = "MANIPULATOR_WT_dial";
/* api callbacks */
wt->draw = manipulator_dial_draw;
wt->draw_select = manipulator_dial_render_3d_intersect;
wt->invoke = manipulator_dial_invoke;
wt->size = sizeof(DialManipulator);
}
void ED_manipulatortypes_dial(void)
{
WM_manipulatortype_append(MANIPULATOR_WT_dial);
}
/** \} */ // Dial Manipulator API
/* -------------------------------------------------------------------- */

View File

@@ -193,21 +193,17 @@ static void manipulator_primitive_invoke(
wmManipulator *MANIPULATOR_primitive_new(wmManipulatorGroup *mgroup, const char *name, const int style)
{
PrimitiveManipulator *prim = MEM_callocN(sizeof(PrimitiveManipulator), name);
const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_primitive", false);
PrimitiveManipulator *prim = (PrimitiveManipulator *)WM_manipulator_new(mpt, mgroup, name);
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
prim->manipulator.type.draw = manipulator_primitive_draw;
prim->manipulator.type.draw_select = manipulator_primitive_render_3d_intersect;
prim->manipulator.type.invoke = manipulator_primitive_invoke;
prim->manipulator.type.intersect = NULL;
prim->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
prim->style = style;
/* defaults */
copy_v3_v3(prim->direction, dir_default);
wm_manipulator_register(mgroup, &prim->manipulator, name);
return (wmManipulator *)prim;
}
@@ -237,6 +233,24 @@ void MANIPULATOR_primitive_set_up_vector(wmManipulator *manipulator, const float
}
}
static void MANIPULATOR_WT_primitive(wmManipulatorType *wt)
{
/* identifiers */
wt->idname = "MANIPULATOR_WT_primitive";
/* api callbacks */
wt->draw = manipulator_primitive_draw;
wt->draw_select = manipulator_primitive_render_3d_intersect;
wt->invoke = manipulator_primitive_invoke;
wt->size = sizeof(PrimitiveManipulator);
}
void ED_manipulatortypes_primitive(void)
{
WM_manipulatortype_append(MANIPULATOR_WT_primitive);
}
/** \} */ // Primitive Manipulator API

View File

@@ -30,6 +30,7 @@
#include "BKE_context.h"
#include "BLI_listbase.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
@@ -50,12 +51,119 @@
#include "WM_api.h"
#include "WM_types.h"
/* only for own init/exit calls (wm_manipulatortype_init/wm_manipulatortype_free) */
#include "wm.h"
/* own includes */
#include "wm_manipulator_wmapi.h"
#include "wm_manipulator_intern.h"
#include "manipulator_library/manipulator_geometry.h"
static void wm_manipulator_register(
wmManipulatorGroup *mgroup, wmManipulator *manipulator, const char *name);
/** \name Manipulator Type Append
*
* \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends.
* \{ */
static GHash *global_manipulatortype_hash = NULL;
const wmManipulatorType *WM_manipulatortype_find(const char *idname, bool quiet)
{
if (idname[0]) {
wmManipulatorType *mt;
mt = BLI_ghash_lookup(global_manipulatortype_hash, idname);
if (mt) {
return mt;
}
if (!quiet) {
printf("search for unknown manipulator '%s'\n", idname);
}
}
else {
if (!quiet) {
printf("search for empty manipulator\n");
}
}
return NULL;
}
/* caller must free */
void WM_manipulatortype_iter(GHashIterator *ghi)
{
BLI_ghashIterator_init(ghi, global_manipulatortype_hash);
}
static wmManipulatorType *wm_manipulatortype_append__begin(void)
{
wmManipulatorType *mt = MEM_callocN(sizeof(wmManipulatorType), "manipulatortype");
return mt;
}
static void wm_manipulatortype_append__end(wmManipulatorType *mt)
{
/* Create at least one property for interaction,
* note: we could enforce each type sets this it's self. */
if (mt->prop_len_max == 0) {
mt->prop_len_max = 1;
}
BLI_ghash_insert(global_manipulatortype_hash, (void *)mt->idname, mt);
}
void WM_manipulatortype_append(void (*mtfunc)(struct wmManipulatorType *))
{
wmManipulatorType *mt = wm_manipulatortype_append__begin();
mtfunc(mt);
wm_manipulatortype_append__end(mt);
}
void WM_manipulatortype_append_ptr(void (*mtfunc)(struct wmManipulatorType *, void *), void *userdata)
{
wmManipulatorType *mt = wm_manipulatortype_append__begin();
mtfunc(mt, userdata);
wm_manipulatortype_append__end(mt);
}
static void manipulatortype_ghash_free_cb(wmManipulatorType *mt)
{
MEM_freeN(mt);
}
void wm_manipulatortype_free(void)
{
BLI_ghash_free(global_manipulatortype_hash, NULL, (GHashValFreeFP)manipulatortype_ghash_free_cb);
global_manipulatortype_hash = NULL;
}
/* called on initialize WM_init() */
void wm_manipulatortype_init(void)
{
/* reserve size is set based on blender default setup */
global_manipulatortype_hash = BLI_ghash_str_new_ex("wm_manipulatortype_init gh", 128);
}
/** \} */
/**
* \note Follow #wm_operator_create convention.
*/
static wmManipulator *wm_manipulator_create(
const wmManipulatorType *mpt)
{
BLI_assert(mpt != NULL);
BLI_assert(mpt->size >= sizeof(wmManipulator));
wmManipulator *mpr = MEM_callocN(mpt->size, __func__);
mpr->type = mpt;
return mpr;
}
/**
* Main draw call for ManipulatorGeomInfo data
*/
@@ -125,11 +233,11 @@ void wm_manipulator_vec_draw(
immEnd();
}
wmManipulator *WM_manipulator_new(wmManipulatorGroup *mgroup, const char *name)
wmManipulator *WM_manipulator_new(const wmManipulatorType *mpt, wmManipulatorGroup *mgroup, const char *name)
{
wmManipulator *manipulator = MEM_callocN(sizeof(wmManipulator), __func__);
wmManipulator *mpr = wm_manipulator_create(mpt);
wm_manipulator_register(mgroup, manipulator, name);
wm_manipulator_register(mgroup, mpr, name);
/* XXX: never happens */
if (name[0] == '\n') {
@@ -140,7 +248,7 @@ wmManipulator *WM_manipulator_new(wmManipulatorGroup *mgroup, const char *name)
fix_linking_manipulator_primitive();
}
return manipulator;
return mpr;
}
wmManipulatorGroup *WM_manipulator_get_parent_group(wmManipulator *manipulator)
@@ -170,24 +278,19 @@ static void manipulator_unique_idname_set(wmManipulatorGroup *mgroup, wmManipula
/**
* Initialize default values and allocate needed memory for members.
*/
static void manipulator_init(wmManipulator *manipulator)
static void manipulator_init(wmManipulator *mpr)
{
const float col_default[4] = {1.0f, 1.0f, 1.0f, 1.0f};
manipulator->user_scale = 1.0f;
manipulator->line_width = 1.0f;
mpr->user_scale = 1.0f;
mpr->line_width = 1.0f;
/* defaults */
copy_v4_v4(manipulator->col, col_default);
copy_v4_v4(manipulator->col_hi, col_default);
copy_v4_v4(mpr->col, col_default);
copy_v4_v4(mpr->col_hi, col_default);
/* create at least one property for interaction */
if (manipulator->max_prop == 0) {
manipulator->max_prop = 1;
}
manipulator->props = MEM_callocN(sizeof(PropertyRNA *) * manipulator->max_prop, "manipulator->props");
manipulator->ptr = MEM_callocN(sizeof(PointerRNA) * manipulator->max_prop, "manipulator->ptr");
mpr->props = MEM_callocN(sizeof(PropertyRNA *) * mpr->type->prop_len_max, "manipulator->props");
mpr->ptr = MEM_callocN(sizeof(PointerRNA) * mpr->type->prop_len_max, "manipulator->ptr");
}
/**
@@ -195,7 +298,7 @@ static void manipulator_init(wmManipulator *manipulator)
*
* \param name: name used to create a unique idname for \a manipulator in \a mgroup
*/
void wm_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *manipulator, const char *name)
static void wm_manipulator_register(wmManipulatorGroup *mgroup, wmManipulator *manipulator, const char *name)
{
manipulator_init(manipulator);
manipulator_unique_idname_set(mgroup, manipulator, name);
@@ -244,7 +347,7 @@ wmManipulatorGroup *wm_manipulator_get_parent_group(const wmManipulator *manipul
void WM_manipulator_set_property(wmManipulator *manipulator, const int slot, PointerRNA *ptr, const char *propname)
{
if (slot < 0 || slot >= manipulator->max_prop) {
if (slot < 0 || slot >= manipulator->type->prop_len_max) {
fprintf(stderr, "invalid index %d when binding property for manipulator type %s\n", slot, manipulator->idname);
return;
}
@@ -254,8 +357,8 @@ void WM_manipulator_set_property(wmManipulator *manipulator, const int slot, Poi
manipulator->ptr[slot] = *ptr;
manipulator->props[slot] = RNA_struct_find_property(ptr, propname);
if (manipulator->type.prop_data_update) {
manipulator->type.prop_data_update(manipulator, slot);
if (manipulator->type->prop_data_update) {
manipulator->type->prop_data_update(manipulator, slot);
}
}
@@ -343,47 +446,51 @@ void WM_manipulator_set_color_highlight(wmManipulator *manipulator, const float
*
* \{ */
#if 0
void WM_manipulator_set_fn_draw(wmManipulator *mpr, wmManipulatorFnDraw draw_fn)
{
mpr->type.draw = draw_fn;
mpr->type->draw = draw_fn;
}
void WM_manipulator_set_fn_draw_select(struct wmManipulator *mpr, wmManipulatorFnDrawSelect fn)
{
mpr->type.draw_select = fn;
mpr->type->draw_select = fn;
}
void WM_manipulator_set_fn_intersect(wmManipulator *mpr, wmManipulatorFnIntersect fn)
{
mpr->type.intersect = fn;
mpr->type->intersect = fn;
}
void WM_manipulator_set_fn_handler(struct wmManipulator *mpr, wmManipulatorFnHandler fn)
#endif
void WM_manipulator_set_fn_custom_handler(struct wmManipulator *mpr, wmManipulatorFnHandler fn)
{
mpr->type.handler = fn;
mpr->custom_handler = fn;
}
#if 0
void WM_manipulator_set_fn_prop_data_update(struct wmManipulator *mpr, wmManipulatorFnPropDataUpdate fn)
{
mpr->type.prop_data_update = fn;
mpr->type->prop_data_update = fn;
}
void WM_manipulator_set_fn_final_position_get(struct wmManipulator *mpr, wmManipulatorFnFinalPositionGet fn)
{
mpr->type.final_position_get = fn;
mpr->type->final_position_get = fn;
}
void WM_manipulator_set_fn_invoke(struct wmManipulator *mpr, wmManipulatorFnInvoke fn)
{
mpr->type.invoke = fn;
mpr->type->invoke = fn;
}
void WM_manipulator_set_fn_exit(struct wmManipulator *mpr, wmManipulatorFnExit fn)
{
mpr->type.exit = fn;
mpr->type->exit = fn;
}
void WM_manipulator_set_fn_cursor_get(struct wmManipulator *mpr, wmManipulatorFnCursorGet fn)
{
mpr->type.cursor_get = fn;
mpr->type->cursor_get = fn;
}
void WM_manipulator_set_fn_select(wmManipulator *mpr, wmManipulatorFnSelect fn)
{
BLI_assert(mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SELECTABLE);
mpr->type.select = fn;
mpr->type->select = fn;
}
#endif
/** \} */
@@ -452,8 +559,8 @@ bool wm_manipulator_select(bContext *C, wmManipulatorMap *mmap, wmManipulator *m
(*sel)[(*tot_selected) - 1] = manipulator;
manipulator->state |= WM_MANIPULATOR_SELECTED;
if (manipulator->type.select) {
manipulator->type.select(C, manipulator, SEL_SELECT);
if (manipulator->type->select) {
manipulator->type->select(C, manipulator, SEL_SELECT);
}
wm_manipulatormap_set_highlighted_manipulator(mmap, C, manipulator, manipulator->highlighted_part);
@@ -467,10 +574,10 @@ void wm_manipulator_calculate_scale(wmManipulator *manipulator, const bContext *
if (manipulator->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SCALE_3D) {
if (rv3d /*&& (U.manipulator_flag & V3D_DRAW_MANIPULATOR) == 0*/) { /* UserPref flag might be useful for later */
if (manipulator->type.final_position_get) {
if (manipulator->type->position_get) {
float position[3];
manipulator->type.final_position_get(manipulator, position);
manipulator->type->position_get(manipulator, position);
scale = ED_view3d_pixel_size(rv3d, position) * (float)U.manipulator_scale;
}
else {
@@ -488,10 +595,10 @@ void wm_manipulator_calculate_scale(wmManipulator *manipulator, const bContext *
static void manipulator_update_prop_data(wmManipulator *manipulator)
{
/* manipulator property might have been changed, so update manipulator */
if (manipulator->props && manipulator->type.prop_data_update) {
for (int i = 0; i < manipulator->max_prop; i++) {
if (manipulator->props && manipulator->type->prop_data_update) {
for (int i = 0; i < manipulator->type->prop_len_max; i++) {
if (manipulator->props[i]) {
manipulator->type.prop_data_update(manipulator, i);
manipulator->type->prop_data_update(manipulator, i);
}
}
}
@@ -526,4 +633,3 @@ bool wm_manipulator_is_visible(wmManipulator *manipulator)
return true;
}

View File

@@ -31,6 +31,7 @@
struct wmKeyConfig;
struct wmManipulatorMap;
struct ManipulatorGeomInfo;
struct GHashIterator;
#include "wm_manipulator_fn.h"
@@ -42,42 +43,17 @@ struct wmManipulator {
struct wmManipulator *next, *prev;
char idname[MAX_NAME + 4]; /* + 4 for unique '.001', '.002', etc suffix */
/* pointer back to group this manipulator is in (just for quick access) */
struct wmManipulatorGroup *parent_mgroup;
/* While we don't have a real type, use this to put type-like vars. */
struct {
/* could become wmManipulatorType */
/* draw manipulator */
wmManipulatorFnDraw draw;
const struct wmManipulatorType *type;
/* determines 3d intersection by rendering the manipulator in a selection routine. */
wmManipulatorFnDrawSelect draw_select;
/* Overrides 'type->handler' when set. */
wmManipulatorFnHandler custom_handler;
/* determine if the mouse intersects with the manipulator. The calculation should be done in the callback itself */
wmManipulatorFnIntersect intersect;
void *custom_data;
/* handler used by the manipulator. Usually handles interaction tied to a manipulator type */
wmManipulatorFnHandler handler;
/* manipulator-specific handler to update manipulator attributes based on the property value */
wmManipulatorFnPropDataUpdate prop_data_update;
/* returns the final position which may be different from the origin, depending on the manipulator.
* used in calculations of scale */
wmManipulatorFnFinalPositionGet final_position_get;
/* activate a manipulator state when the user clicks on it */
wmManipulatorFnInvoke invoke;
/* called when manipulator tweaking is done - used to free data and reset property when cancelling */
wmManipulatorFnExit exit;
wmManipulatorFnCursorGet cursor_get;
/* called when manipulator selection state changes */
wmManipulatorFnSelect select;
} type;
/* pointer back to group this manipulator is in (just for quick access) */
struct wmManipulatorGroup *parent_mgroup;
int flag; /* flags that influence the behavior or how the manipulators are drawn */
short state; /* state flags (active, highlighted, selected) */
@@ -106,8 +82,6 @@ struct wmManipulator {
* or owner pointer if manipulator spawns and controls a property */
PointerRNA opptr;
/* maximum number of properties attached to the manipulator */
int max_prop;
/* arrays of properties attached to various manipulator parameters. As
* the manipulator is interacted with, those properties get updated */
PointerRNA *ptr;
@@ -131,8 +105,6 @@ enum {
WM_MANIPULATOR_TWEAK_PRECISE = (1 << 0),
};
void wm_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *manipulator, const char *name);
bool wm_manipulator_deselect(struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
bool wm_manipulator_select(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
@@ -147,7 +119,6 @@ void fix_linking_manipulator_dial(void);
void fix_linking_manipulator_facemap(void);
void fix_linking_manipulator_primitive(void);
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */

View File

@@ -159,8 +159,8 @@ wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
unsigned char *part)
{
for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
if (manipulator->type.intersect && (manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
if ((*part = manipulator->type.intersect(C, manipulator, event))) {
if (manipulator->type->intersect && (manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
if ((*part = manipulator->type->intersect(C, manipulator, event))) {
return manipulator;
}
}
@@ -176,8 +176,8 @@ void wm_manipulatorgroup_intersectable_manipulators_to_list(const wmManipulatorG
{
for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
if ((manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
if (((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) && manipulator->type.draw_select) ||
((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) == 0 && manipulator->type.intersect))
if (((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) && manipulator->type->draw_select) ||
((mgroup->type->flag & WM_MANIPULATORGROUPTYPE_IS_3D) == 0 && manipulator->type->intersect))
{
BLI_addhead(listbase, BLI_genericNodeN(manipulator));
}
@@ -297,8 +297,8 @@ typedef struct ManipulatorTweakData {
static void manipulator_tweak_finish(bContext *C, wmOperator *op, const bool cancel)
{
ManipulatorTweakData *mtweak = op->customdata;
if (mtweak->active->type.exit) {
mtweak->active->type.exit(C, mtweak->active, cancel);
if (mtweak->active->type->exit) {
mtweak->active->type->exit(C, mtweak->active, cancel);
}
wm_manipulatormap_set_active_manipulator(mtweak->mmap, C, NULL, NULL);
MEM_freeN(mtweak);
@@ -338,8 +338,11 @@ static int manipulator_tweak_modal(bContext *C, wmOperator *op, const wmEvent *e
}
/* handle manipulator */
if (manipulator->type.handler) {
manipulator->type.handler(C, manipulator, event, mtweak->flag);
if (manipulator->custom_handler) {
manipulator->custom_handler(C, manipulator, event, mtweak->flag);
}
else if (manipulator->type->handler) {
manipulator->type->handler(C, manipulator, event, mtweak->flag);
}
/* Ugly hack to send manipulator events */

View File

@@ -255,7 +255,7 @@ static void manipulators_draw_list(const wmManipulatorMap *mmap, const bContext
wmManipulator *manipulator = link->data;
link_next = link->next;
manipulator->type.draw(C, manipulator);
manipulator->type->draw(C, manipulator);
/* free/remove manipulator link after drawing */
BLI_freelinkN(draw_manipulators, link);
}
@@ -282,7 +282,7 @@ static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible
for (LinkData *link = visible_manipulators->first; link; link = link->next) {
manipulator = link->data;
/* pass the selection id shifted by 8 bits. Last 8 bits are used for selected manipulator part id */
manipulator->type.draw_select(C, manipulator, selectionbase << 8);
manipulator->type->draw_select(C, manipulator, selectionbase << 8);
selectionbase++;
}
@@ -423,10 +423,15 @@ void wm_manipulatormaps_handled_modal_update(
/* regular update for running operator */
if (modal_running) {
if (manipulator && manipulator->type.handler && manipulator->opname &&
if (manipulator && manipulator->opname &&
STREQ(manipulator->opname, handler->op->idname))
{
manipulator->type.handler(C, manipulator, event, 0);
if (manipulator->custom_handler) {
manipulator->custom_handler(C, manipulator, event, 0);
}
else if (manipulator->type->handler) {
manipulator->type->handler(C, manipulator, event, 0);
}
}
}
/* operator not running anymore */
@@ -492,8 +497,8 @@ static bool wm_manipulatormap_select_all_intern(
changed = true;
}
manipulator_iter->state |= WM_MANIPULATOR_SELECTED;
if (manipulator_iter->type.select) {
manipulator_iter->type.select(C, manipulator_iter, action);
if (manipulator_iter->type->select) {
manipulator_iter->type->select(C, manipulator_iter, action);
}
(*sel)[i] = manipulator_iter;
BLI_assert(i < (*tot_sel));
@@ -576,8 +581,8 @@ bool WM_manipulatormap_cursor_set(const wmManipulatorMap *mmap, wmWindow *win)
{
for (; mmap; mmap = mmap->next) {
wmManipulator *manipulator = mmap->mmap_context.highlighted_manipulator;
if (manipulator && manipulator->type.cursor_get) {
WM_cursor_set(win, manipulator->type.cursor_get(manipulator));
if (manipulator && manipulator->type->cursor_get) {
WM_cursor_set(win, manipulator->type->cursor_get(manipulator));
return true;
}
}
@@ -603,9 +608,9 @@ void wm_manipulatormap_set_highlighted_manipulator(
manipulator->state |= WM_MANIPULATOR_HIGHLIGHT;
manipulator->highlighted_part = part;
if (C && manipulator->type.cursor_get) {
if (C && manipulator->type->cursor_get) {
wmWindow *win = CTX_wm_window(C);
WM_cursor_set(win, manipulator->type.cursor_get(manipulator));
WM_cursor_set(win, manipulator->type->cursor_get(manipulator));
}
}
else {
@@ -640,8 +645,10 @@ void wm_manipulatormap_set_active_manipulator(
if (ot) {
/* first activate the manipulator itself */
if (manipulator->type.invoke && manipulator->type.handler) {
manipulator->type.invoke(C, manipulator, event);
if (manipulator->type->invoke &&
(manipulator->type->handler || manipulator->custom_handler))
{
manipulator->type->invoke(C, manipulator, event);
}
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &manipulator->opptr);
@@ -664,8 +671,10 @@ void wm_manipulatormap_set_active_manipulator(
}
}
else {
if (manipulator->type.invoke && manipulator->type.handler) {
manipulator->type.invoke(C, manipulator, event);
if (manipulator->type->invoke &&
(manipulator->type->handler || manipulator->custom_handler))
{
manipulator->type->invoke(C, manipulator, event);
}
}
WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);

View File

@@ -49,6 +49,10 @@ struct wmOperator;
struct wmManipulatorGroup *wm_manipulator_get_parent_group(const struct wmManipulator *manipulator);
/* wm_manipulator.c, for init/exit */
void wm_manipulatortype_free(void);
void wm_manipulatortype_init(void);
/* -------------------------------------------------------------------- */
/* wmManipulatorGroup */