Jomelo / LCDMenuLib2

Create a tree menu. Use it with different lcd types / console output / ssh console.
MIT License
249 stars 46 forks source link

Top dynamic element not updated if lower element changes it value #68

Closed rstanislav closed 1 year ago

rstanislav commented 4 years ago

For example menu:

1) Value: 0 2) Param: 0

Both of them are dynamic, if in dynamic function of first element i change value of second on encoder press - second element changes instantly, for example:

1) Value: 1 2) Param: 1

But, if i change in dynamic function of second element value of first (for example back to 0) - expected it should look like this:

1) Value: 1 2) Param: 1

But currently it looks like this:

1) Value: 0 2) Param: 1

Value changed, but on display its not updated, and if i move cursor by rotating encoder to any other element it updates.

Is it a bug ? Maybe its possible to force update of menu or its element ? I have tryed to use

LCDML.DISP_update(); and LCDML.DISP_menuUpdate();

But display not updated, so only way to see updated value is to move cursor by rotating encoder.

I'm using arduino mega with st7920 128x64 display over spi.

Jomelo commented 4 years ago

Hello, the DISP_update and menuUpdate function do not work on this case because a dynamic menu function runs as a menu function.

Disp_update call only the lcdml_menu_clear() and lcdml_menu_display() functions. The menuUpdate function regenerate only the menu structure for example for hidden buttons.

Can you try it with this function:

LCDML.OTHER_updateFunc();

This function will update the element content.

This many types of update function are grown in the last years with every new library content update. Today i would change this handling but running programms can not be updated easily when i change the names. .. ;-|

rstanislav commented 4 years ago

Thanks for answer, i have tryed, but it didn't work, same result, does it updates all menu elements ? maybe i should pass element id or something like that ?

As a workaround i found that if i do LCDML.OTHER_setCursorToID(1); (so cursor does not move) - it updates top element.

Code looks like this:

LCDML_addAdvanced (0  , LCDML_0         , 1  , NULL               , "", mDyn1, 0,_LCDML_TYPE_dynParam);
LCDML_addAdvanced (1  , LCDML_0         , 2  , NULL               , "", mDyn2, 0,_LCDML_TYPE_dynParam);

mDyn1:

void mDyn1(uint8_t line)
{
  if (line == LCDML.MENU_getCursorPos())
  {
    if (LCDML.BT_checkAny())
    {
      if (LCDML.BT_checkEnter())
      {

        if (main_mode == 1) {
          main_mode = 0;
        } else {
          main_mode = 1;
          vent_mode = 1;
        }
        LCDML.BT_resetEnter();
      }
    }
  }

  if (main_mode == 1) {
    u8g2.drawUTF8( _LCDML_DISP_box_x0 + _LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind,  _LCDML_DISP_topoffset_y0 + (_LCDML_DISP_font_h * (1 + line)), "Mode: auto");
  } else {
    u8g2.drawUTF8( _LCDML_DISP_box_x0 + _LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind,  _LCDML_DISP_topoffset_y0 + (_LCDML_DISP_font_h * (1 + line)), "Mode: manual");
  }
}

mDyn2:

void mDyn2(uint8_t line)
{
  if (line == LCDML.MENU_getCursorPos())
  {
    if (LCDML.BT_checkAny())
    {
      if (LCDML.BT_checkEnter())
      {

        if (vent_mode == 1) {
          vent_mode = 0;
          main_mode = 0;
          //LCDML.OTHER_setCursorToID(1);
          LCDML.OTHER_updateFunc();
        } else {
          vent_mode = 1;
        }
        LCDML.BT_resetEnter();
      }
    }
  }
 if (vent_mode == 1) {
    u8g2.drawUTF8( _LCDML_DISP_box_x0 + _LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind,  _LCDML_DISP_topoffset_y0 + (_LCDML_DISP_font_h * (1 + line)), "Vent: on");
  } else {
    u8g2.drawUTF8( _LCDML_DISP_box_x0 + _LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind,  _LCDML_DISP_topoffset_y0 + (_LCDML_DISP_font_h * (1 + line)), "Vent: off");
  }
}
rstanislav commented 4 years ago

Any updates ? :(

Jomelo commented 4 years ago

Hey, i will fix it on the next weekend. At the moment there is no function to update the content and the display.

Jomelo commented 4 years ago

Hello, i have checked this case. It is not easy to fix it because the dynamic function is called from the "update" function. Now when i call in the dynamic function the update function, I have a loop.

There is at the moment no way to update the library and stay compatible to the old versions.

Experiment 1: I can fix this problem when i add in LCDML_display_menu tab another "for" loop which make only the changes of an dynamic function and call the output of an dynamic function in another loop. But with mixed content (normal elements and dynparams) it is not working.

Experiment 2: Before the Update function in the menu is called i have to call the dynamic function internaly. (Only the action part) the output will printed by normal way. Problem, i have to change the dynamic function handling to split the output and the action part. This is not compatible.

Experiment 3: I'm looking for another way but I'm still working on it.

Jomelo commented 4 years ago

Can you try the newes version: v2.2.5

I add there a new method to call the dynamic content function again without button action. All Button checks have no effekt because this second call is only to update the display content.

Example

 // This check have only an effect when MENU_disScroll is set
      if(LCDML.BT_checkUp())
      {
        g_dynParam1++;
        LCDML.MENU_setDynFunctionContentUpdate(); // this function is new 
      }

This solution is compatible to the older version.

Sometimes when I have the time to set up a new major version like 3.0.0 i will split the dynamic function into two parts / methods one for the ouput and another for the dynamic action part.

rstanislav commented 4 years ago

Tried today - screen is frozen after power up on new version, didn't react to control actions (i'm using encoder). =(

Jomelo commented 4 years ago

Hello, is the menu frozen because the new code line a have posted above or it is frozen because the new version ?

At the moment i have removed the new functionality from the master version. I have only few time to work on the library, I hope I can spend more time on the next weekend.

To fix this problem without losing the compatibility to older versions is nearly impossible ...

rstanislav commented 4 years ago

Hello, its frozen because of new version, after powerup :( Thanks alot for your work & help, great project! Will wait for fix, i wish i could help, but in last commit there is too many changes I will try to check today - maybe there is problem with new control code part of code.

rstanislav commented 4 years ago

Checked today - there is strange thing - if i do LCDML.SCREEN_enable(mFunc_screensaver, 2000); in setup function and then disable it in menu (via button) - everything works, if i remove it from setup screen is frozen at start and not reacting to buttons\encoder. LCDML.MENU_setDynFunctionContentUpdate(); works - it updates top elements, only thing that i noticed - in lcdml_menu_display() i have custom part that draws info on top of screen (but inside of main frame) (code of it is around part that draws scrollbar and frame) - but it didn't updates with LCDML.MENU_setDynFunctionContentUpdate();, only way to update it is to move cursor with encoder.

Jomelo commented 4 years ago

Hello, i add v2.2.6-beta to the master branch. The screensaver bug is fixed. The screensaver variable was not correctly defined to NULL on startup (I add this bug in v2.2.5 on optimization some lines. ... shouldn't happen).

For the other bug i add another line. On my 20x4 display it works correctly when i add after every parameter this line:

LCDML.MENU_setDynFunctionContentUpdate();

Jomelo commented 4 years ago

Hey, i have update the master version again, there was another bug to freeze the menu. I think that was the bug you have descriped above.

rstanislav commented 4 years ago

It works! Thanks alot! Only one question left - how to make it update info on top of screen (not menu itself)

in lcdml_menu_display() i have custom part that draws info on top of screen (but inside of main frame) (code of it is around part that draws scrollbar and frame) - but it didn't updates with LCDML.MENU_setDynFunctionContentUpdate();, only way to update it is to move cursor with encoder.

Jomelo commented 4 years ago

Can you say me the position where you have insert this content and give me an example ?

rstanislav commented 4 years ago

Code is between draw frame part and scrollbar part in lcdml_menu_display():

  u8g2.setFont(_LCDML_DISP_top_font);
  char buf[45];
  fin_temp_avg_int = fin_temp_avg;
  char str_temp[8];
  dtostrf(fin_temp_avg, 4, 2, str_temp);
  sprintf (buf, "Меню: Т - %s", str_temp);
  u8g2.drawUTF8( _LCDML_DISP_box_x0 + 2, _LCDML_DISP_box_y0 + _LCDML_DISP_top_font_h + 1 , buf);

  u8g2.setFont(_LCDML_DISP_font);

Photo of what is looks like: https://drive.google.com/file/d/1mN3ut95kotzEnyV9xrXW9FcNNkgtiJfX/view

It updates if i move cursor with encoder, but LCDML.MENU_setDynFunctionContentUpdate(); doesn't updates it :(

rstanislav commented 3 years ago

Any updates ? :(