Page MenuHomePhabricator

Check responsibility of DisplayInteractor
Closed, ResolvedPublic

Description

Currently the DisplayInteractor : public EventStateMachine, public InteractionEventObserver is the current interactor to handle mouse events on render windows.
Providing different functions for specific mouse interactions (zoom, scroll, move, ...) it computes some values that are needed for a certain action (e.g. zoom factor by looking at the current and previous display coordinate).

We could move those calculations out of the DisplayInteractor to a base class and later extend this class with the current DisplayInteractor and a new DisplayInteractionBroadcaster.
Such a Broadcaster does not contain any call to modify the camera controller or slice navigation controller of a render window but sends events in order to inform others that a certain event has been triggered by the user (mouse event on render window).

Event Timeline

kalali triaged this task as Normal priority.Feb 15 2018, 6:54 PM
kalali created this task.

Here one can find an overview of the interaction concept in MITK: http://docs.mitk.org/nightly/DataInteractionPage.html (DataInteractor example: http://docs.mitk.org/nightly/Step10Page.html#SectionImplementationDataInteractor)

Interaction events are sent automatically by the user when interacting with the MITK workbench (Qt level). Such an even can be received by a QmitkRenderWindow. It is then transformed into an mitk::InteractionEvent (e.g. MousePressEvent) and added to the dispatcher of the underlying renderer for further processing.
Further processing means that the interaction event is sent to all currently known InteractionEventObserver (e.g. the mitk::DisplayInteractor) by notifying the observer.

The basis for interaction is mitk::InteractionEvent, which defines different key and mouse values (e.g. LeftMouseButton). The buttons can either describe the button that triggers an event (EventButton) or describe the button(s) that are already pressed, when another event is triggered (ButtonState).
Different events can be stored in an .xml-config File as <event_variant>

Subclassing an mitk::InteractionEventHandler allows to set such an .xml-config file for the subclass (via SetEventConfig). The .xml-config file will be stored as an mitk::EventConfig, which is created by using an EventConfigXMLParser to parse the .xml-config file.
The base-class will then call a ConfigurationChanged -function, that can be overridden in the subclass. The mitk::DisplayInteractor for example overrides this function to set some member variables according to the properties that were extracted from the .xml-config file (e.g. scroll direction, zoom factor, ...).

In order to use the triggered events, a state machine has to be subclassed (mitk::EventStateMachine, which in turn subclasses mitk::InteractionEventHandler). Such a state machine defines which actions to take on which interaction events. Those actions can be connected inside the derived class (e.g. mitk::DisplayInteractor) to call member functions (connection is done inside the ConnectActionsAndFunctions-function). The mitk::DisplayInteractor for example connects the init event from the state machine with its member function Init.

kalali added a comment.EditedFeb 19 2018, 6:36 PM

So if we think about implementing our own synchronization mechanism (e.g. a SynchronizedDisplayInteractor or at least a InteractionEventBoradcast) we need to subclass mitk::InteractionEventObserver. This way we can override the notify-function, which is needed to get informed by the dispatcher.
In order to create actions for the interaction events, we need to subclass mitk::EventStateMachine. Both is done by the mitk::DisplayInteractor. Here we can find common calculations that are also needed for a synchronization mechanism.

However, if we want to be able to chose between the classic DisplayInteractor and a synchronized version, we need to set it in the mitk::MouseModeSwitcher-class. Here only a mitk::DisplayInteractor is accepted, which is then registered as a microservice (as an mitk::InteractionEventObserver to be notified by the dispatcher).
If we create a base-class for the display interactors, this base class might as well contain the common calculations.

kalali added a comment.EditedFeb 20 2018, 11:01 AM

Each mouse interaction event is handled by a state machine, depending on the current state. This leads to a call of a certain function (action to be taken). This is done inside the mitk::DisplayInteractor.
In the synchronization broadcast case, the action should be to invoke an itk-event. So each action of the state machine, defined in the DisplayInteraction.xml-file, has to be covered (if we don't want to write a new DisplayInteraction.xml-file). Otherwise we'll get a warning (No implementation of action 'actionName' has been found.).
That means we need to define all actions that will be used by an event state machine already in the base-class.

kalali added a comment.EditedFeb 27 2018, 6:01 PM

Another idea is outlined in the parent task: Use the current mitk::DisplayInteractor as mitk::InteractionEventBroadcast and leave the common calculations there. Put interactor specific code into observer-classes that react on the events sent by the broadcast class. Here a classic observer could mimic the behavior of the former mitk::DisplayInteractor.
The customized observer-classes don't need to define functions for all events. They could simply not react on certain events.

Concerning the mitk::mouseModeSwitcher and the instantiation of an interactor inside this mouse mode switcher see T24300.

kalali removed a subscriber: metzger.Mar 8 2018, 1:59 PM
kalali closed this task as Resolved.Mar 12 2018, 10:33 AM

This task will be closed now but remains as a look-up task for our decision process.