1.3k views
in System Integration by
Hi, EW team:

        I met a specific GUI requirement. When 2 fingers touch screen and slide, the screen has to call out a new dialog, and the old one will not respond user.  The easiest idea seems to be using PresentDialog to present the new one. But the new dialog can not receive the continuous slide which was initially captured by the old one. Is there any way to overcome the difficulty?

      Thank you.

 

Best regards.

Stephen

1 Answer

0 votes
by
 
Best answer

Hello Stephen,

a touch interaction (once begun) remains associated to the original event handler. This so-called grab cycle ensures that the handler which has received a press event will not loose the control and also will receive a release event. See also Touch events and the grab cycle

This grab cycle can be terminated prematurely and the interaction can be relayed to a new event handler. In the simplest case you configure the so-called RetargetCondition in the original handler to achieve this. See also Combine several Touch Handlers together. As soon as the specified condition is fulfilled, the handler will try to find another handler which is willing to take over the interaction. This technique is used often to implement complex UI with nested lists and widgets the user can scroll and interact with.

More low-level approach is the usage of the methods RetargetCursor() or DeflectCursor(). The idea: the code executed in context of the actually active handler invokes the method to 'relay' the actual interaction to other handler. This could be the handler found in other component, e.g. in the previously presented dialog. This requires the code to have access to he component and to its handler. It means to 'know' them. You will need to remember the presented dialog e.g. in a variable so that the code triggered by the original handler can see whether the variable is initialized and relay the interaction in such case.

For example, following could be the implementation of a slot method associated to the original handler. That means the code is executed in context of the original handler:

// Is there is a dialog presented, relay the interaction to its handler
if ( the_dialog )
  GetRoot().DeflectCursor( the_dialog.SomeTouchHandler, <0,0>);

If you plan to use dialogs, please remind that the dialogs appear asynchronously. That mean, that the effect of PresentDialog() has a delay. Even if the_dialog from the code above exists already, it can eventually be not yet visible and not yet ready to handle touch events. If the dialog does not perform any animations, following could be sufficient. Now the code is executed when the dialog is already part of the view tree:

// Is there is a dialog presented and already visible, relay the interaction to its handler
if ( the_dialog && the_dialog.Owner )
  GetRoot().DeflectCursor( the_dialog.SomeTouchHandler, <0,0>);

Well, so far technical backgrounds. I'm not sure whether it helps you further or not. From our experience, I would recommend other approach. Let the original handler handle the user interaction. That means, when the user taped with two fingers and dragged them, present the new dialog but let the original handler continue handling the events. Just limit to invoke a method in the presented dialog to inform it about the performed drag operation. The dialog can then update its state/position etc. For example:

// Is there is a dialog presented, then just inform it about the dragged finger
if ( the_dialog && the_dialog.Owner )
  the_dialog.SomeUpdateMethod( TouchHandler.CurrentPos );

Best regards

Paul Banach

by

Hello Stephen,

I found your question very interesting to try it out. Below you will find a simple example demonstrating a possible implementation of how to redirect the user inputs to a just presented dialog. The most important aspects of this example are:

1. The Touch Handler responsible for the 2-finger gesture detection to present the dialog is found in a separate component named MainDialog. This means, it is not implemented directly in the Application component.

2. The MainDialog component is presented as dialog in Application component. As such it is active when there is no other dialog presented. As soon as other dialog overlays it, MainDialog is automatically deactivated. This is important to avoid interferences with touch interactions while there are other dialogs visible.

3. To become a dialog, MainDialog instance is simply assigned to the property ActiveDialog of Application component itself. See also Simplified approach to handle top-level dialogs (switching screens).

4. The Wipe Touch Handler in the MainDialog is configured with its properties RetargetCondition and RetargetDelay to try to retarget the actual interaction to other touch handler existing behind it regardless of the performed gesture. See below:

5. This means, when there is other handler behind the MainDialog, the handler will take over the interaction automatically. This is the case after the regular dialog has been presented.

6. IMPORTANT: the MainDialog is configured to always lie on top of the screen. For this purpose I set its property StackingPriority to 1. This is important because the Touch Handler searches only for other handlers behind it and not in front of it. See also Control the stacking priority of nested views.

