cancel
Showing results for 
Search instead for 
Did you mean: 

ItemSelectedCallback for scroll list is not called

OIrin.1
Associate II

Hello,

My GUI project developed with TouchGFX has got a screen with a scroll list. I want to be able to select an item from that scroll list. I used "Scroll Wheel and List Example" project as a reference as it supports item selection in the scroll list. But in my project the callback function that is called when an item is selected (ItemSelectedCallback) is not called. When I touch a desired item the list just starts trembling, trying to scroll according to micromovement of my finger on the touch panel, but there is no entrance into the selection callback.

Any help is much appreciated.

11 REPLIES 11
JTP1
Lead

Hello

Have you remember to set the callback to the scrollList

  scrollList.setItemSelectedCallback(ItemSelectedCallback);

and also link the callback to the handler function in parent class constuctor:

Screen1View::Screen1View() :
ItemSelectedCallback(this,&Screen1View::ItemSelectedHandler)
{ }

and then declare those in .hpp.

Maybe you show us your code ?

OIrin.1
Associate II

Thank you for the answer.

Yes, I did implemented all these stuff.

Here is the .hpp code:

#include <gui_generated/library_screen_screen/Library_ScreenViewBase.hpp>
#include <gui/library_screen_screen/Library_ScreenPresenter.hpp>
 
class Library_ScreenView : public Library_ScreenViewBase
{
public:
    Library_ScreenView();
    virtual ~Library_ScreenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
 
    virtual void library_list_scrollUpdateItem (AnalysisContainer& item, int16_t itemIndex);
protected:
 
    // Callback which is executed when a item in the scroll list is selected.
    // The parameter itemSelected is the selected item.
    Callback<Library_ScreenView, int16_t> library_list_scrollItemSelectedCallback;
    void library_list_scrollItemSelectedHandler(int16_t itemSelected);
 
    uint8_t previousIndex;
    uint8_t currentIndex;
};

And here is the .cpp code:

#include <gui/library_screen_screen/Library_ScreenView.hpp>
 
Library_ScreenView::Library_ScreenView():
	library_list_scrollItemSelectedCallback(this, &Library_ScreenView::library_list_scrollItemSelectedHandler),
	previousIndex(100),
	currentIndex(100)
{
 
}
 
void Library_ScreenView::setupScreen()
{
    Library_ScreenViewBase::setupScreen();
 
    library_list_scroll.setItemSelectedCallback(library_list_scrollItemSelectedCallback);
}
 
void Library_ScreenView::tearDownScreen()
{
    Library_ScreenViewBase::tearDownScreen();
}
 
void Library_ScreenView::library_list_scrollUpdateItem(AnalysisContainer& item, int16_t itemIndex)
{
	item.setListElements(itemIndex);
}
 
void Library_ScreenView::library_list_scrollItemSelectedHandler(int16_t itemSelected)
{
    for (int i = 0; i < library_list_scrollListItems.getNumberOfDrawables(); i++)
    {
        if(!(library_list_scrollListItems[i].isSelected()) && itemSelected == library_list_scrollListItems[i].getIndex())
        {
            for (int j = 0; j < library_list_scrollListItems.getNumberOfDrawables(); j++)
            {
                if(library_list_scrollListItems[j].isSelected())
                {
                	library_list_scrollListItems[j].setUnselected();
                }
            }
            // scrollListListItems[currentIndex].setUnselected();
            library_list_scrollListItems[i].setSelected();
            currentIndex = itemSelected;
        }
    }
 
}

So the problem is that library_list_scrollItemSelectedHandler() is never called when I touch any of the items in the list. I even reduced the list to just one item, but without success. On the display the item is just slightly shivering when I touch it.

JTP1
Lead

OK. How you have observed that its not calling the callback ? Just thinking the problem might be in list item (AnalysisContainer ?) where you have implement the setSelected etc functions.

I placed breakpoints in the callback function (any line starting from 30) and the breakpoints are never hit. setSelected() and other function are called from this callback, so code execution does not reach these calls. The list item is a simple text area with a box, there is nothing special about it.

Here is the code for the container:

#include <gui/containers/AnalysisContainer.hpp>
#include <cstdio>
 
AnalysisContainer::AnalysisContainer()
{
 
}
 
void AnalysisContainer::initialize()
{
    AnalysisContainerBase::initialize();
}
 
void AnalysisContainer::setListElements (int16_t item)
{
    char tmp_str[100];
    std::sprintf(tmp_str, "%02d", item);
    Unicode::fromUTF8((const uint8_t*)tmp_str, Analysis_scroll_text_txtBuffer, ANALYSIS_SCROLL_TEXT_TXT_SIZE);
    Analysis_scroll_text_txt.invalidate();
}
 
