3D View: Refactor navigation operators #106279

Merged
Germano Cavalcante merged 1 commits from mano-wii/blender:navigation_refactor into main 2023-04-28 14:11:06 +02:00
8 changed files with 466 additions and 375 deletions

View File

@ -43,8 +43,44 @@
#include "view3d_navigate.h" /* own include */
/* Prototypes. */
static void viewops_data_init_context(bContext *C, ViewOpsData *vod);
static void viewops_data_init_navigation(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init,
ViewOpsData *vod);
static void viewops_data_end_navigation(bContext *C, ViewOpsData *vod);
static int viewpan_invoke_impl(ViewOpsData *vod, PointerRNA *ptr);
const char *viewops_operator_idname_get(eV3D_OpMode nav_type)
brecht marked this conversation as resolved Outdated

This should be a static function and get a less generic name like viewops_operator_idname_get.

This should be a static function and get a less generic name like `viewops_operator_idname_get`.
{
mano-wii marked this conversation as resolved Outdated

This name is too generic for a global variable. I think it's better to make this a function call with a switch statement so there will be compiler warnings when this goes out of sync with the enum.

This name is too generic for a global variable. I think it's better to make this a function call with a switch statement so there will be compiler warnings when this goes out of sync with the enum.
switch (nav_type) {
case V3D_OP_MODE_ZOOM:
return "VIEW3D_OT_zoom";
case V3D_OP_MODE_ROTATE:
return "VIEW3D_OT_rotate";
case V3D_OP_MODE_MOVE:
return "VIEW3D_OT_move";
case V3D_OP_MODE_VIEW_PAN:
return "VIEW3D_OT_view_pan";
case V3D_OP_MODE_VIEW_ROLL:
return "VIEW3D_OT_view_roll";
case V3D_OP_MODE_DOLLY:
return "VIEW3D_OT_dolly";
#ifdef WITH_INPUT_NDOF
case V3D_OP_MODE_NDOF_ORBIT:
return "VIEW3D_OT_ndof_orbit";
case V3D_OP_MODE_NDOF_ORBIT_ZOOM:
return "VIEW3D_OT_ndof_orbit_zoom";
#endif
}
BLI_assert(false);
return nullptr;
}
/* -------------------------------------------------------------------- */
/** \name Navigation Polls
/** \name Generic Operator Callback Utils
* \{ */
static bool view3d_navigation_poll_impl(bContext *C, const char viewlock)
@ -57,6 +93,128 @@ static bool view3d_navigation_poll_impl(bContext *C, const char viewlock)
return !(RV3D_LOCK_FLAGS(rv3d) & viewlock);
}
static eV3D_OpEvent view3d_navigate_event(ViewOpsData *vod, const wmEvent *event)
{
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case VIEW_MODAL_CONFIRM:
return VIEW_CONFIRM;
case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
vod->axis_snap = true;
return VIEW_APPLY;
case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
vod->rv3d->persp = vod->init.persp_with_auto_persp_applied;
vod->axis_snap = false;
return VIEW_APPLY;
case VIEWROT_MODAL_SWITCH_ZOOM:
case VIEWROT_MODAL_SWITCH_MOVE:
case VIEWROT_MODAL_SWITCH_ROTATE: {
const eV3D_OpMode nav_type_new = (event->val == VIEWROT_MODAL_SWITCH_ZOOM) ?
V3D_OP_MODE_ZOOM :
(event->val == VIEWROT_MODAL_SWITCH_MOVE) ?
V3D_OP_MODE_MOVE :
V3D_OP_MODE_ROTATE;
if (nav_type_new == vod->nav_type) {
break;
}
mano-wii marked this conversation as resolved Outdated

This switch statement feels like it's putting code in a shared function that really belongs to the specific operator.

This switch statement feels like it's putting code in a shared function that really belongs to the specific operator.
vod->nav_type = nav_type_new;
return VIEW_APPLY;
}
}
mano-wii marked this conversation as resolved Outdated

I rather see an explicit list of cases without default, with a comment explaining why they are not handled. That will give a compiler warning to ensure someone checks if it needs to be handled.

