cancel
Showing results for 
Search instead for 
Did you mean: 

doScroll() doesn't scroll the full text

nico23
Senior II

So, I'm trying to have a text that scroll automatically if the container width is too small.

My costume container will set the text and then calculate the width with

textLightSoundSettings.setTypedText(TypedText(T_AVVSONORITEXT));

if (textLightSoundSettings.getTextWidth() > scrollTextLightSoundSettings.getWidth()) {
            scrollText = true;
            pixelToScroll = textLightSoundSettings.getTextWidth() - scrollTextLightSoundSettings.getWidth();
}

Then, in the container's tick handle event

void lightSoundItem::handleTickEvent()
{
    lightSoundItemBase::handleTickEvent();

    if(scrollText)
    {
        static int16_t pixelScrolled = 0;
        static bool scrollRight = true;

        if (scrollRight) {
            if (pixelScrolled < pixelToScroll) {
                scrollTextLightSoundSettings.doScroll(1, 0);
                pixelScrolled += 1;
            } else {   
				scrollRight = false;
            }
        } else {
            if (pixelScrolled > 0) {
                scrollTextLightSoundSettings.doScroll(-1, 0);
                pixelScrolled -= 1;
            } else {
				scrollRight = true;
                }
            }
        }
        scrollTextLightSoundSettings.invalidate();
    }
}

For some reason, even if the pixelToScroll is calculated correctly, when the text scrolls, it doesn't reach the end of the text, but it stops too early.

Am I missing something?

1 ACCEPTED SOLUTION

Accepted Solutions
nico23
Senior II

Hi @GaetanGodart ,

 

it turned out it was an issue with my logic and I was able to fix it (anyway, thanks a lot for the link to the custom widget)

void lightSoundItem::handleTickEvent()
{
    lightSoundItemBase::handleTickEvent();

    if (!scrollText) {
        return; // No scrolling needed
    }
    
    switch (scrollState) {
        case SCROLL_RIGHT:
            {
                animationTime++;
                
                // Calculate new position using sine easing
                int16_t newPosition = EasingEquations::sineEaseInOut(
                    animationTime,           // t: current time
                    0,                       // b: beginning value (left position)
                    pixelToScroll,          // c: change (total distance to scroll)
                    animationDuration       // d: duration
                );
                
                // Calculate delta from current position
                int16_t deltaX = newPosition - currentScrollPosition;
                
                // Apply scroll
                if (deltaX != 0) {
                    scrollTextLightSoundSettings.doScroll(deltaX, 0);
                    currentScrollPosition = newPosition;
                }
                
                // Check if animation is complete
                if (animationTime >= animationDuration) {
                    scrollState = PAUSE_RIGHT;
                    pauseCounter = 0;
                    animationTime = 0;
                }
            }
            break;
            
        case PAUSE_RIGHT:
            pauseCounter++;
            if (pauseCounter >= pauseDuration) {
                scrollState = SCROLL_LEFT;
                pauseCounter = 0;
            }
            break;
            
        case SCROLL_LEFT:
            {
                animationTime++;
                
                // Calculate new position using sine easing (going back to 0)
                int16_t newPosition = EasingEquations::sineEaseInOut(
                    animationTime,           // t: current time
                    pixelToScroll,          // b: beginning value (right position)
                    -pixelToScroll,         // c: change (negative distance back to start)
                    animationDuration       // d: duration
                );
                
                // Calculate delta from current position
                int16_t deltaX = newPosition - currentScrollPosition;
                
                // Apply scroll
                if (deltaX != 0) {
                    scrollTextLightSoundSettings.doScroll(deltaX, 0);
                    currentScrollPosition = newPosition;
                }
                
                // Check if animation is complete
                if (animationTime >= animationDuration) {
                    scrollState = PAUSE_LEFT;
                    pauseCounter = 0;
                    animationTime = 0;
                }
            }
            break;
            
        case PAUSE_LEFT:
            pauseCounter++;
            if (pauseCounter >= pauseDuration) {
                scrollState = SCROLL_RIGHT;
                pauseCounter = 0;
            }
            break;
    }
}

The header file contains

int16_t tickCounter;
    const int duration = 240;
    bool scrollForward = true;
    int16_t prevPosAnimation = 0;
    
    // Animation state variables
    uint16_t animationTime = 0;
    uint16_t animationDuration = 120; // Total animation duration (ticks)
    uint16_t pauseDuration = 60;      // Pause duration at each end (ticks)
    uint16_t pauseCounter = 0;
    
    enum ScrollState {
        SCROLL_RIGHT,    // Moving right (positive deltaX)
        PAUSE_RIGHT,     // Paused at right position
        SCROLL_LEFT,     // Moving left (negative deltaX)
        PAUSE_LEFT       // Paused at left position
    };
    
    ScrollState scrollState = SCROLL_RIGHT;
    int16_t currentScrollPosition = 0;

The only thing I came across is that, for some reason, on the first access of the view where my container is, before the animation starts I have to wait some seconds.

It's like I have to wait a full "ghost" execution of the animation state machine before I actually see the text moving.

View solution in original post

2 REPLIES 2
GaetanGodart
ST Employee

Hello @nico23 ,

 

Perhaps this custom widget is doing what you want to do.

You could either use it directly or look at the code and do the same thing.

 

If that is not good enough for you, could you please share your project so I can try it myself and try to see where the issue is?

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)
nico23
Senior II

Hi @GaetanGodart ,

 

it turned out it was an issue with my logic and I was able to fix it (anyway, thanks a lot for the link to the custom widget)

void lightSoundItem::handleTickEvent()
{
    lightSoundItemBase::handleTickEvent();

    if (!scrollText) {
        return; // No scrolling needed
    }
    
    switch (scrollState) {
        case SCROLL_RIGHT:
            {
                animationTime++;
                
                // Calculate new position using sine easing
                int16_t newPosition = EasingEquations::sineEaseInOut(
                    animationTime,           // t: current time
                    0,                       // b: beginning value (left position)
                    pixelToScroll,          // c: change (total distance to scroll)
                    animationDuration       // d: duration
                );
                
                // Calculate delta from current position
                int16_t deltaX = newPosition - currentScrollPosition;
                
                // Apply scroll
                if (deltaX != 0) {
                    scrollTextLightSoundSettings.doScroll(deltaX, 0);
                    currentScrollPosition = newPosition;
                }
                
                // Check if animation is complete
                if (animationTime >= animationDuration) {
                    scrollState = PAUSE_RIGHT;
                    pauseCounter = 0;
                    animationTime = 0;
                }
            }
            break;
            
        case PAUSE_RIGHT:
            pauseCounter++;
            if (pauseCounter >= pauseDuration) {
                scrollState = SCROLL_LEFT;
                pauseCounter = 0;
            }
            break;
            
        case SCROLL_LEFT:
            {
                animationTime++;
                
                // Calculate new position using sine easing (going back to 0)
                int16_t newPosition = EasingEquations::sineEaseInOut(
                    animationTime,           // t: current time
                    pixelToScroll,          // b: beginning value (right position)
                    -pixelToScroll,         // c: change (negative distance back to start)
                    animationDuration       // d: duration
                );
                
                // Calculate delta from current position
                int16_t deltaX = newPosition - currentScrollPosition;
                
                // Apply scroll
                if (deltaX != 0) {
                    scrollTextLightSoundSettings.doScroll(deltaX, 0);
                    currentScrollPosition = newPosition;
                }
                
                // Check if animation is complete
                if (animationTime >= animationDuration) {
                    scrollState = PAUSE_LEFT;
                    pauseCounter = 0;
                    animationTime = 0;
                }
            }
            break;
            
        case PAUSE_LEFT:
            pauseCounter++;
            if (pauseCounter >= pauseDuration) {
                scrollState = SCROLL_RIGHT;
                pauseCounter = 0;
            }
            break;
    }
}

The header file contains

int16_t tickCounter;
    const int duration = 240;
    bool scrollForward = true;
    int16_t prevPosAnimation = 0;
    
    // Animation state variables
    uint16_t animationTime = 0;
    uint16_t animationDuration = 120; // Total animation duration (ticks)
    uint16_t pauseDuration = 60;      // Pause duration at each end (ticks)
    uint16_t pauseCounter = 0;
    
    enum ScrollState {
        SCROLL_RIGHT,    // Moving right (positive deltaX)
        PAUSE_RIGHT,     // Paused at right position
        SCROLL_LEFT,     // Moving left (negative deltaX)
        PAUSE_LEFT       // Paused at left position
    };
    
    ScrollState scrollState = SCROLL_RIGHT;
    int16_t currentScrollPosition = 0;

The only thing I came across is that, for some reason, on the first access of the view where my container is, before the animation starts I have to wait some seconds.

It's like I have to wait a full "ghost" execution of the animation state machine before I actually see the text moving.