Cleanup: Convert 'ViewOpsData' functions into methods

This commit refactors the code by converting the data manipulation
functions of 'ViewOpsData' into methods.

This change adopts a more object-oriented approach, resulting in
improved code organization and enhanced reusability.

Pull Request: https://projects.blender.org/blender/blender/pulls/110209
This commit is contained in:
Germano Cavalcante 2023-07-24 13:41:47 +02:00 committed by Germano Cavalcante
parent 546892bdbc
commit 15a4609ece
7 changed files with 335 additions and 343 deletions

View File

@ -46,14 +46,8 @@
#include "view3d_navigate.hh" /* 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);
static eViewOpsFlag viewops_flag_from_prefs();
const char *viewops_operator_idname_get(eV3D_OpMode nav_type)
{
@ -87,6 +81,308 @@ const char *viewops_operator_idname_get(eV3D_OpMode nav_type)
return nullptr;
}
/* -------------------------------------------------------------------- */
/** \name ViewOpsData definition
* \{ */
void ViewOpsData::init_context(bContext *C)
{
/* Store data. */
this->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
this->scene = CTX_data_scene(C);
this->area = CTX_wm_area(C);
this->region = CTX_wm_region(C);
this->v3d = static_cast<View3D *>(this->area->spacedata.first);
this->rv3d = static_cast<RegionView3D *>(this->region->regiondata);
}
void ViewOpsData::state_backup()
{
copy_v3_v3(this->init.ofs, rv3d->ofs);
copy_v3_v3(this->init.ofs_lock, rv3d->ofs_lock);
this->init.camdx = rv3d->camdx;
this->init.camdy = rv3d->camdy;
this->init.camzoom = rv3d->camzoom;
this->init.dist = rv3d->dist;
copy_qt_qt(this->init.quat, rv3d->viewquat);
this->init.persp = rv3d->persp;
this->init.view = rv3d->view;
this->init.view_axis_roll = rv3d->view_axis_roll;
}
void ViewOpsData::state_restore()
{
/* DOLLY, MOVE, ROTATE and ZOOM. */
{
/* For Move this only changes when offset is not locked. */
/* For Rotate this only changes when rotating around objects or last-brush. */
/* For Zoom this only changes when zooming to mouse position. */
/* Note this does not remove auto-keys on locked cameras. */
copy_v3_v3(this->rv3d->ofs, this->init.ofs);
}
/* MOVE and ZOOM. */
{
/* For Move this only changes when offset is not locked. */
/* For Zoom this only changes when zooming to mouse position in camera view. */
this->rv3d->camdx = this->init.camdx;
this->rv3d->camdy = this->init.camdy;
}
/* MOVE. */
{
if ((this->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(this->v3d, this->rv3d)) {
// this->rv3d->camdx = this->init.camdx;
// this->rv3d->camdy = this->init.camdy;
}
else if (ED_view3d_offset_lock_check(this->v3d, this->rv3d)) {
copy_v2_v2(this->rv3d->ofs_lock, this->init.ofs_lock);
}
else {
// copy_v3_v3(vod->rv3d->ofs, vod->init.ofs);
if (RV3D_LOCK_FLAGS(this->rv3d) & RV3D_BOXVIEW) {
view3d_boxview_sync(this->area, this->region);
}
}
}
/* ZOOM. */
{
this->rv3d->camzoom = this->init.camzoom;
}
/* ROTATE and ZOOM. */
{
/**
* For Rotate this only changes when orbiting from a camera view.
* In this case the `dist` is calculated based on the camera relative to the `ofs`.
*/
/* Note this does not remove auto-keys on locked cameras. */
this->rv3d->dist = this->init.dist;
}
/* ROLL and ROTATE. */
{
/* Note this does not remove auto-keys on locked cameras. */
copy_qt_qt(this->rv3d->viewquat, this->init.quat);
}
/* ROTATE. */
{
this->rv3d->persp = this->init.persp;
this->rv3d->view = this->init.view;
this->rv3d->view_axis_roll = this->init.view_axis_roll;
}
/* NOTE: there is no need to restore "last" values (as set by #ED_view3d_lastview_store). */
ED_view3d_camera_lock_sync(this->depsgraph, this->v3d, this->rv3d);
}
void ViewOpsData::init_navigation(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init)
{
eViewOpsFlag viewops_flag = viewops_flag_from_prefs();
bool calc_rv3d_dist = true;
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_PAN:
viewops_flag &= ~VIEWOPS_FLAG_ORBIT_SELECT;
[[fallthrough]];
case V3D_OP_MODE_NDOF_ORBIT:
case V3D_OP_MODE_NDOF_ORBIT_ZOOM:
case V3D_OP_MODE_NDOF_ALL:
viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
calc_rv3d_dist = false;
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_ZOOM_TO_MOUSE);
}
/* Set the view from the camera, if view locking is enabled.
* we may want to make this optional but for now its needed always. */
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, calc_rv3d_dist);
this->state_backup();
if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
wmWindow *win = CTX_wm_window(C);
const bool use_depth_last = ED_view3d_autodist_last_check(win, event);
if (use_depth_last) {
this->use_dyn_ofs = ED_view3d_autodist_last_get(win, this->dyn_ofs);
}
else {
float fallback_depth_pt[3];
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
this->use_dyn_ofs = ED_view3d_autodist(
depsgraph, region, v3d, event->mval, this->dyn_ofs, true, fallback_depth_pt);
ED_view3d_autodist_last_set(win, event, this->dyn_ofs, this->use_dyn_ofs);
}
}
else {
wmWindow *win = CTX_wm_window(C);
ED_view3d_autodist_last_clear(win);
this->use_dyn_ofs = false;
}
if (viewops_flag & VIEWOPS_FLAG_ORBIT_SELECT) {
float ofs[3];
if (view3d_orbit_calc_center(C, ofs) || (this->use_dyn_ofs == false)) {
this->use_dyn_ofs = true;
negate_v3_v3(this->dyn_ofs, ofs);
viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
}
}
if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) {
if (ED_view3d_persp_ensure(depsgraph, this->v3d, this->region)) {
/* If we're switching from camera view to the perspective one,
* need to tag viewport update, so camera view and borders are properly updated. */
ED_region_tag_redraw(this->region);
}
}
/* After #VIEWOPS_FLAG_PERSP_ENSURE. */
if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
if (this->use_dyn_ofs) {
if (rv3d->is_persp) {
float my_origin[3]; /* Original #RegionView3D.ofs. */
float my_pivot[3]; /* View pivot. */
float dvec[3];
/* locals for dist correction */
float mat[3][3];
float upvec[3];
negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
/* Set the dist value to be the distance from this 3d point this means you'll
* always be able to zoom into it and panning won't go bad when dist was zero. */
/* remove dist value */
upvec[0] = upvec[1] = 0;
upvec[2] = rv3d->dist;
copy_m3_m4(mat, rv3d->viewinv);
mul_m3_v3(mat, upvec);
sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
negate_v3(my_pivot); /* ofs is flipped */
/* find a new ofs value that is along the view axis
* (rather than the mouse location) */
closest_to_line_v3(dvec, this->dyn_ofs, my_pivot, my_origin);
rv3d->dist = len_v3v3(my_pivot, dvec);
negate_v3_v3(rv3d->ofs, dvec);
}
else {
const float mval_region_mid[2] = {float(region->winx) / 2.0f, float(region->winy) / 2.0f};
ED_view3d_win_to_3d(v3d, region, this->dyn_ofs, mval_region_mid, rv3d->ofs);
negate_v3(rv3d->ofs);
}
negate_v3(this->dyn_ofs);
/* XXX: The initial state captured by #ViewOpsData::state_backup is being modified here.
* This causes the state when canceling a navigation operation to not be fully restored. */
this->init.dist = rv3d->dist;
copy_v3_v3(this->init.ofs, rv3d->ofs);
}
}
this->init.persp_with_auto_persp_applied = rv3d->persp;
this->init.event_type = event->type;
copy_v2_v2_int(this->init.event_xy, event->xy);
copy_v2_v2_int(this->prev.event_xy, event->xy);
if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) {
zero_v2_int(this->init.event_xy_offset);
}
else {
/* Simulate the event starting in the middle of the region. */
this->init.event_xy_offset[0] = BLI_rcti_cent_x(&this->region->winrct) - event->xy[0];
this->init.event_xy_offset[1] = BLI_rcti_cent_y(&this->region->winrct) - event->xy[1];
}
/* For dolly */
const float mval[2] = {float(event->mval[0]), float(event->mval[1])};
ED_view3d_win_to_vector(region, mval, this->init.mousevec);
{
int event_xy_offset[2];
add_v2_v2v2_int(event_xy_offset, event->xy, this->init.event_xy_offset);
/* For rotation with trackball rotation. */
calctrackballvec(&region->winrct, event_xy_offset, this->init.trackvec);
}
{
float tvec[3];
negate_v3_v3(tvec, rv3d->ofs);
this->init.zfac = ED_view3d_calc_zfac(rv3d, tvec);
}
copy_qt_qt(this->curr.viewquat, rv3d->viewquat);
this->reverse = 1.0f;
if (rv3d->persmat[2][1] < 0.0f) {
this->reverse = -1.0f;
}
this->nav_type = nav_type;
this->viewops_flag = viewops_flag;
/* Default. */
this->use_dyn_ofs_ortho_correction = false;
rv3d->rflag |= RV3D_NAVIGATING;
}
void ViewOpsData::end_navigation(bContext *C)
{
this->rv3d->rflag &= ~RV3D_NAVIGATING;
if (this->timer) {
WM_event_timer_remove(CTX_wm_manager(C), this->timer->win, this->timer);
}
MEM_SAFE_FREE(this->init.dial);
/* Need to redraw because drawing code uses RV3D_NAVIGATING to draw
* faster while navigation operator runs. */
ED_region_tag_redraw(this->region);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Generic Operator Callback Utils
* \{ */
@ -180,7 +476,7 @@ static int view3d_navigation_invoke_generic(bContext *C,
use_cursor_init = RNA_property_boolean_get(ptr, prop);
}
viewops_data_init_navigation(C, event, nav_type, use_cursor_init, vod);
vod->init_navigation(C, event, nav_type, use_cursor_init);
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
switch (nav_type) {
@ -213,8 +509,8 @@ int view3d_navigate_invoke_impl(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type)
{
ViewOpsData *vod = MEM_cnew<ViewOpsData>(__func__);
viewops_data_init_context(C, vod);
ViewOpsData *vod = new ViewOpsData();
vod->init_context(C);
int ret = view3d_navigation_invoke_generic(C, vod, event, op->ptr, nav_type);
op->customdata = (void *)vod;
@ -259,7 +555,7 @@ int view3d_navigate_modal_fn(bContext *C, wmOperator *op, const wmEvent *event)
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);
vod->end_navigation(C);
return view3d_navigation_invoke_generic(C, vod, event, op->ptr, vod->nav_type);
}
@ -531,339 +827,24 @@ static eViewOpsFlag viewops_flag_from_prefs()
return flag;
}
static void viewops_data_init_context(bContext *C, ViewOpsData *vod)
{
/* Store data. */
vod->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
vod->scene = CTX_data_scene(C);
vod->area = CTX_wm_area(C);
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_state_backup(ViewOpsData *vod, const bool calc_dist)
{
Depsgraph *depsgraph = vod->depsgraph;
View3D *v3d = vod->v3d;
RegionView3D *rv3d = vod->rv3d;
/* Set the view from the camera, if view locking is enabled.
* we may want to make this optional but for now its needed always.
* NOTE: This changes the value of `rv3d->dist`. */
ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, calc_dist);
copy_v3_v3(vod->init.ofs, rv3d->ofs);
copy_v3_v3(vod->init.ofs_lock, rv3d->ofs_lock);
vod->init.camdx = rv3d->camdx;
vod->init.camdy = rv3d->camdy;
vod->init.camzoom = rv3d->camzoom;
vod->init.dist = rv3d->dist;
copy_qt_qt(vod->init.quat, rv3d->viewquat);
vod->init.persp = rv3d->persp;
vod->init.view = rv3d->view;
vod->init.view_axis_roll = rv3d->view_axis_roll;
}
void viewops_data_state_restore(ViewOpsData *vod)
{
/* DOLLY, MOVE, ROTATE and ZOOM. */
{
/* For Move this only changes when offset is not locked. */
/* For Rotate this only changes when rotating around objects or last-brush. */
/* For Zoom this only changes when zooming to mouse position. */
/* Note this does not remove auto-keys on locked cameras. */
copy_v3_v3(vod->rv3d->ofs, vod->init.ofs);
}
/* MOVE and ZOOM. */
{
/* For Move this only changes when offset is not locked. */
/* For Zoom this only changes when zooming to mouse position in camera view. */
vod->rv3d->camdx = vod->init.camdx;
vod->rv3d->camdy = vod->init.camdy;
}
/* MOVE. */
{
if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
// vod->rv3d->camdx = vod->init.camdx;
// vod->rv3d->camdy = vod->init.camdy;
}
else if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
copy_v2_v2(vod->rv3d->ofs_lock, vod->init.ofs_lock);
}
else {
// copy_v3_v3(vod->rv3d->ofs, vod->init.ofs);
if (RV3D_LOCK_FLAGS(vod->rv3d) & RV3D_BOXVIEW) {
view3d_boxview_sync(vod->area, vod->region);
}
}
}
/* ZOOM. */
{
vod->rv3d->camzoom = vod->init.camzoom;
}
/* ROTATE and ZOOM. */
{
/**
* For Rotate this only changes when orbiting from a camera view.
* In this case the `dist` is calculated based on the camera relative to the `ofs`.
*/
/* Note this does not remove auto-keys on locked cameras. */
vod->rv3d->dist = vod->init.dist;
}
/* ROLL and ROTATE. */
{
/* Note this does not remove auto-keys on locked cameras. */
copy_qt_qt(vod->rv3d->viewquat, vod->init.quat);
}
/* ROTATE. */
{
vod->rv3d->persp = vod->init.persp;
vod->rv3d->view = vod->init.view;
vod->rv3d->view_axis_roll = vod->init.view_axis_roll;
}
/* NOTE: there is no need to restore "last" values (as set by #ED_view3d_lastview_store). */
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
}
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;
ARegion *region = vod->region;
View3D *v3d = vod->v3d;
RegionView3D *rv3d = vod->rv3d;
eViewOpsFlag viewops_flag = viewops_flag_from_prefs();
bool calc_rv3d_dist = true;
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_PAN:
viewops_flag &= ~VIEWOPS_FLAG_ORBIT_SELECT;
[[fallthrough]];
case V3D_OP_MODE_NDOF_ORBIT:
case V3D_OP_MODE_NDOF_ORBIT_ZOOM:
case V3D_OP_MODE_NDOF_ALL:
viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
calc_rv3d_dist = false;
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_ZOOM_TO_MOUSE);
}
/* we need the depth info before changing any viewport options */
if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
wmWindow *win = CTX_wm_window(C);
const bool use_depth_last = ED_view3d_autodist_last_check(win, event);
if (use_depth_last) {
vod->use_dyn_ofs = ED_view3d_autodist_last_get(win, vod->dyn_ofs);
}
else {
float fallback_depth_pt[3];
view3d_operator_needs_opengl(C); /* Needed for Z-buffer drawing. */
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
vod->use_dyn_ofs = ED_view3d_autodist(
depsgraph, vod->region, vod->v3d, event->mval, vod->dyn_ofs, true, fallback_depth_pt);
ED_view3d_autodist_last_set(win, event, vod->dyn_ofs, vod->use_dyn_ofs);
}
}
else {
wmWindow *win = CTX_wm_window(C);
ED_view3d_autodist_last_clear(win);
vod->use_dyn_ofs = false;
}
viewops_data_state_backup(vod, calc_rv3d_dist);
if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) {
if (ED_view3d_persp_ensure(depsgraph, vod->v3d, vod->region)) {
/* If we're switching from camera view to the perspective one,
* need to tag viewport update, so camera view and borders are properly updated. */
ED_region_tag_redraw(vod->region);
}
}
vod->init.persp_with_auto_persp_applied = rv3d->persp;
copy_v2_v2_int(vod->init.event_xy, event->xy);
copy_v2_v2_int(vod->prev.event_xy, event->xy);
if (viewops_flag & VIEWOPS_FLAG_USE_MOUSE_INIT) {
zero_v2_int(vod->init.event_xy_offset);
}
else {
/* Simulate the event starting in the middle of the region. */
vod->init.event_xy_offset[0] = BLI_rcti_cent_x(&vod->region->winrct) - event->xy[0];
vod->init.event_xy_offset[1] = BLI_rcti_cent_y(&vod->region->winrct) - event->xy[1];
}
vod->init.event_type = event->type;
copy_qt_qt(vod->curr.viewquat, rv3d->viewquat);
if (viewops_flag & VIEWOPS_FLAG_ORBIT_SELECT) {
float ofs[3];
if (view3d_orbit_calc_center(C, ofs) || (vod->use_dyn_ofs == false)) {
vod->use_dyn_ofs = true;
negate_v3_v3(vod->dyn_ofs, ofs);
viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE;
}
}
if (viewops_flag & VIEWOPS_FLAG_DEPTH_NAVIGATE) {
if (vod->use_dyn_ofs) {
if (rv3d->is_persp) {
float my_origin[3]; /* Original #RegionView3D.ofs. */
float my_pivot[3]; /* View pivot. */
float dvec[3];
/* locals for dist correction */
float mat[3][3];
float upvec[3];
negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
/* Set the dist value to be the distance from this 3d point this means you'll
* always be able to zoom into it and panning won't go bad when dist was zero. */
/* remove dist value */
upvec[0] = upvec[1] = 0;
upvec[2] = rv3d->dist;
copy_m3_m4(mat, rv3d->viewinv);
mul_m3_v3(mat, upvec);
sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
negate_v3(my_pivot); /* ofs is flipped */
/* find a new ofs value that is along the view axis
* (rather than the mouse location) */
closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
rv3d->dist = len_v3v3(my_pivot, dvec);
negate_v3_v3(rv3d->ofs, dvec);
}
else {
const float mval_region_mid[2] = {float(region->winx) / 2.0f, float(region->winy) / 2.0f};
ED_view3d_win_to_3d(v3d, region, vod->dyn_ofs, mval_region_mid, rv3d->ofs);
negate_v3(rv3d->ofs);
}
negate_v3(vod->dyn_ofs);
/* XXX: The initial state captured by #viewops_data_state_backup is being modified here.
* This causes the state when canceling a navigation operation to not be fully restored. */
vod->init.dist = rv3d->dist;
copy_v3_v3(vod->init.ofs, rv3d->ofs);
}
}
/* For dolly */
const float mval[2] = {float(event->mval[0]), float(event->mval[1])};
ED_view3d_win_to_vector(region, mval, vod->init.mousevec);
{
int event_xy_offset[2];
add_v2_v2v2_int(event_xy_offset, event->xy, vod->init.event_xy_offset);
/* For rotation with trackball rotation. */
calctrackballvec(&region->winrct, event_xy_offset, vod->init.trackvec);
}
{
float tvec[3];
negate_v3_v3(tvec, rv3d->ofs);
vod->init.zfac = ED_view3d_calc_zfac(rv3d, tvec);
}
vod->reverse = 1.0f;
if (rv3d->persmat[2][1] < 0.0f) {
vod->reverse = -1.0f;
}
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);
ViewOpsData *vod = new ViewOpsData();
vod->init_context(C);
vod->init_navigation(C, event, nav_type, use_cursor_init);
return vod;
}
static void viewops_data_end_navigation(bContext *C, ViewOpsData *vod)
{
ARegion *region;
if (vod) {
region = vod->region;
vod->rv3d->rflag &= ~RV3D_NAVIGATING;
if (vod->timer) {
WM_event_timer_remove(CTX_wm_manager(C), vod->timer->win, vod->timer);
}
MEM_SAFE_FREE(vod->init.dial);
}
else {
region = CTX_wm_region(C);
}
/* Need to redraw because drawing code uses RV3D_NAVIGATING to draw
* faster while navigation operator runs. */
ED_region_tag_redraw(region);
}
void viewops_data_free(bContext *C, ViewOpsData *vod)
{
viewops_data_end_navigation(C, vod);
if (vod) {
MEM_freeN(vod);
if (!vod) {
return;
}
vod->end_navigation(C);
delete vod;
}
/** \} */
@ -2060,7 +2041,7 @@ ViewOpsData *ED_view3d_navigation_init(bContext *C)
}
ViewOpsData *vod = MEM_cnew<ViewOpsData>(__func__);
viewops_data_init_context(C, vod);
vod->init_context(C);
vod->keymap = WM_keymap_find_all(CTX_wm_manager(C), "3D View", SPACE_VIEW3D, 0);
return vod;
@ -2123,7 +2104,7 @@ bool ED_view3d_navigation_do(bContext *C, ViewOpsData *vod, const wmEvent *event
const eV3D_OpEvent event_code = view3d_navigate_event(vod, event);
op_return = view3d_navigation_modal(C, vod, event_code, event->xy);
if (op_return != OPERATOR_RUNNING_MODAL) {
viewops_data_end_navigation(C, vod);
vod->end_navigation(C);
vod->is_modal_event = false;
}
}
@ -2148,7 +2129,7 @@ bool ED_view3d_navigation_do(bContext *C, ViewOpsData *vod, const wmEvent *event
vod->is_modal_event = true;
}
else {
viewops_data_end_navigation(C, vod);
vod->end_navigation(C);
/* Postpone the navigation confirmation to the next call.
* This avoids constant updating of the transform operation for example. */
vod->rv3d->rflag |= RV3D_NAVIGATING;

View File

@ -192,6 +192,19 @@ struct ViewOpsData {
/** Used for navigation on non view3d operators. */
wmKeyMap *keymap;
bool is_modal_event;
void init_context(bContext *C);
void state_backup();
void state_restore();
void init_navigation(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init);
void end_navigation(bContext *C);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("ViewOpsData")
#endif
};
/* view3d_navigate.cc */
@ -236,8 +249,6 @@ ViewOpsData *viewops_data_create(bContext *C,
const wmEvent *event,
const eV3D_OpMode nav_type,
const bool use_cursor_init);
void viewops_data_state_restore(ViewOpsData *vod);
void VIEW3D_OT_view_all(wmOperatorType *ot);
void VIEW3D_OT_view_selected(wmOperatorType *ot);
void VIEW3D_OT_view_center_cursor(wmOperatorType *ot);

View File

@ -163,7 +163,7 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
case VIEW_CANCEL: {
viewops_data_state_restore(vod);
vod->state_restore();
ret = OPERATOR_CANCELLED;
break;
}

View File

@ -73,7 +73,7 @@ int viewmove_modal_impl(bContext *C,
break;
}
case VIEW_CANCEL: {
viewops_data_state_restore(vod);
vod->state_restore();
ret = OPERATOR_CANCELLED;
break;
}

View File

@ -141,7 +141,7 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
case VIEW_CANCEL: {
viewops_data_state_restore(vod);
vod->state_restore();
ret = OPERATOR_CANCELLED;
break;
}

View File

@ -317,7 +317,7 @@ int viewrotate_modal_impl(bContext *C,
break;
}
case VIEW_CANCEL: {
viewops_data_state_restore(vod);
vod->state_restore();
ret = OPERATOR_CANCELLED;
break;
}

View File

@ -369,7 +369,7 @@ int viewzoom_modal_impl(bContext *C,
break;
}
case VIEW_CANCEL: {
viewops_data_state_restore(vod);
vod->state_restore();
ret = OPERATOR_CANCELLED;
break;
}