cancel
Showing results for 
Search instead for 
Did you mean: 

How to detect long press on custom container?

BParh.1
Senior III

So I create a simple custom container containing just a box. Then I create 3 instances of this custom container in Screen1. I modify the custom container class to detect single click. But how to detect long press > 1s on any of these 3 containers?

Attached is the partially done of the project, it is able to detect single click but not long press. Can someone give me some pointer or maybe complete the project?

So the final objective is for function onLongPressHandler() in CustomContainer1 class called when there is long press.

1 ACCEPTED SOLUTION

Accepted Solutions
Alexandre RENOUX
Principal

Hello BParh.1,

If you want another solution to have handleTickEvent() called inside a CustomContainer, you can call registerTimerWidget() like the below code snippet. When you don't need the handleTickEvent anymore, it's good practice to unregister the widget with unregisterTimerWidget().

MyCustomContainer::MyCustomContainer()
{
    Application::getInstance()->registerTimerWidget(this);
}
 
void MyCustomContainer::initialize()
{
    MyCustomContainerBase::initialize();
}
 
void MyCustomContainer::handleTickEvent()
{
    //Now this function is executed
}

/Alexandre

View solution in original post

8 REPLIES 8
Romain DIELEMAN
ST Employee

Hi,

Alexandre shared a project of his once in this forum. You can try to search for the post but I have the project here. To implement a long click you will need to use the handleTickEvent() function.

/Romain

BParh.1
Senior III

Thank you @Romain DIELEMAN​ , I am aware of this sample, however this is not really for Custom Container case. If I follow the same approach as you attached, I am afraid the code become bloated as the number of container instances increase. Imagine for every single container I have to track it in this way:

void Screen1View::handleTickEvent()
{
    if(isPressed)
    {
        tickCounter++;
        if(tickCounter%180 == 0) //3 seconds have passed
        {
            tickCounter = 0;
            if(isGreen)
            {
                box.setColor(touchgfx::Color::getColorFrom24BitRGB(0, 141, 237));
                box.invalidate();
                isGreen = false;
            }
            else
            {
                box.setColor(touchgfx::Color::getColorFrom24BitRGB(127, 242, 0));
                box.invalidate();
                isGreen = true;
            }
        }
    }
    else
    {
        tickCounter = 0;
    }
}

In my sample I only put 3 container instances, but in real project this number can grow say 10 instances, then I have to have 10 copies of similar code.

My idea is to let the behavior of long press stay inside the Custom Container class, I am not sure it if it possible in current platform, or if there is other alternative to do it?

BParh.1
Senior III

The other way to ask here is how to have regular periodic function akin to handleTickEvent() in Screen level, but this time is in Custom Container level.

I find one better approach than my originally one but still I dont think it is the best. So I define say handleTickEvent() function in Custom Container, then call this periodically from Screen handleTickEvent() function. This way I can track how long the CustomContainer has been pressed.

But what I think the best approach is:

  1. For the Screen to enumerate what are Custom Containers presence in the screen.
  2. Then register the Container handleTickEvent() at init time of Screen so that it is called periodically.

Can this be done? How?

The final objective here is to have periodic handling isolated to Custom Container rather than put everything into the Screen handleTickEvent().

Alexandre RENOUX
Principal

Hello BParh.1,

If you want another solution to have handleTickEvent() called inside a CustomContainer, you can call registerTimerWidget() like the below code snippet. When you don't need the handleTickEvent anymore, it's good practice to unregister the widget with unregisterTimerWidget().

MyCustomContainer::MyCustomContainer()
{
    Application::getInstance()->registerTimerWidget(this);
}
 
void MyCustomContainer::initialize()
{
    MyCustomContainerBase::initialize();
}
 
void MyCustomContainer::handleTickEvent()
{
    //Now this function is executed
}

/Alexandre

BParh.1
Senior III

Thank you @Alexandre RENOUX​ , just what I was looking for 👍

BParh.1
Senior III

Hi @Alexandre RENOUX​ , I register my custom container handleTickEvent(), it works great so far except at the beginning, a single click is perceived as long press. Could this be a bug? By hunch I feel this might be racing condition.

My sample code here is attached

Anyway, at which point we should unregister the handle?

Alexandre RENOUX
Principal

Hi @BParh.1​ ,

I cannot reproduce on my computer your issue. But I found something wrong with your code. Actually you unregister the widget at the right place put you don't register it correctly. In your code, you register several times the same CustomContainer. A widget should be registered only once. So I created a boolean to avoid it.

Replace CustomContainer1.cpp and .hpp with the ones I enclosed and tell me if you still have the issue. Make sure to move your simulator window before interacting with it because otherwise the prompt window will appear on top as soon as you click.

When you send a project, it's good practice to delete the touchgfx/ and build/ folder at least. This reduces the project size considerably.

/Alexandre

BParh.1
Senior III

Thank you for the tip @Alexandre RENOUX​ , was looking a way to reduce my cleaning the solution but still too big, was not aware we can actually dete the touchgfx/ and build/folder, well noted, thank you! 😀 .

I tried your suggestion and problem persist. The only thing that can help to reduce the issue if I increase the tick count consider as long press e.g. from 30 to 60 count. With this the issue still occurred but much less frequent.

So with regards to following snippet code, the issue indicate that only at the beginning the m_isPressed remain true througout even thoug it was just a single click. As if the onClickHandler() is late to realize the ClickEvent::RELEASED.

 
void CustomContainer1::onClickHandler(const Box& elem, const ClickEvent& ev) {
    // Detect Single Click
    m_isPressed = (ev.getType() == ClickEvent::PRESSED);
.............
}

vs unregister the handleTickEvent()