7. Following this approach the implementation limits to configure few properties. No line of code is necessary to control the retargeting of user nteraction.

Download: The example project. Note, the example is created for version 12 or newer.

I hope this example together with the explanation in my preceding answer helps you further to implement your own application case. 

Best regards

Paul Banach

by
Hi, Paul:

     Thank you for your answer.

     I might need more time to digest the information you provided and practice.

    I will give you feedback later.

 

Best regards.

Stephen
ago by
Hi, Paul:

      The problem I am facing is a bit more complex. Let's take your  demo above for example. I have many widgets such as buttons and sliders integrated into the MainDialog. So if two fingers touch the screen one after another, it will often come to the case that the first finger touches a widget, and the second touches elsewhere, which may be MainDialog or another widget. In this case, recognition of 2 finger slide is also required.

    To overcome the difficulty, I introduced a signal counting the finger number on the screen from the touch driver. My idea was to have the event that the finger number increases from 1 to 2  trigger Presenting the Dialog. I think this will simplify the treatment regarding  the various cases of touching the MainDialog by 2 fingers. But I have no idea how to transfer control from all kinds of widgets to the newly presented Dialog.

    Maybe you can help me make a further step.

    Thank you.

 

Best regards.

Stephen
ago by

Hello Stephen,

So if two fingers touch the screen one after another, it will often come to the case ...

From technical point of view, when there is large time delay between two finger touch interactions, it is not possible to recognize them as a single composed two-finger-gesture. Instead they will be processed as two separate touch interactions.

... the first finger touches a widget, and the second touches elsewhere, which may be MainDialog or another widget

Ensure that the entire screen is occupied by a touch handler configured to react to 2-finger-gesture. Then it doesn't matter where the user has touched.

But I have no idea how to transfer control from all kinds of widgets to the newly presented Dialog.

When using the ready to use widgets, it is not possible to handle it. You will need to implement your own set of widgets adapted explicitly to handle such touch requirements.

Best regards

Paul Banach

ago by
Hiļ¼ŒPaul:

    I'd like to know the time limit beyond which the 2 fingers are not be recognized as 2-finger-gesture. I have to clarify it to customer with this limit.

Best regards.

Stephen
ago by

Hello Stephen,

this limit is coded with 50 ms. We have selected this value wisely based on our experience. The idea behind a multi-touch a gesture is to be detected only when the user really touched the screen with multiple fingers (almost) simultaneously. It is not the idea to detect gestures when the user touched the screen with one finger and after a (long) pause touched it with a second finger.

The value 50 ms is coded in the Mosaic framework. You can try to modify this value. However, there is a trap you have to take in account. The variable intended to store the delay is 8-bit signed integer. The max. delay you can configure is thus limited to 127 ms. If you want to try this approach, following could be the steps:

Step 1: Exit Embedded Wizard if it is running.

Step 2: Using Windows File Explorer navigate to the installation folder of Embedded Wizard.

Step 3: Within this folder navigate to the sub-folder named Mosaic.

Step 4: Within the Mosaic folder look for the file named Core.ewu.

Step 5: Open the file in a text editor.

Step 6: Search for the following code line:

int8 multiFingerDelay;

Step 7: Modify in all occurrences of this code the type from int8 to int16. This should permit you to store time delay up to 32767 ms. 

Step 8: Again search for the following code line:

multiFingerDelay = int8( event1.AutoDeflected? 0 : 50 )

Step 9: Modify in all occurrences of this code line the type int8 to int16.

Step 10: Also replace the value 50 by your desired delay, eg. 1000 for 1000 ms.

Step 11: Save the modifications. Please note: the files within the installation directory are protected by Windows OS. Depending on functionality of your text editor, you will eventually need to create a temporary copy of the file, modify this copy and overwrite the original file within the Mosaic folder with this copy. In the best case the text editor will ask you to confirm the overwrite operation of protected files.

Please report us whether this modification has helped you. If this is the case we can add a configuration property to Mosaic permitting the user the adjustment of this delay.

Best regards

Paul Banach

Embedded Wizard Website | Privacy Policy | Imprint

...