Overwrite (or delete) interactor event button press

Hi,

I am using vtkRenderWindowInteractor as an interactor with a onMiddleButtonPress defined at runtime. I’m trying to implement a feature that overwrites at one point the existing onMiddleButtonPress callback with a new one.

Defining the 2nd and new callback function this way leads to an unexpected behavior where both of them are triggered one after another:

renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  // code of the new callback function should do
})

There are bunch of undocumented methods in the documentation that might do what I am looking for

It is important to return a value VOID or ABORT in your callback. If you do not return ABORT, then ALL callbacks will be triggered.

Makes sense. Perhaps that could be added to the documentation.

And by returning a value VOID or ABORT, does this mean returning it when trying to overwrite the callback?
Would it be something like:

renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  return void(0);
})

Perhaps that could be added to the documentation

Feel free to make a PR that improves the documentation.

renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  return void(0);
})

It is more like:

import { EVENT_ABORT, VOID } from './macros';
...
renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  return EVENT_ABORT;
})

Oh, I see. I was not aware of the existence of these macros.

I tried EVENT_ABORT and it works. However, it doesn’t overwrite the previous callback, but blocks any further callback from triggering.

My goal is to alternate between two different callbacks depending on a boolean variable.
An example would be:
when const choice = false

renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  console.log("This callback is triggered when `choice` == false")
})

or when const choice = true

renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  console.log("This callback is triggered when `choice` == true")
})

Sorry for not explaining my goal in a clear way earlier.

2 options:

  1. you keep calling both callbacks
renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  if (!choice) {
    console.log("This callback is triggered when `choice` == false")
    return EVENT_ABORT;
  }
  return VOID;
})
renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
  if (choice) {
    console.log("This callback is triggered when `choice` == true")
    return EVENT_ABORT;
  }
  return VOID;
})
  1. you unsubscribe when changing choice:
setChoice(newChoice) {
  if (old) {
   old.unsubscribe();
  }
  if (newChoice) {
    old = renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
      console.log("This callback is triggered when `choice` == true")
      return EVENT_ABORT;
    });
  } else {
    old = renderWindow.getInteractor().onMiddleButtonPress( (calldata: any) => {
      console.log("This callback is triggered when `choice` == false")
      return EVENT_ABORT;
    });
 }
 choice = newChoice;
})

Initially, before initiating this post, I went for the first option, but for some reasons, it didn’t play well with React.useState hook (basically, updated state variable couldn’t be retrieved inside of the callback). I’m unsure if this problem is related to my project. I’ll try to create a minimal sandbox trying to replicate the problem I am having.

Option 2 solved my problem for now. Thank you!

Hello,

Getting back with the CodeSandbox demonstrating the unexpected behavior I am having.

Basically, what I am trying to do is to combine a pointPicker callback and react.useState. The idea to update the state depending on whether a point was picked or not.
Notice how the state gets updated correctly and triggers the useEffect, but this is not reflected when trying to access the state variable inside of the callback. Somehow, the default value is always returned

See CodeSandbox

This is a react hook issue, isMeasuring in the callback never gets updated.