void AnalysisContainer::setIndex(uint8_t ind)
{
    index = ind;
}
 
uint8_t AnalysisContainer::getIndex()
{
    return index;
}
 
void AnalysisContainer::setSelected()
{
    Analysis_scroll_bckg_box.setVisible(true);
    invalidate();
    selected = true;
}
 
void AnalysisContainer::setUnselected()
{
    Analysis_scroll_bckg_box.setVisible(false);
    invalidate();
    selected = false;
}
 
bool AnalysisContainer::isSelected()
{
    return selected;
}

JTP1
Lead

Weird. I replicate your project as close as I could and callback works like it should be. (4.18.0 and 4.21.3, in simulator and discovery kit).

In your code, you dont seem to set the index. I add it to:

void Library_ScreenView::library_list_scrollUpdateItem(AnalysisContainer& item, int16_t itemIndex)
{
	item.setListElements(itemIndex);
	item.setIndex(itemIndex); // Here
 }

Then highlighting the selected item works. Otherwise this line dont work in the callback

  if(!(library_list_scrollListItems[i].isSelected()) && itemSelected == library_list_scrollListItems[i].getIndex())

since index is not set.

Thanks for the advice. Unfortunetely, it did not help.

setIndex() is a custom method which I created for my own purposes and it does not influence somehow on calling ItemSelectedHandler() which is inherited from one of parent classes.

Can the problem relate to touch sensor processing? I use a custom board and modified a touch sensor processing function to make it work with exact touch model. Perhaps TouchGFX uses some other touch functions, not only touchGetState().

JTP1
Lead

Does normal buttons work in UI ?

Btw. note that you should not check the ClickListener selection in the scrollList container. Checking that would prevent callback.

Yes, buttons, list scroll, scroll wheels work. The only things that did not, was selection inside scroll lists.

I did not check ClickListener, but you gave me a clue.

I looked inside the code for ScrollList::handleClickEvent:

void ScrollList::handleClickEvent(const ClickEvent& event)
{
    ScrollBase::handleClickEvent(event);
    if (event.getType() == ClickEvent::PRESSED)
    {
        xClick = event.getX();
        yClick = event.getY();
        initialSwipeOffset = getOffset();
 
        setOffset(getNearestAlignedOffset(initialSwipeOffset));
        if (itemPressedCallback && itemPressedCallback->isValid())
        {
            int16_t click = (getHorizontal() ? xClick : yClick);
            int32_t offset = click - getOffset();
            int32_t listSize = getNumberOfItems() * itemSize;
            if (getCircular())
            {
                offset += listSize;
                offset %= listSize;
            }
            if (offset >= 0 && offset < listSize)
            {
                int16_t item = offset / itemSize;
                itemPressedCallback->execute(item);
            }
        }
    }
    else if (event.getType() == ClickEvent::RELEASED)
    {
        if (currentAnimationState == NO_ANIMATION)
        {
            // For a tiny drag, start by re-aligning (no animation(!))
            setOffset(getNearestAlignedOffset(getOffset()));
            if (itemSelectedCallback && itemSelectedCallback->isValid())
            {
                int16_t click = (getHorizontal() ? xClick : yClick);
                int32_t offset = click - getOffset();
                int32_t listSize = getNumberOfItems() * itemSize;
                if (getCircular())
                {
                    offset += listSize;
                    offset %= listSize;
                }
                else
                {
                    offset -= distanceBeforeAlignedItem;
                }
                if (offset >= 0 && offset < listSize)
                {
                    int16_t item = offset / itemSize;
                    itemSelectedCallback->execute(item);
                }
            }
        }
        else if (currentAnimationState == ANIMATING_DRAG)
        {
            // click + drag + release. Find best Y to scroll to
            animateToPosition(getNearestAlignedOffset(getOffset()));
        }
    }
}

and noticed that itemSelectedCallback() is called if the touch is released AND there is no animation detected. I suppose that when I try to select an item in the scroll list and release the touch panel there is still ongoing animation and animateToPosition() is called instead of itemSelectedCallback().

I decided to use itemPressedCallback() instead of itemSelectedCallback() and it has started working. I have attached a small video of the way it is working now. You can notice that the list is slightly trembling when I touch it, which perhaps prevents ItemSelectedCallback to be called. The drawback of using itemPressedCallback is that sometimes an item is selected when I want to scroll the list, but not to select anything.

JTP1
Lead

Good that you get forward. Yes, the disadvantage now is that the item gets selected easily also when try to scroll the list. Think it must be some small issue on the touch IC handling. How you have done the touch ic reading ?