I rather see an explicit list of cases without `default`, with a comment explaining why they are not handled. That will give a compiler warning to ensure someone checks if it needs to be handled.
}
else {
if (event->type == TIMER && event->customdata == vod->timer) {
/* Zoom uses timer for continuous zoom. */
return VIEW_APPLY;
}
if (event->type == MOUSEMOVE) {
return VIEW_APPLY;
}
if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
return VIEW_CONFIRM;
}
if (event->type == EVT_ESCKEY && event->val == KM_PRESS) {
return VIEW_CANCEL;
}
}
return VIEW_PASS;
}
static int view3d_navigation_modal(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2])
{
switch (vod->nav_type) {
case V3D_OP_MODE_ZOOM:
return viewzoom_modal_impl(C, vod, event_code, xy);
case V3D_OP_MODE_ROTATE:
return viewrotate_modal_impl(C, vod, event_code, xy);
case V3D_OP_MODE_MOVE:
return viewmove_modal_impl(C, vod, event_code, xy);
default:
break;
}
return OPERATOR_CANCELLED;
}
static int view3d_navigation_invoke_generic(bContext *C,
ViewOpsData *vod,
const wmEvent *event,
PointerRNA *ptr,
mano-wii marked this conversation as resolved Outdated

Not sure you need to have a switch on the navigation type here at all, if zoom is the only one creating a timer this can just be checked for all types.

Not sure you need to have a switch on the navigation type here at all, if zoom is the only one creating a timer this can just be checked for all types.
const eV3D_OpMode nav_type)
{
bool use_cursor_init = false;
if (PropertyRNA *prop = RNA_struct_find_property(ptr, "use_cursor_init")) {
use_cursor_init = RNA_property_boolean_get(ptr, prop);
}
viewops_data_init_navigation(C, event, nav_type, use_cursor_init, vod);
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
switch (nav_type) {
case V3D_OP_MODE_ZOOM:
return viewzoom_invoke_impl(C, vod, event, ptr);
mano-wii marked this conversation as resolved Outdated

It's unclear why V3D_VIEW_PAN is not handled here, can't tell easily tell if it's intentionally part of default or not.

It's unclear why `V3D_VIEW_PAN` is not handled here, can't tell easily tell if it's intentionally part of `default` or not.
case V3D_OP_MODE_ROTATE:
return viewrotate_invoke_impl(vod, event);
case V3D_OP_MODE_MOVE:
return viewmove_invoke_impl(vod, event);
case V3D_OP_MODE_VIEW_PAN: {
return viewpan_invoke_impl(vod, ptr);
}
default:
break;
}
return OPERATOR_CANCELLED;
}
int view3d_navigate_invoke_impl(bContext *C,
wmOperator *op,
const wmEvent *event,
const eV3D_OpMode nav_type)
{
ViewOpsData *vod = MEM_cnew<ViewOpsData>(__func__);
viewops_data_init_context(C, vod);
int ret = view3d_navigation_invoke_generic(C, vod, event, op->ptr, nav_type);
op->customdata = (void *)vod;
if (ret == OPERATOR_RUNNING_MODAL) {
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
viewops_data_free(C, vod);
op->customdata = nullptr;
return ret;
}
mano-wii marked this conversation as resolved Outdated

Can this check if the use_cursor_init property exists rather than nav_type != V3D_VIEW_PAN?

Can this check if the `use_cursor_init` property exists rather than `nav_type != V3D_VIEW_PAN`?
/** \} */
/* -------------------------------------------------------------------- */
/** \name Generic Callbacks
* \{ */
mano-wii marked this conversation as resolved Outdated

This is unused.

This is unused.
bool view3d_location_poll(bContext *C)
{
return view3d_navigation_poll_impl(C, RV3D_LOCK_LOCATION);
@ -72,11 +230,32 @@ bool view3d_zoom_or_dolly_poll(bContext *C)
return view3d_navigation_poll_impl(C, RV3D_LOCK_ZOOM_AND_DOLLY);
mano-wii marked this conversation as resolved Outdated

Can this logic be in viewzoom_invoke_impl, by passing it the ptr? This also seems like code that should be in the specific operator implementation.

Can this logic be in `viewzoom_invoke_impl`, by passing it the `ptr`? This also seems like code that should be in the specific operator implementation.
}
/** \} */
int view3d_navigate_modal_fn(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = static_cast<ViewOpsData *>(op->customdata);
/* -------------------------------------------------------------------- */
/** \name Generic Callbacks
* \{ */
const eV3D_OpMode nav_type_prev = vod->nav_type;
const eV3D_OpEvent event_code = view3d_navigate_event(vod, event);
if (nav_type_prev != vod->nav_type) {
wmOperatorType *ot_new = WM_operatortype_find(viewops_operator_idname_get(vod->nav_type),
false);
WM_operator_type_set(op, ot_new);
viewops_data_end_navigation(C, vod);
mano-wii marked this conversation as resolved Outdated

I still think that having code like this in the generic function makes it harder to understand and reason about. This logic is tied to the rotate operator and I don't see a reason for it to be here. Personally I would also still prefer passing a ptr to the specific operators rather than sharing the code for RNA property reading.

I still think that having code like this in the generic function makes it harder to understand and reason about. This logic is tied to the rotate operator and I don't see a reason for it to be here. Personally I would also still prefer passing a `ptr` to the specific operators rather than sharing the code for RNA property reading.
return view3d_navigation_invoke_generic(C, vod, event, op->ptr, vod->nav_type);
}
int ret = view3d_navigation_modal(C, vod, event_code, event->xy);
if ((ret & OPERATOR_RUNNING_MODAL) == 0) {
if (ret & OPERATOR_FINISHED) {
ED_view3d_camera_lock_undo_push(op->type->name, vod->v3d, vod->rv3d, C);
}
viewops_data_free(C, vod);
op->customdata = nullptr;
}
return ret;
}
void view3d_navigate_cancel_fn(bContext *C, wmOperator *op)
{
@ -312,8 +491,12 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
return is_set;
}
static enum eViewOpsFlag viewops_flag_from_args(bool use_select, bool use_depth)
static eViewOpsFlag viewops_flag_from_prefs(void)
{
const bool use_select = (U.uiflag & USER_ORBIT_SELECTION) != 0;
const bool use_depth = (U.uiflag & VIEWOPS_FLAG_DEPTH_NAVIGATE) != 0;
const bool use_zoom_to_mouse = (U.uiflag & USER_ZOOM_TO_MOUSEPOS) != 0;
enum eViewOpsFlag flag = VIEWOPS_FLAG_NONE;
if (use_select) {
flag |= VIEWOPS_FLAG_ORBIT_SELECT;
@ -321,20 +504,15 @@ static enum eViewOpsFlag viewops_flag_from_args(bool use_select, bool use_depth)
if (use_depth) {
flag |= VIEWOPS_FLAG_DEPTH_NAVIGATE;
}
if (use_zoom_to_mouse) {
flag |= VIEWOPS_FLAG_ZOOM_TO_MOUSE;
}
return flag;
}
enum eViewOpsFlag viewops_flag_from_prefs(void)
static void viewops_data_init_context(bContext *C, ViewOpsData *vod)
{
return viewops_flag_from_args((U.uiflag & USER_ORBIT_SELECTION) != 0,
(U.uiflag & USER_DEPTH_NAVIGATE) != 0);
}
ViewOpsData *viewops_data_create(bContext *C, const wmEvent *event, enum eViewOpsFlag viewops_flag)
{
ViewOpsData *vod = MEM_cnew<ViewOpsData>(__func__);
/* Store data. */
vod->bmain = CTX_data_main(C);
vod->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@ -343,13 +521,46 @@ ViewOpsData *viewops_data_create(bContext *C, const wmEvent *event, enum eViewOp
vod->region = CTX_wm_region(C);
vod->v3d = static_cast<View3D *>(vod->area->spacedata.first);
vod->rv3d = static_cast<RegionView3D *>(vod->region->regiondata);
}
static void viewops_data_init_navigation(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init,
ViewOpsData *vod)
{
Depsgraph *depsgraph = vod->depsgraph;
RegionView3D *rv3d = vod->rv3d;
eViewOpsFlag viewops_flag = viewops_flag_from_prefs();
if (use_cursor_init) {
viewops_flag |= VIEWOPS_FLAG_USE_MOUSE_INIT;
}
switch (nav_type) {
case V3D_OP_MODE_ZOOM:
case V3D_OP_MODE_MOVE:
case V3D_OP_MODE_VIEW_PAN:
case V3D_OP_MODE_DOLLY:
viewops_flag &= ~VIEWOPS_FLAG_ORBIT_SELECT;
break;
case V3D_OP_MODE_ROTATE:
viewops_flag |= VIEWOPS_FLAG_PERSP_ENSURE;
break;
#ifdef WITH_INPUT_NDOF
case V3D_OP_MODE_NDOF_ORBIT:
case V3D_OP_MODE_NDOF_ORBIT_ZOOM:
viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
break;
#endif
default:
break;
}
/* Could do this more nicely. */
if ((viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) == 0) {
viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
viewops_flag &= ~(VIEWOPS_FLAG_DEPTH_NAVIGATE | VIEWOPS_FLAG_ZOOM_TO_MOUSE);
}
/* we need the depth info before changing any viewport options */
@ -496,12 +707,27 @@ ViewOpsData *viewops_data_create(bContext *C, const wmEvent *event, enum eViewOp
vod->reverse = -1.0f;
}
rv3d->rflag |= RV3D_NAVIGATING;
vod->nav_type = nav_type;
vod->viewops_flag = viewops_flag;
/* Default. */
vod->use_dyn_ofs_ortho_correction = false;
rv3d->rflag |= RV3D_NAVIGATING;
}
ViewOpsData *viewops_data_create(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init)
{
ViewOpsData *vod = MEM_cnew<ViewOpsData>(__func__);
viewops_data_init_context(C, vod);
viewops_data_init_navigation(C, event, nav_type, use_cursor_init, vod);
return vod;
}
void viewops_data_free(bContext *C, ViewOpsData *vod)
static void viewops_data_end_navigation(bContext *C, ViewOpsData *vod)
{
ARegion *region;
if (vod) {
@ -512,11 +738,7 @@ void viewops_data_free(bContext *C, ViewOpsData *vod)
WM_event_remove_timer(CTX_wm_manager(C), vod->timer->win, vod->timer);
}
if (vod->init.dial) {
MEM_freeN(vod->init.dial);
}
MEM_freeN(vod);
MEM_SAFE_FREE(vod->init.dial);
}
else {
region = CTX_wm_region(C);
@ -527,6 +749,14 @@ void viewops_data_free(bContext *C, ViewOpsData *vod)
ED_region_tag_redraw(region);
}
void viewops_data_free(bContext *C, ViewOpsData *vod)
{
viewops_data_end_navigation(C, vod);
if (vod) {
MEM_freeN(vod);
}
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1658,10 +1888,10 @@ static const EnumPropertyItem prop_view_pan_items[] = {
{0, nullptr, 0, nullptr, nullptr},
};
static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int viewpan_invoke_impl(ViewOpsData *vod, PointerRNA *ptr)
{
int x = 0, y = 0;
int pandir = RNA_enum_get(op->ptr, "type");
int pandir = RNA_enum_get(ptr, "type");
if (pandir == V3D_VIEW_PANRIGHT) {
x = -32;
@ -1676,23 +1906,22 @@ static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
y = 25;
}
ViewOpsData *vod = viewops_data_create(
C, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT));
viewmove_apply(vod, vod->prev.event_xy[0] + x, vod->prev.event_xy[1] + y);
ED_view3d_camera_lock_undo_push(op->type->name, vod->v3d, vod->rv3d, C);
viewops_data_free(C, vod);
return OPERATOR_FINISHED;
}
static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_VIEW_PAN);
}
void VIEW3D_OT_view_pan(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Pan View Direction";
ot->description = "Pan the view in a given direction";
ot->idname = "VIEW3D_OT_view_pan";
ot->idname = viewops_operator_idname_get(V3D_OP_MODE_VIEW_PAN);
/* api callbacks */
ot->invoke = viewpan_invoke;

View File

@ -32,6 +32,19 @@ struct rcti;
struct wmEvent;
struct wmOperator;
typedef enum eV3D_OpMode {
V3D_OP_MODE_ZOOM = 0,
V3D_OP_MODE_ROTATE,
V3D_OP_MODE_MOVE,
mano-wii marked this conversation as resolved Outdated

eNavType and V3D_ prefix are too generic. They both need to include 3D viewport and navigation.

`eNavType` and `V3D_` prefix are too generic. They both need to include 3D viewport and navigation.
V3D_OP_MODE_VIEW_PAN,
V3D_OP_MODE_VIEW_ROLL,
V3D_OP_MODE_DOLLY,
#ifdef WITH_INPUT_NDOF
V3D_OP_MODE_NDOF_ORBIT,
V3D_OP_MODE_NDOF_ORBIT_ZOOM,
#endif
} eV3D_OpMode;
enum eV3D_OpPropFlag {
V3D_OP_PROP_MOUSE_CO = (1 << 0),
V3D_OP_PROP_DELTA = (1 << 1),
@ -39,13 +52,13 @@ enum eV3D_OpPropFlag {
V3D_OP_PROP_USE_MOUSE_INIT = (1 << 3),
};
enum {
typedef enum eV3D_OpEvent {
VIEW_PASS = 0,
VIEW_APPLY,
VIEW_CONFIRM,
/** Only supported by some viewport operators. */
VIEW_CANCEL,
};
} eV3D_OpEvent;
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
enum {
@ -58,7 +71,7 @@ enum {
VIEWROT_MODAL_SWITCH_ROTATE = 6,
};
enum eViewOpsFlag {
typedef enum eViewOpsFlag {
VIEWOPS_FLAG_NONE = 0,
/** When enabled, rotate around the selection. */
VIEWOPS_FLAG_ORBIT_SELECT = (1 << 0),
@ -72,8 +85,10 @@ enum eViewOpsFlag {
VIEWOPS_FLAG_PERSP_ENSURE = (1 << 2),
/** When set, ignore any options that depend on initial cursor location. */
VIEWOPS_FLAG_USE_MOUSE_INIT = (1 << 3),
};
ENUM_OPERATORS(eViewOpsFlag, VIEWOPS_FLAG_USE_MOUSE_INIT);
VIEWOPS_FLAG_ZOOM_TO_MOUSE = (1 << 4),
} eViewOpsFlag;
ENUM_OPERATORS(eViewOpsFlag, VIEWOPS_FLAG_ZOOM_TO_MOUSE);
/** Generic View Operator Custom-Data */
typedef struct ViewOpsData {
@ -146,6 +161,9 @@ typedef struct ViewOpsData {
float viewquat[4];
} curr;
eV3D_OpMode nav_type;
eViewOpsFlag viewops_flag;
float reverse;
bool axis_snap; /* view rotate only */
@ -165,13 +183,22 @@ typedef struct ViewOpsData {
/* view3d_navigate.cc */
/**
* Navigation operators that share the `ViewOpsData` utility.
*/
const char *viewops_operator_idname_get(eV3D_OpMode nav_type);
bool view3d_location_poll(struct bContext *C);
bool view3d_rotation_poll(struct bContext *C);
bool view3d_zoom_or_dolly_poll(struct bContext *C);
int view3d_navigate_invoke_impl(bContext *C,
wmOperator *op,
const wmEvent *event,
const eV3D_OpMode nav_type);
int view3d_navigate_modal_fn(bContext *C, wmOperator *op, const wmEvent *event);
void view3d_navigate_cancel_fn(struct bContext *C, struct wmOperator *op);
enum eViewOpsFlag viewops_flag_from_prefs(void);
void calctrackballvec(const struct rcti *rect, const int event_xy[2], float r_dir[3]);
void viewmove_apply(ViewOpsData *vod, int x, int y);
void viewmove_apply_reset(ViewOpsData *vod);
@ -193,9 +220,10 @@ void viewops_data_free(struct bContext *C, ViewOpsData *vod);
/**
* Allocate, fill in context pointers and calculate the values for #ViewOpsData
*/
ViewOpsData *viewops_data_create(struct bContext *C,
const struct wmEvent *event,
enum eViewOpsFlag viewops_flag);
ViewOpsData *viewops_data_create(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
void VIEW3D_OT_view_selected(struct wmOperatorType *ot);
@ -219,6 +247,11 @@ void VIEW3D_OT_fly(struct wmOperatorType *ot);
/* view3d_navigate_move.c */
int viewmove_modal_impl(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2]);
int viewmove_invoke_impl(ViewOpsData *vod, const wmEvent *event);
void viewmove_modal_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_move(struct wmOperatorType *ot);
@ -249,6 +282,11 @@ void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
/* view3d_navigate_rotate.c */
int viewrotate_modal_impl(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2]);
int viewrotate_invoke_impl(ViewOpsData *vod, const wmEvent *event);
void viewrotate_modal_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_rotate(struct wmOperatorType *ot);
@ -326,6 +364,11 @@ void VIEW3D_OT_walk(struct wmOperatorType *ot);
/* view3d_navigate_zoom.c */
int viewzoom_modal_impl(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2]);
int viewzoom_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event, PointerRNA *ptr);
void viewzoom_modal_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_zoom(struct wmOperatorType *ot);

View File

@ -246,11 +246,7 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
vod = op->customdata = viewops_data_create(
C,
event,
(viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
(use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
vod = op->customdata = viewops_data_create(C, event, V3D_OP_MODE_DOLLY, use_cursor_init);
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@ -314,7 +310,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
/* identifiers */
ot->name = "Dolly View";
ot->description = "Dolly in/out in the view";
ot->idname = "VIEW3D_OT_dolly";
ot->idname = viewops_operator_idname_get(V3D_OP_MODE_DOLLY);
/* api callbacks */
ot->invoke = viewdolly_invoke;

View File

@ -49,52 +49,17 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
}
static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
int viewmove_modal_impl(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2])
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
bool use_autokey = false;
int ret = OPERATOR_RUNNING_MODAL;
/* Execute the events. */
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case VIEW_MODAL_CONFIRM:
event_code = VIEW_CONFIRM;
break;
case VIEW_MODAL_CANCEL:
event_code = VIEW_CANCEL;
break;
case VIEWROT_MODAL_SWITCH_ZOOM:
WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL, event);
event_code = VIEW_CONFIRM;
break;
case VIEWROT_MODAL_SWITCH_ROTATE:
WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL, event);
event_code = VIEW_CONFIRM;
break;
}
}
else {
if (event->type == MOUSEMOVE) {
event_code = VIEW_APPLY;
}
else if (event->type == vod->init.event_type) {
if (event->val == KM_RELEASE) {
event_code = VIEW_CONFIRM;
}
}
else if (event->type == EVT_ESCKEY) {
if (event->val == KM_PRESS) {
event_code = VIEW_CANCEL;
}
}
}
switch (event_code) {
case VIEW_APPLY: {
viewmove_apply(vod, event->xy[0], event->xy[1]);
viewmove_apply(vod, xy[0], xy[1]);
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
use_autokey = true;
}
@ -111,66 +76,47 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
ret = OPERATOR_CANCELLED;
break;
}
case VIEW_PASS:
break;
}
if (use_autokey) {
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
}
if ((ret & OPERATOR_RUNNING_MODAL) == 0) {
if (ret & OPERATOR_FINISHED) {
ED_view3d_camera_lock_undo_push(op->type->name, vod->v3d, vod->rv3d, C);
}
viewops_data_free(C, op->customdata);
op->customdata = NULL;
}
return ret;
}
static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int viewmove_invoke_impl(ViewOpsData *vod, const wmEvent *event)
{
ViewOpsData *vod;
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
vod = op->customdata = viewops_data_create(
C,
event,
(viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
(use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
vod = op->customdata;
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
if (event->type == MOUSEPAN) {
/* invert it, trackpad scroll follows same principle as 2d windows this way */
viewmove_apply(
vod, 2 * event->xy[0] - event->prev_xy[0], 2 * event->xy[1] - event->prev_xy[1]);
viewops_data_free(C, op->customdata);
op->customdata = NULL;
eV3D_OpEvent event_code = event->type == MOUSEPAN ? VIEW_CONFIRM : VIEW_PASS;
if (event_code == VIEW_CONFIRM) {
/* Invert it, trackpad scroll follows same principle as 2d windows this way. */
int mx = 2 * event->xy[0] - event->prev_xy[0];
int my = 2 * event->xy[1] - event->prev_xy[1];
viewmove_apply(vod, mx, my);
return OPERATOR_FINISHED;
}
/* add temp handler */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_MOVE);
}
void VIEW3D_OT_move(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Pan View";
ot->description = "Move the view";
ot->idname = "VIEW3D_OT_move";
ot->idname = viewops_operator_idname_get(V3D_OP_MODE_MOVE);
/* api callbacks */
ot->invoke = viewmove_invoke;
ot->modal = viewmove_modal;
ot->modal = view3d_navigate_modal_fn;
ot->poll = view3d_location_poll;
ot->cancel = view3d_navigate_cancel_fn;

View File

@ -435,8 +435,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const wmNDOFMotionData *ndof = event->customdata;
vod = op->customdata = viewops_data_create(
C, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_DEPTH_NAVIGATE));
vod = op->customdata = viewops_data_create(C, event, V3D_OP_MODE_NDOF_ORBIT, false);
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@ -522,8 +521,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
const wmNDOFMotionData *ndof = event->customdata;
vod = op->customdata = viewops_data_create(
C, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_DEPTH_NAVIGATE));
vod = op->customdata = viewops_data_create(C, event, V3D_OP_MODE_NDOF_ORBIT_ZOOM, false);
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);

View File

@ -253,7 +253,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
else {
/* makes op->customdata */
vod = op->customdata = viewops_data_create(C, event, viewops_flag_from_prefs());
vod = op->customdata = viewops_data_create(C, event, V3D_OP_MODE_VIEW_ROLL, false);
vod->init.dial = BLI_dial_init((const float[2]){BLI_rcti_cent_x(&vod->region->winrct),
BLI_rcti_cent_y(&vod->region->winrct)},
FLT_EPSILON);
@ -287,7 +287,7 @@ void VIEW3D_OT_view_roll(wmOperatorType *ot)
/* identifiers */
ot->name = "View Roll";
ot->description = "Roll the view";
ot->idname = "VIEW3D_OT_view_roll";
ot->idname = viewops_operator_idname_get(V3D_OP_MODE_VIEW_ROLL);
/* api callbacks */
ot->invoke = viewroll_invoke;

View File

@ -293,60 +293,17 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
ED_region_tag_redraw(vod->region);
}
static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
int viewrotate_modal_impl(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2])
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
bool use_autokey = false;
int ret = OPERATOR_RUNNING_MODAL;
/* Execute the events. */
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case VIEW_MODAL_CONFIRM:
event_code = VIEW_CONFIRM;
break;
case VIEW_MODAL_CANCEL:
event_code = VIEW_CANCEL;
break;
case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
vod->axis_snap = true;
event_code = VIEW_APPLY;
break;
case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
vod->rv3d->persp = vod->init.persp_with_auto_persp_applied;
vod->axis_snap = false;
event_code = VIEW_APPLY;
break;
case VIEWROT_MODAL_SWITCH_ZOOM:
WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL, event);
event_code = VIEW_CONFIRM;
break;
case VIEWROT_MODAL_SWITCH_MOVE:
WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL, event);
event_code = VIEW_CONFIRM;
break;
}
}
else {
if (event->type == MOUSEMOVE) {
event_code = VIEW_APPLY;
}
else if (event->type == vod->init.event_type) {
if (event->val == KM_RELEASE) {
event_code = VIEW_CONFIRM;
}
}
else if (event->type == EVT_ESCKEY) {
if (event->val == KM_PRESS) {
event_code = VIEW_CANCEL;
}
}
}
switch (event_code) {
case VIEW_APPLY: {
viewrotate_apply(vod, event->xy);
viewrotate_apply(vod, xy);
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
use_autokey = true;
}
@ -376,84 +333,60 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
ret = OPERATOR_CANCELLED;
break;
}
case VIEW_PASS:
break;
}
if (use_autokey) {
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true);
}
if ((ret & OPERATOR_RUNNING_MODAL) == 0) {
if (ret & OPERATOR_FINISHED) {
ED_view3d_camera_lock_undo_push(op->type->name, vod->v3d, vod->rv3d, C);
}
viewops_data_free(C, op->customdata);
op->customdata = NULL;
}
return ret;
}
static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int viewrotate_invoke_impl(ViewOpsData *vod, const wmEvent *event)
{
ViewOpsData *vod;
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
/* makes op->customdata */
vod = op->customdata = viewops_data_create(
C,
event,
viewops_flag_from_prefs() | VIEWOPS_FLAG_PERSP_ENSURE |
(use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
if (vod->use_dyn_ofs && (vod->rv3d->is_persp == false)) {
vod->use_dyn_ofs_ortho_correction = true;
}
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
eV3D_OpEvent event_code = ELEM(event->type, MOUSEROTATE, MOUSEPAN) ? VIEW_CONFIRM : VIEW_PASS;
if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
/* Rotate direction we keep always same */
int event_xy[2];
if (event_code == VIEW_CONFIRM) {
/* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
const bool is_inverted = (event->flag & WM_EVENT_SCROLL_INVERT) &&
(event->type != MOUSEROTATE);
if (event->type == MOUSEPAN) {
if (event->flag & WM_EVENT_SCROLL_INVERT) {
event_xy[0] = 2 * event->xy[0] - event->prev_xy[0];
event_xy[1] = 2 * event->xy[1] - event->prev_xy[1];
}
else {
copy_v2_v2_int(event_xy, event->prev_xy);
}
int m_xy[2];
if (is_inverted) {
m_xy[0] = 2 * event->xy[0] - event->prev_xy[0];
m_xy[1] = 2 * event->xy[1] - event->prev_xy[1];
}
else {
/* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
copy_v2_v2_int(event_xy, event->prev_xy);
copy_v2_v2_int(m_xy, event->prev_xy);
}
viewrotate_apply(vod, event_xy);
viewops_data_free(C, op->customdata);
op->customdata = NULL;
viewrotate_apply(vod, m_xy);
return OPERATOR_FINISHED;
}
/* add temp handler */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_ROTATE);
}
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Rotate View";
ot->description = "Rotate the view";
ot->idname = "VIEW3D_OT_rotate";
ot->idname = viewops_operator_idname_get(V3D_OP_MODE_ROTATE);
/* api callbacks */
ot->invoke = viewrotate_invoke;
ot->modal = viewrotate_modal;
ot->modal = view3d_navigate_modal_fn;
ot->poll = view3d_rotation_poll;
ot->cancel = view3d_navigate_cancel_fn;

View File

@ -331,9 +331,10 @@ static void viewzoom_apply_3d(ViewOpsData *vod,
static void viewzoom_apply(ViewOpsData *vod,
const int xy[2],
const eViewZoom_Style viewzoom,
const bool zoom_invert,
const bool zoom_to_pos)
const bool zoom_invert)
{
const bool zoom_to_pos = (vod->viewops_flag & VIEWOPS_FLAG_ZOOM_TO_MOUSE) != 0;
if ((vod->rv3d->persp == RV3D_CAMOB) &&
(vod->rv3d->is_persp && ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) == 0) {
viewzoom_apply_camera(vod, xy, viewzoom, zoom_invert, zoom_to_pos);
@ -343,62 +344,17 @@ static void viewzoom_apply(ViewOpsData *vod,
}
}
static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
int viewzoom_modal_impl(bContext *C,
ViewOpsData *vod,
const eV3D_OpEvent event_code,
const int xy[2])
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
bool use_autokey = false;
int ret = OPERATOR_RUNNING_MODAL;
/* Execute the events. */
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case VIEW_MODAL_CONFIRM:
event_code = VIEW_CONFIRM;
break;
case VIEW_MODAL_CANCEL:
event_code = VIEW_CANCEL;
break;
case VIEWROT_MODAL_SWITCH_MOVE:
WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL, event);
event_code = VIEW_CONFIRM;
break;
case VIEWROT_MODAL_SWITCH_ROTATE:
WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL, event);
event_code = VIEW_CONFIRM;
break;
}
}
else {
if (event->type == MOUSEMOVE) {
event_code = VIEW_APPLY;
}
else if (event->type == TIMER) {
if (event->customdata == vod->timer) {
/* Continuous zoom. */
event_code = VIEW_APPLY;
}
}
else if (event->type == vod->init.event_type) {
if (event->val == KM_RELEASE) {
event_code = VIEW_CONFIRM;
}
}
else if (event->type == EVT_ESCKEY) {
if (event->val == KM_PRESS) {
event_code = VIEW_CANCEL;
}
}
}
switch (event_code) {
case VIEW_APPLY: {
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
viewzoom_apply(vod,
event->xy,
(eViewZoom_Style)U.viewzoom,
(U.uiflag & USER_ZOOM_INVERT) != 0,
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
viewzoom_apply(vod, xy, (eViewZoom_Style)U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0);
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
use_autokey = true;
}
@ -423,64 +379,33 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
ret = OPERATOR_CANCELLED;
break;
}
case VIEW_PASS:
break;
}
if (use_autokey) {
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
}
if ((ret & OPERATOR_RUNNING_MODAL) == 0) {
if (ret & OPERATOR_FINISHED) {
ED_view3d_camera_lock_undo_push(op->type->name, vod->v3d, vod->rv3d, C);
}
viewops_data_free(C, op->customdata);
op->customdata = NULL;
}
return ret;
}
static int viewzoom_exec(bContext *C, wmOperator *op)
static void view_zoom_apply_step(bContext *C,
Depsgraph *depsgraph,
Scene *scene,
ScrArea *area,
ARegion *region,
const int delta,
const int zoom_xy[2])
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d;
RegionView3D *rv3d;
ScrArea *area;
ARegion *region;
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
bool use_cam_zoom;
float dist_range[2];
const int delta = RNA_int_get(op->ptr, "delta");
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
if (op->customdata) {
ViewOpsData *vod = op->customdata;
area = vod->area;
region = vod->region;
}
else {
area = CTX_wm_area(C);
region = CTX_wm_region(C);
}
v3d = area->spacedata.first;
rv3d = region->regiondata;
use_cam_zoom = (rv3d->persp == RV3D_CAMOB) &&
!(rv3d->is_persp && ED_view3d_camera_lock_check(v3d, rv3d));
int zoom_xy_buf[2];
const int *zoom_xy = NULL;
if (use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
zoom_xy_buf[0] = RNA_struct_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") :
region->winx / 2;
zoom_xy_buf[1] = RNA_struct_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") :
region->winy / 2;
zoom_xy = zoom_xy_buf;
}
ED_view3d_dist_range_get(v3d, dist_range);
if (delta < 0) {
@ -514,73 +439,94 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true);
ED_region_tag_redraw(region);
}
static int viewzoom_exec(bContext *C, wmOperator *op)
{
BLI_assert(op->customdata == NULL);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
const int delta = RNA_int_get(op->ptr, "delta");
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
int zoom_xy_buf[2];
const int *zoom_xy = NULL;
const bool do_zoom_to_mouse_pos = (use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS));
if (do_zoom_to_mouse_pos) {
zoom_xy_buf[0] = RNA_struct_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") :
region->winx / 2;
zoom_xy_buf[1] = RNA_struct_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") :
region->winy / 2;
zoom_xy = zoom_xy_buf;
}
view_zoom_apply_step(C, depsgraph, scene, area, region, delta, zoom_xy);
ED_view3d_camera_lock_undo_grouped_push(op->type->name, v3d, rv3d, C);
viewops_data_free(C, op->customdata);
op->customdata = NULL;
return OPERATOR_FINISHED;
}
int viewzoom_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event, PointerRNA *ptr)
{
eV3D_OpEvent event_code = ELEM(event->type, MOUSEZOOM, MOUSEPAN) ? VIEW_CONFIRM : VIEW_PASS;
if (event_code == VIEW_CONFIRM) {
int xy[2];
PropertyRNA *prop;
prop = RNA_struct_find_property(ptr, "mx");
xy[0] = RNA_property_is_set(ptr, prop) ? RNA_property_int_get(ptr, prop) : event->xy[0];
prop = RNA_struct_find_property(ptr, "my");
xy[1] = RNA_property_is_set(ptr, prop) ? RNA_property_int_get(ptr, prop) : event->xy[1];
const int delta = RNA_int_get(ptr, "delta");
if (delta) {
const bool do_zoom_to_mouse_pos = (vod->viewops_flag & VIEWOPS_FLAG_ZOOM_TO_MOUSE) != 0;
view_zoom_apply_step(C,
vod->depsgraph,
vod->scene,
vod->area,
vod->region,
delta,
do_zoom_to_mouse_pos ? xy : NULL);
return OPERATOR_FINISHED;
}
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->init.event_xy[0] = vod->prev.event_xy[0] = xy[0];
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + xy[0] -
event->prev_xy[0];
}
viewzoom_apply(vod, event->prev_xy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
return OPERATOR_FINISHED;
}
if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vod->prev.time = PIL_check_seconds_timer();
}
return OPERATOR_RUNNING_MODAL;
}
/* viewdolly_invoke() copied this function, changes here may apply there */
static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
vod = op->customdata = viewops_data_create(
C,
event,
(viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
(use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
/* if one or the other zoom position aren't set, set from event */
if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
RNA_int_set(op->ptr, "mx", event->xy[0]);
RNA_int_set(op->ptr, "my", event->xy[1]);
}
if (RNA_struct_property_is_set(op->ptr, "delta")) {
viewzoom_exec(C, op);
}
else {
if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) {
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->init.event_xy[0] = vod->prev.event_xy[0] = event->xy[0];
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->init.event_xy[1] = vod->prev.event_xy[1] = vod->init.event_xy[1] + event->xy[0] -
event->prev_xy[0];
}
viewzoom_apply(vod,
event->prev_xy,
USER_ZOOM_DOLLY,
(U.uiflag & USER_ZOOM_INVERT) != 0,
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
viewops_data_free(C, op->customdata);
op->customdata = NULL;
return OPERATOR_FINISHED;
}
if (U.viewzoom == USER_ZOOM_CONTINUE) {
/* needs a timer to continue redrawing */
vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
vod->prev.time = PIL_check_seconds_timer();
}
/* add temp handler */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_FINISHED;
return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_ZOOM);
}
void VIEW3D_OT_zoom(wmOperatorType *ot)
@ -588,12 +534,12 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
/* identifiers */
ot->name = "Zoom View";
ot->description = "Zoom in/out in the view";
ot->idname = "VIEW3D_OT_zoom";
ot->idname = viewops_operator_idname_get(V3D_OP_MODE_ZOOM);
/* api callbacks */
ot->invoke = viewzoom_invoke;
ot->exec = viewzoom_exec;
ot->modal = viewzoom_modal;
ot->modal = view3d_navigate_modal_fn;
ot->poll = view3d_zoom_or_dolly_poll;
ot->cancel = view3d_navigate_cancel_fn;