This example shows how one can inject virtual input into a Cornerstone application. In this example we create a simple application with only one widget, namely Sparkles. The motivation for this is that Sparkles shows nicely where our simulated input is located.
The key element in virtualising input is the Application's before-input-event. That is sent after input is gathered across the network but not yet processed by widgets. This is the moment when we want to inject artificial input into the input samples. This event sends sample indices as its parameters. In order for input to be properly handled we need to push our generated input to each sample.
Main function of this example is relatively simple. We create Sparkles-widget to the background by using plugin-machinery built into Cornerstone. After this we create an instance of HandMovement. It is added to listen Application's after-update event in order to update the location simulated hand.
HandMovement-class simulates a finger that makes circles at the middle of the screen. It has an instance of MultiWidgets::VirtualInput as its member. This class acts as an user friendly interface for managing virtual input. It is enough for the user to create appropriate VirtualObject's and pass them to instance of VirtualInput. The rest of the HandMovement's members are used for keeping track of the finger movements and the state of the finger.
The function that updates the location of the virtual hand is split into four different branches of execution. The choice of branch depends on the value of m_state. All of the branches have common initialization where the current position of the finger is calculated.
First call to function initializes the hand. We create virtual hand with single finger using function MultiWidgets::VirtualHand::fingerDown. After that we register our newly created hand to VirtualInput and update the internal state of the object.
When moving finger we specify the position of the whole hand in relation to finger we want to control. This can be done using function MultiWidgets::VirtualHand::setLocationAboutFinger. Finally we check if hand is already made a full circle and update the state if needed.
Lifting the simulated finger up is simple. The only thing needed to do is to unregister our VirtualHand from VirtualInput.
The rest of synthesizeInput-function detects when it is time to continue the movements of simulated finger. Also the angle is updated and associated timer is resetted.
The full source code for the complete application is listed below: