2019-11-13 03:06 AM
Hello,
I am developing a software with STM32L4R9AI-Disco. I am trying to make
some menu screens. All screens have scroll wheels. the project has no touch. it
has physical buttons. I need screen transitions between all screen
combinations.
* I have interactions for screen transitions. When I call the interactions,
everything works well.
* I want to call the interactions via using function pointers. You can
see the source codes and explanations below.
* I need to know last selected items of scroll wheels for every closing
screen. Because when I return back the screen again, I need to setup scroll wheel
last position. I defined a struct type from my C code and a buffer to hold
variables from that struct types.
//my declarations from C code
typedef struct{
void *intFuncPtr; //function pointers for screen transition fuctions
uint32_t parameter; // scrollweels last positions
}screenTransitionType;
#define MAX_SCREEN_TRANSITION 20
screenTransitionType screenTransitionBuffer[MAX_SCREEN_TRANSITION]; //transition buffer
extern bool putScreenTransitionBuffer(screenTransitionType st); //put new struct to buffer
extern bool pullScreenTransitionBuffer(screenTransitionType *st); // pull last struct from buffer and destroy it //from buffer
extern bool checkLastScreenTransitionBuffer(screenTransitionType *st); // check and get last struct from buffer //without destroy it from buffer
//one of my screen calls screen transition (it is inside the screen_modeMenuView.cpp)
void screen_modeMenuView::btn_enter_clicked()
{
screenTransitionType st; //define a screenTransitionType variable
int itemIndex=scrollWheel_modeMenu.getSelectedItem();
switch((modeMenuItem::modeMenuItemType)itemIndex){
case modeMenuItem::MODE_MENU_ITEM_SETTINGS:
void(FrontendApplicationBase::*ptr)()= &FrontendApplicationBase::gotoscreen_modeMenuScreenCoverTransitionNorth; //function pointer for
//return screen
st.intFuncPtr = (void *&)(ptr); //save func pointer
st.parameter=(uint32_t)modeMenuItem::MODE_MENU_ITEM_SETTINGS; //save scrollwheel slected item
if(putScreenTransitionBuffer(st)){ //save them in buffer
static_cast<FrontendApplication*>(Application::getInstance())
->gotoscreen_mainSettingsMenuScreenCoverTransitionSouth(); //change screen
}
break;
}
}
//the other screen (screen_mainSettingsMenuView.cpp)
void screen_mainSettingsMenuView::btn_home_clicked()
{
screenTransitionType st;
void (FrontendApplicationBase::* ptr)(); //function pointer for screen transition function type
if(checkLastScreenTransitionBuffer(&st)){ //get last screen parameters that already put on the buffer
ptr = (void (FrontendApplicationBase::* &)())(st.intFuncPtr); //get the transition function address from struct and store it to ptr
(static_cast<FrontendApplication*>(Application::getInstance())->*ptr)(); //call the transition function
}
When i call the transition function via function pointer ptr and check it in debugger, my code goes to correct transition function:
void FrontendApplicationBase::gotoscreen_modeMenuScreenCoverTransitionNorth()
{
transitionCallback = touchgfx::Callback<FrontendApplicationBase>(this, &FrontendApplication::gotoscreen_modeMenuScreenCoverTransitionNorthImpl);
pendingScreenTransitionCallback = &transitionCallback;
}
but when my code run
transitionCallback = touchgfx::Callback<FrontendApplicationBase>(this, &FrontendApplication::gotoscreen_modeMenuScreenCoverTransitionNorthImpl);
this line in transition function, it goes to HardFauldHandler.
My question is how can i call transition function via function pointers? I guess my way is OK, and i can call transition function via pointer but i couldn’t understand why my code goes to HardFaultHandler.
if any idea, I will be happy.
Best Regards,
Murat
2019-11-13 04:42 AM
Hi,
Check this example i prepared some time ago that pushes function pointers onto a stack, allowing a "go back to last view" functionality. Maybe this can give you some inspiration.
http://sw-center-st-com.s3-eu-west-1.amazonaws.com/touchgfx/TouchGFX/Community/gotoStack_example.zip
/Martin
2019-11-14 10:51 PM
Hello Martin,
Thanks for your example. I regulated your code for my project and it is working very well.
I want to ask one more question.
I want to change screen transition speed but i couldn't find a way. Could you give me any advice, please?
2019-11-15 01:16 AM
Great.
For transition speed check out touchgfx/transitions/SlideTransition.hpp, for instance (transitionSteps:(
/**
* @fn SlideTransition::SlideTransition(const uint8_t transitionSteps = 20) : Transition(), snapshot(), snapshotPtr(&snapshot), handleTickCallback(this, &SlideTransition::tickMoveDrawable), direction(templateDirection), animationSteps(transitionSteps), animationCounter(0), calculatedValue(0)
*
* @brief Constructor.
*
* Constructor.
*
* @param transitionSteps Number of steps in the transition animation.
*/
SlideTransition(const uint8_t transitionSteps = 20)
: Transition(),
snapshot(),
snapshotPtr(&snapshot),
handleTickCallback(this, &SlideTransition::tickMoveDrawable),
direction(templateDirection),
animationSteps(transitionSteps),
animationCounter(0),
calculatedValue(0)
{
...
/Martin
2019-11-15 01:54 AM
Additional info: What you can see from the code is that you're basically using "transitionSteps" to control how many steps you would like the animation to take - Based on that information, the transition class will calculate the "step" to take each tick in order to satisfy your requirement in terms of steps and easing equation.
/**
* @fn virtual void SlideTransition::handleTickEvent()
*
* @brief Handles the tick event when transitioning.
*
* Handles the tick event when transitioning. It moves the contents of the Screen's
* container and a SnapshotWidget with a snapshot of the previous Screen. The
* direction of the transition determines the direction the contents of the
* container and the SnapshotWidget moves.
*/
virtual void handleTickEvent()
{
...
Transition::handleTickEvent();
// Calculate new position or stop animation
animationCounter++;
if (animationCounter <= animationSteps)
{
// Calculate value in [0;targetValue]
calculatedValue = EasingEquations::cubicEaseOut(animationCounter, 0, targetValue, animationSteps);