Transform: Simplify and specialize the handling of events

The `transformEvent` function is becoming increasingly complex due to
the inclusion of operation-specific code.

To improve this, remove the `handled` boolean and allow each
`TransModeInfo::handle_event_fn` to determine how to handle already
processed events.

Additionally, move some operation-specific logic to the operators file.

Note:
The `handled` boolean was added in aef307cf31 to fix a bug with the
custom events of the Edge and Vertex Slide operators;
This commit is contained in:
Germano Cavalcante
2024-10-05 22:11:07 +02:00
committed by Germano Cavalcante
parent ed1c708619
commit 6d5d3ce975
6 changed files with 71 additions and 87 deletions

View File

@@ -6,16 +6,9 @@
* \ingroup edtransform
*/
#include <cstdlib>
#include "MEM_guardedalloc.h"
#include "DNA_gpencil_legacy_types.h"
#include "DNA_screen_types.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_rect.h"
#include "BKE_context.hh"
#include "BKE_editmesh.hh"
@@ -39,7 +32,6 @@
#include "WM_api.hh"
#include "WM_message.hh"
#include "WM_types.hh"
#include "UI_interface_icons.hh"
#include "UI_resources.hh"
@@ -987,13 +979,11 @@ static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
/* Take the opportunity to update the gizmo. */
transform_gizmo_3d_model_from_constraint_and_mode_set(t);
}
t->redraw |= TREDRAW_HARD;
return true;
}
int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
{
bool handled = false;
bool is_navigating = t->vod ? ((RegionView3D *)t->region->regiondata)->rflag & RV3D_NAVIGATING :
false;
@@ -1002,7 +992,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event))
{
t->redraw |= TREDRAW_HARD;
handled = true;
}
else if (event->type == TIMER) {
if (ED_uvedit_live_unwrap_timer_check(static_cast<const wmTimer *>(event->customdata))) {
@@ -1024,7 +1013,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
/* Snapping mouse move events. */
t->redraw |= handleSnapping(t, event);
handled = true;
}
/* Handle modal keymap first. */
/* Enforce redraw of transform when modifiers are used. */
@@ -1033,13 +1021,11 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
case TFM_MODAL_CANCEL:
if (!(t->modifiers & MOD_EDIT_SNAP_SOURCE)) {
t->state = TRANS_CANCEL;
handled = true;
}
break;
case TFM_MODAL_CONFIRM:
if (!(t->modifiers & MOD_EDIT_SNAP_SOURCE)) {
t->state = TRANS_CONFIRM;
handled = true;
}
break;
case TFM_MODAL_TRANSLATE:
@@ -1061,7 +1047,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
t->flag ^= T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
}
@@ -1124,7 +1109,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
initSnapping(t, nullptr);
applyMouseInput(t, &t->mouse, t->mval, t->values);
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_SNAP_INV_ON:
@@ -1133,21 +1117,18 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
transform_snap_flag_from_modifiers_set(t);
t->redraw |= TREDRAW_HARD;
}
handled = true;
break;
case TFM_MODAL_SNAP_INV_OFF:
if (t->modifiers & MOD_SNAP_INVERT) {
t->modifiers &= ~MOD_SNAP_INVERT;
transform_snap_flag_from_modifiers_set(t);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_SNAP_TOGGLE:
t->modifiers ^= MOD_SNAP;
transform_snap_flag_from_modifiers_set(t);
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_AXIS_X:
case TFM_MODAL_AXIS_Y:
@@ -1156,25 +1137,22 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
case TFM_MODAL_PLANE_Y:
case TFM_MODAL_PLANE_Z:
if (transform_event_modal_constraint(t, event->val)) {
handled = true;
t->redraw |= TREDRAW_HARD;
}
break;
case TFM_MODAL_CONS_OFF:
if ((t->flag & T_NO_CONSTRAINT) == 0) {
stopConstraint(t);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_ADD_SNAP:
addSnapPoint(t);
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_REMOVE_SNAP:
removeSnapPoint(t);
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_PROPSIZE:
/* MOUSEPAN usage... */
@@ -1190,7 +1168,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
}
calculatePropRatio(t);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_PROPSIZE_UP:
@@ -1204,7 +1181,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
}
calculatePropRatio(t);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_PROPSIZE_DOWN:
@@ -1213,21 +1189,18 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
t->prop_size = max_ff(t->prop_size, T_PROP_SIZE_MIN);
calculatePropRatio(t);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_AUTOIK_LEN_INC:
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, 1);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_AUTOIK_LEN_DEC:
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, -1);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_INSERTOFS_TOGGLE_DIR:
@@ -1252,12 +1225,10 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
case TFM_MODAL_NODE_ATTACH_ON:
t->modifiers |= MOD_NODE_ATTACH;
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_NODE_ATTACH_OFF:
t->modifiers &= ~MOD_NODE_ATTACH;
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_AUTOCONSTRAINT:
@@ -1309,7 +1280,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
}
}
}
handled = true;
}
break;
case TFM_MODAL_PRECISION:
@@ -1330,8 +1300,10 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
}
break;
case TFM_MODAL_EDIT_SNAP_SOURCE_ON:
transform_mode_snap_source_init(t, nullptr);
t->redraw |= TREDRAW_HARD;
if (!(t->modifiers & MOD_EDIT_SNAP_SOURCE)) {
transform_mode_snap_source_init(t, nullptr);
t->redraw |= TREDRAW_HARD;
}
break;
default:
break;
@@ -1350,7 +1322,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
sort_trans_data_dist(t);
calculatePropRatio(t);
t->redraw = TREDRAW_HARD;
handled = true;
}
}
break;
@@ -1362,7 +1333,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
calculatePropRatio(t);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case EVT_PADPLUSKEY:
@@ -1373,7 +1343,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
}
calculatePropRatio(t);
t->redraw = TREDRAW_HARD;
handled = true;
}
break;
case EVT_PADMINUS:
@@ -1381,7 +1350,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f;
calculatePropRatio(t);
t->redraw = TREDRAW_HARD;
handled = true;
}
break;
case EVT_LEFTALTKEY:
@@ -1389,15 +1357,11 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D, SPACE_IMAGE)) {
t->flag |= T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
default:
break;
}
/* Snapping key events. */
t->redraw |= handleSnapping(t, event);
}
else if (event->val == KM_RELEASE) {
switch (event->type) {
@@ -1407,7 +1371,6 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D, SPACE_IMAGE)) {
t->flag &= ~T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
}
@@ -1419,32 +1382,25 @@ int transformEvent(TransInfo *t, wmOperator *op, const wmEvent *event)
}
/* Per transform event, if present. */
if (t->mode_info && t->mode_info->handle_event_fn &&
(!handled ||
/* Needed for vertex slide, see #38756. */
(event->type == MOUSEMOVE)))
{
if (t->mode_info && t->mode_info->handle_event_fn) {
t->redraw |= t->mode_info->handle_event_fn(t, event);
}
/* Try to init modal numinput now, if possible. */
if (!(handled || t->redraw) && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
if (!t->redraw && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
handleNumInput(t->context, &(t->num), event))
{
t->redraw |= TREDRAW_HARD;
handled = true;
}
if (t->redraw && !ISMOUSE_MOTION(event->type)) {
/* The status area is currently also tagged to update by the notifiers in
* `viewRedrawForce`. However, this may change in the future, and tagging
* the region twice doesn't add any overhead. */
WM_window_status_area_tag_redraw(CTX_wm_window(t->context));
}
WorkSpace *workspace = CTX_wm_workspace(t->context);
if (workspace) {
BKE_workspace_status_clear(workspace);
}
if (!is_navigating && (handled || t->redraw)) {
if (!is_navigating && t->redraw) {
return 0;
}
return OPERATOR_PASS_THROUGH;

View File

@@ -21,8 +21,6 @@
#include "ED_mesh.hh"
#include "ED_screen.hh"
#include "WM_api.hh"
#include "RNA_access.hh"
#include "UI_interface.hh"
@@ -92,6 +90,7 @@ struct EdgeSlideParams {
bool use_even;
bool flipped;
bool update_status_bar;
};
/**
@@ -410,11 +409,14 @@ static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const wmEvent *event)
EdgeSlideParams *slp = static_cast<EdgeSlideParams *>(t->custom.mode.data);
if (slp) {
bool is_event_handled = t->redraw && (event->type != MOUSEMOVE);
slp->update_status_bar |= is_event_handled;
switch (event->type) {
case EVT_EKEY:
if (event->val == KM_PRESS) {
slp->use_even = !slp->use_even;
calcEdgeSlideCustomPoints(t);
slp->update_status_bar = true;
return TREDRAW_HARD;
}
break;
@@ -422,6 +424,7 @@ static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const wmEvent *event)
if (event->val == KM_PRESS) {
slp->flipped = !slp->flipped;
calcEdgeSlideCustomPoints(t);
slp->update_status_bar = true;
return TREDRAW_HARD;
}
break;
@@ -430,6 +433,7 @@ static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const wmEvent *event)
if (event->val == KM_PRESS) {
t->flag ^= T_ALT_TRANSFORM;
calcEdgeSlideCustomPoints(t);
slp->update_status_bar = true;
return TREDRAW_HARD;
}
break;
@@ -809,20 +813,24 @@ static void applyEdgeSlide(TransInfo *t)
return;
}
WorkspaceStatus status(t->context);
status.opmodal(IFACE_("Confirm"), op->type, TFM_MODAL_CONFIRM);
status.opmodal(IFACE_("Cancel"), op->type, TFM_MODAL_CONFIRM);
status.opmodal(IFACE_("Snap"), op->type, TFM_MODAL_SNAP_TOGGLE, is_snap);
status.opmodal(IFACE_("Snap Invert"), op->type, TFM_MODAL_SNAP_INV_ON, is_snap_invert);
status.opmodal(IFACE_("Set Snap Base"), op->type, TFM_MODAL_EDIT_SNAP_SOURCE_ON);
status.opmodal(IFACE_("Move"), op->type, TFM_MODAL_TRANSLATE);
status.opmodal(IFACE_("Rotate"), op->type, TFM_MODAL_ROTATE);
status.opmodal(IFACE_("Resize"), op->type, TFM_MODAL_RESIZE);
status.opmodal(IFACE_("Precision Mode"), op->type, TFM_MODAL_PRECISION, is_precision);
status.item_bool(IFACE_("Clamp"), is_clamp, ICON_EVENT_C, ICON_EVENT_ALT);
status.item_bool(IFACE_("Even"), use_even, ICON_EVENT_E);
if (use_even) {
status.item_bool(IFACE_("Flipped"), flipped, ICON_EVENT_F);
if (slp->update_status_bar) {
slp->update_status_bar = false;
WorkspaceStatus status(t->context);
status.opmodal(IFACE_("Confirm"), op->type, TFM_MODAL_CONFIRM);
status.opmodal(IFACE_("Cancel"), op->type, TFM_MODAL_CANCEL);
status.opmodal(IFACE_("Snap"), op->type, TFM_MODAL_SNAP_TOGGLE, is_snap);
status.opmodal(IFACE_("Snap Invert"), op->type, TFM_MODAL_SNAP_INV_ON, is_snap_invert);
status.opmodal(IFACE_("Set Snap Base"), op->type, TFM_MODAL_EDIT_SNAP_SOURCE_ON);
status.opmodal(IFACE_("Move"), op->type, TFM_MODAL_TRANSLATE);
status.opmodal(IFACE_("Rotate"), op->type, TFM_MODAL_ROTATE);
status.opmodal(IFACE_("Resize"), op->type, TFM_MODAL_RESIZE);
status.opmodal(IFACE_("Precision Mode"), op->type, TFM_MODAL_PRECISION, is_precision);
status.item_bool(IFACE_("Clamp"), is_clamp, ICON_EVENT_C, ICON_EVENT_ALT);
status.item_bool(IFACE_("Even"), use_even, ICON_EVENT_E);
if (use_even) {
status.item_bool(IFACE_("Flipped"), flipped, ICON_EVENT_F);
}
}
}
@@ -883,6 +891,7 @@ static void initEdgeSlide_ex(TransInfo *t,
slp->flipped = !flipped;
}
slp->perc = 0.0f;
slp->update_status_bar = true;
if (!use_clamp) {
t->flag |= T_ALT_TRANSFORM;

View File

@@ -6,12 +6,9 @@
* \ingroup edtransform
*/
#include <cstdlib>
#include "DNA_gpencil_legacy_types.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_string.h"
#include "BLI_task.h"
@@ -19,8 +16,6 @@
#include "ED_screen.hh"
#include "WM_types.hh"
#include "UI_interface.hh"
#include "BLT_translation.hh"
@@ -173,6 +168,10 @@ static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
status = TREDRAW_HARD;
}
bool is_event_handled = (event->type != MOUSEMOVE) && (status || t->redraw);
bool update_status_bar = t->custom.mode.data || is_event_handled;
t->custom.mode.data = POINTER_FROM_INT(update_status_bar);
return status;
}
@@ -315,13 +314,18 @@ static void apply_shear(TransInfo *t)
ED_area_status_text(t->area, str);
WorkspaceStatus status(t->context);
status.item(IFACE_("Confirm"), ICON_MOUSE_LMB);
status.item(IFACE_("Cancel"), ICON_MOUSE_RMB);
status.item_bool({}, t->orient_axis_ortho == (t->orient_axis + 1) % 3, ICON_EVENT_X);
status.item_bool({}, t->orient_axis_ortho == (t->orient_axis + 2) % 3, ICON_EVENT_Y);
status.item(IFACE_("Shear Axis"), ICON_NONE);
status.item(IFACE_("Swap Axes"), ICON_MOUSE_MMB);
bool update_status_bar = POINTER_AS_INT(t->custom.mode.data);
if (update_status_bar) {
t->custom.mode.data = POINTER_FROM_INT(0);
WorkspaceStatus status(t->context);
status.item(IFACE_("Confirm"), ICON_MOUSE_LMB);
status.item(IFACE_("Cancel"), ICON_MOUSE_RMB);
status.item_bool({}, t->orient_axis_ortho == (t->orient_axis + 1) % 3, ICON_EVENT_X);
status.item_bool({}, t->orient_axis_ortho == (t->orient_axis + 2) % 3, ICON_EVENT_Y);
status.item(IFACE_("Shear Axis"), ICON_NONE);
status.item(IFACE_("Swap Axes"), ICON_MOUSE_MMB);
}
}
static void initShear(TransInfo *t, wmOperator * /*op*/)
@@ -344,6 +348,9 @@ static void initShear(TransInfo *t, wmOperator * /*op*/)
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_NONE; /* Don't think we have any unit here? */
bool update_status_bar = true;
t->custom.mode.data = POINTER_FROM_INT(update_status_bar);
transform_mode_default_modal_orientation_set(t, V3D_ORIENT_VIEW);
}

View File

@@ -75,6 +75,11 @@ static void transdata_elem_shrink_fatten_fn(void *__restrict iter_data_v,
static eRedrawFlag shrinkfatten_handleEvent(TransInfo *t, const wmEvent *event)
{
if (t->redraw) {
/* Event already handled. */
return TREDRAW_NOTHING;
}
BLI_assert(t->mode == TFM_SHRINKFATTEN);
const wmKeyMapItem *kmi = static_cast<const wmKeyMapItem *>(t->custom.mode.data);
if (kmi && event->type == kmi->type && event->val == kmi->val) {

View File

@@ -115,6 +115,11 @@ static void snapsource_confirm(TransInfo *t)
static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event)
{
if (t->redraw) {
/* Event already handled. */
return TREDRAW_NOTHING;
}
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case TFM_MODAL_CONFIRM:
@@ -125,9 +130,6 @@ static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event
BLI_assert(t->state != TRANS_CONFIRM);
}
else {
t->modifiers |= MOD_EDIT_SNAP_SOURCE;
}
break;
case TFM_MODAL_CANCEL:
snapsource_end(t);
@@ -252,6 +254,7 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator * /*op*/)
t->mouse.apply = nullptr;
t->mouse.post = nullptr;
t->mouse.use_virtual_mval = false;
t->modifiers |= MOD_EDIT_SNAP_SOURCE;
}
/** \} */

View File

@@ -211,8 +211,12 @@ static void freeVertSlideVerts(TransInfo * /*t*/,
static eRedrawFlag handleEventVertSlide(TransInfo *t, const wmEvent *event)
{
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
if (t->redraw && event->type != MOUSEMOVE) {
/* Event already handled. */
return TREDRAW_NOTHING;
}
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
if (slp) {
switch (event->type) {
case EVT_EKEY: