cancel
Showing results for 
Search instead for 
Did you mean: 

how to initiate touchgfx slider event from code

blueriver
Associate II

Hi eveyone!

I am using TouchGFX Designer 4.25.0

In the real world, you can only move a linear slider control by touching/moving the slider knob itself. One of the issues with using the TouchGFX Slider Widget is that it will instantly move from one position to another by touching/clicking anywhere on the slider scale. The graphical indicator (knob) is only there to indicate where the new setting sits on its scale of 0% to 100%.

I have 16 sliders, eight of which are visible at any one time. With my application, it would be a disaster if a user "accidentally" touched a slider (scale) and moved a setting from very low to very high in an instant. I have seen one post (a medical app !!) where the designer has the same problem.

++++++

So far, I have half a solution and would like to ask for help on how to solve my current dilema. Thanks in advance.

void ChannelFader::UpdateStatus()  // Slider adjustment confirmed
{
  /* other code here */
  sliderChSlider.setTouchable(false);
}

Here, I have disabled touch for the slider

I have created a background image behind the slider and created code to respond to it being touched

void ChannelFader::imgChFaderScaleClickHandler(const Image& b, const ClickEvent& evt)
{
   if (&b == &imgChFaderScale)
   {
      int x = evt.getX();
      int y = evt.getY();
      /* here will be code to determine that slider indicator is being touched */

      /* if so then ... */
      sliderChSlider.setTouchable(true);
   }
}

This code works fine. And the slider is then set sliderChSlider.setTouchable(true)

Here's my problem ...

Releasing the click (onto the slider indicator) does indeed enable the slider. But I have to click again to re-enage with the slider and make it move.

What I would like to do is have a line of code that re-enages with the slider (as if I had clicked it). Then I can slide the indicator, set a new position, release it. Then the first snippet of code would then sliderChSlider.setTouchable(false) once more. And everythng would be safe again from accidental touches/clicks.

Many thanks for any insight you can offer to help me solve this dilema.

Regards
blueriver

 

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

1)

It is probably possible but I think it will be harder.
If you want to go this way, since there is no function to manage the moving element separately, you should copy the class and modify it to your needs.
You can find the base class under touchgfx => framework => source/include => touchgfx => containers => slider.cpp/hpp:

GaetanGodart_0-1746456167818.png

 

2)

I don't remember exactly but I think it is necessary to be abel to call handleClickEvent or handleDragEvent or both.

 

3)

It is indeed responsible for that.
It would also work if it got called less than 60 times per seconds, it would just not be as smooth because even if we missed a tick, we would get the next tick and the function use a coordinate, not a relative coordinate to the previous position.

 

4)

The actionValidatedSwipe() does not validate the swipe nor does it leaves the draggable object at its position.
The draggeable object will stay at its position by itself if we don't do anything (here it moves back because actionFailed would be called c.f. point 5).

Instead, the only thing it does is to act as the trigger for an interaction on TouchGFX Designer :

GaetanGodart_1-1746456625798.png

These actions will fade the different elements so we get the green arrow, it is simply easier to do fades in Designer than in code.

 

5)

Indeed, it is actionFailed() that makes the moving part snap back to it's start position if the user failed to go all the way to the end.
Or rather, it is actionFailed() that triggers the interaction that makes it happen, because just like for fading, smooth movements are also easier done as an interaction in Designer.
It is that interaction that makes the movement smooth, you can change the values in Designer directly :

GaetanGodart_2-1746456920737.png

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

View solution in original post

6 REPLIES 6
blueriver
Associate II

Hi Again,

A thought came to mind for an alternative way to achieve the above.

Given that it is possible to know if the touch/click event occurs within the co-ordinate bounds of the slider indicator, this leads to the follwoing question ...

Is it possible to condition the outcome of the slider touch/click/drag/value_update event with a co-ordinate check somehow? and ignore if not touching the slider indicator itself.

+

