From 575db256dbb54cc013c729157115ba4be8c7b13e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Jun 2017 05:27:14 +1000 Subject: WM: add wmManipulatorType, from wmManipulator Having the type in mixed in with each instance made it hard to expose types to RNA/Python. --- source/blender/editors/space_api/spacetypes.c | 16 ++ .../editors/transform/transform_manipulator.c | 2 +- source/blender/windowmanager/intern/wm_init_exit.c | 2 + .../manipulators/WM_manipulator_api.h | 23 +-- .../manipulators/WM_manipulator_library.h | 7 + .../manipulators/WM_manipulator_types.h | 45 +++++ .../manipulator_library/arrow2d_manipulator.c | 34 ++-- .../intern/manipulator_library/arrow_manipulator.c | 80 +++++---- .../intern/manipulator_library/cage_manipulator.c | 41 +++-- .../intern/manipulator_library/dial_manipulator.c | 30 +++- .../manipulator_library/primitive_manipulator.c | 28 +++- .../manipulators/intern/wm_manipulator.c | 184 ++++++++++++++++----- .../manipulators/intern/wm_manipulator_intern.h | 43 +---- .../manipulators/intern/wm_manipulatorgroup.c | 19 ++- .../manipulators/intern/wm_manipulatormap.c | 37 +++-- .../manipulators/wm_manipulator_wmapi.h | 4 + 16 files changed, 414 insertions(+), 181 deletions(-) diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 3a431eb82df..acc197bcc5b 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -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) { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index d1c8c08ec88..6d38037ab30 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -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: diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 022502c9935..6cf27094e67 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -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) diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index bffd7607fd0..f43c47005a9 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -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 */ diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_library.h b/source/blender/windowmanager/manipulators/WM_manipulator_library.h index 1e7106905e3..4e0c5b004c8 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_library.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_library.h @@ -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__ */ diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h index 5fb909b06cf..01f5d1c0199 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h @@ -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 */ diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c index 106e1f97990..0cec342dd06 100644 --- a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow2d_manipulator.c @@ -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__); - - 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; + const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_arrow_2d", false); + ArrowManipulator2D *arrow = (ArrowManipulator2D *)WM_manipulator_new(mpt, mgroup, name); + 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 */ diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c index bbfe17485cf..0487903163a 100644 --- a/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c @@ -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 */ diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c index c89633cf0fa..30c24b1c788 100644 --- a/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/cage_manipulator.c @@ -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); - - 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; + const wmManipulatorType *mpt = WM_manipulatortype_find("MANIPULATOR_WT_cage", false); + RectTransformManipulator *cage = (RectTransformManipulator *)WM_manipulator_new(mpt, mgroup, name); + 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 diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c index 0f4467f16ed..aeb1fa76abd 100644 --- a/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c @@ -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 /* -------------------------------------------------------------------- */ diff --git a/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c b/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c index 0c27e739fe7..c67aeace8d9 100644 --- a/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/manipulator_library/primitive_manipulator.c @@ -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 diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c index 2537f02ba3b..a2d88b35b54 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c @@ -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; } - diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h index e0c3fdda181..ca48b05e786 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h @@ -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; - - /* 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; + const struct wmManipulatorType *type; - /* returns the final position which may be different from the origin, depending on the manipulator. - * used in calculations of scale */ - wmManipulatorFnFinalPositionGet final_position_get; + /* Overrides 'type->handler' when set. */ + wmManipulatorFnHandler custom_handler; - /* activate a manipulator state when the user clicks on it */ - wmManipulatorFnInvoke invoke; + void *custom_data; - /* 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 */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c index d805d730651..18bee2e4457 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c @@ -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 */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c index a2549589929..00bc9f2ea56 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c @@ -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); diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h index d33d93ddde4..008e44c5f97 100644 --- a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h +++ b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h @@ -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 */ -- cgit v1.2.3