Would anyone know if the next version of TouchGFX Designer have an option for a slider definition, such that it responds like a real physical slider?

Thanks,
blueriver

GaetanGodart
ST Employee

Hello @blueriver ,

 

Perhaps the easiest way would be to create a custom container.

Luckily for you, I already made a custom slider that you can take great inspiration from as it can only be moved if we press on the moving part of the slider, you can find it attached.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Hi Gaetan,

Many, many thanks for the response.

I have spent some time looking at the CustomWidgetConfirmationSlider example. Looking at the code, I can (mostly) see how this works, but it has generated a few follow-up questions (if I may ...)

1/. I'm Ok with your suggested idea, but just wish to confirm that you are saying that I should abandon using a conventional slider? As there is no way of distinguishing between the slider body (scale) and the indicator knob? Is this correct?

 

I have used containers to group together objects, but the use of a standard container as a draggable object is new to me (I need to look at a few examples to get up to speed). Looking at your example does seed a few questions:-

 

2/. Are all containers draggable by default. And is it the   setTouchable(true);   statement that enables this draggable action?

3/. I assume the statement       containerSlider.setXY(xVal, Y_POS);     is responsible for moving the circular knob. Does this work because  "handleDragEvent" is called every tick (1/60 sec) and therefore there is a new xVal every tick?

4/. Is it the statement    actionValidatedSwipe();    that ends the 'drag' and leaves the draggable object at its destination?

5/. I notice, that if the drag doesn't complete the full extent of the X drag, the 'knob' returns back to the start position. I assume the statement    actionFailed()   makes this happen. But I also notice this happens smoothly over a period of time (and doesn't snap back). How is this achieved? What sets the 'return' time period and smoothness?

Sorry for lots of questions, but there was a lot to unpack.

As always, many thanks and best regards,

blueriver

 

 

1)

It is probably possible but I think it will be harder.
If you want to go this way, since there is no function to manage the moving element separately, you should copy the class and modify it to your needs.
You can find the base class under touchgfx => framework => source/include => touchgfx => containers => slider.cpp/hpp:

GaetanGodart_0-1746456167818.png

 

2)

I don't remember exactly but I think it is necessary to be abel to call handleClickEvent or handleDragEvent or both.

 

3)

It is indeed responsible for that.
It would also work if it got called less than 60 times per seconds, it would just not be as smooth because even if we missed a tick, we would get the next tick and the function use a coordinate, not a relative coordinate to the previous position.

 

4)

The actionValidatedSwipe() does not validate the swipe nor does it leaves the draggable object at its position.
The draggeable object will stay at its position by itself if we don't do anything (here it moves back because actionFailed would be called c.f. point 5).

Instead, the only thing it does is to act as the trigger for an interaction on TouchGFX Designer :

GaetanGodart_1-1746456625798.png

These actions will fade the different elements so we get the green arrow, it is simply easier to do fades in Designer than in code.

 

5)

Indeed, it is actionFailed() that makes the moving part snap back to it's start position if the user failed to go all the way to the end.
Or rather, it is actionFailed() that triggers the interaction that makes it happen, because just like for fading, smooth movements are also easier done as an interaction in Designer.
It is that interaction that makes the movement smooth, you can change the values in Designer directly :

GaetanGodart_2-1746456920737.png

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Many thanks Gaetan,

Over past couple of hours, I've delved further into the TouchGFX project itself. And found the Actions and Triggers defined by the container properties.

Looking at the interactions (InteractionValidatedSwipe and InteractionAnimateBackCircle) I can see how this now all glues together.

With your last very detailed and informative post, I'm sure I can now create my FaderSlider and for it to respond just how I wish it to.

Thanks once again,

blueriver

p.s. For a future revision of TouchGFX Designer,it would be great if an option checkbox were added to the slider widget properties, such that only the "moving element" (knob) is in focus for dragging. Hope this is possible.

 

 

 

Hello @blueriver ,

 

My pleasure! :)

I will see with the team if we can implement this feature.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)