Update text on the buttons without redrawing the entire screen.

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Update text on the buttons without redrawing the entire screen.

      Hello. Trying to create buttons with dynamic text. Update text should occur every minute. The screenshot shows the places where this text will be.
      I update the text via WM_PAINT in the callback function of the buttons. To call WM_PAINT, I do WM_InvalidateRect (), where I pass text coordinates inside the button and pass a pointer to the button object.
      But there is a redrawing of the entire screen, and as a result - flicker.
      Question: how to prevent redrawing the entire screen? How to update part of the button / screen?
      Images
      • 1.jpg

        21 kB, 335×247, viewed 40 times
    • Hi,

      Try the example below. There I invalidate just a rectangle part of a button to draw a string. As you will see the bottom edges of the button will change their color, due to transparency. At transparent areasof a window or widget the background has to be drawn first. But as you see, just a small part of the background gets drawn. The different color are because each time the background gets redrawn I set a different color.

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Externals
      5. *
      6. **********************************************************************
      7. */
      8. /*********************************************************************
      9. *
      10. * Defines
      11. *
      12. **********************************************************************
      13. */
      14. /*********************************************************************
      15. *
      16. * Static data
      17. *
      18. **********************************************************************
      19. */
      20. /*********************************************************************
      21. *
      22. * Static code
      23. *
      24. **********************************************************************
      25. */
      26. /*********************************************************************
      27. *
      28. * _cbBk
      29. */
      30. static void _cbBk(WM_MESSAGE * pMsg) {
      31. GUI_COLOR aColor[] = {GUI_RED, GUI_GREEN, GUI_BLUE};
      32. static int Index;
      33. GUI_RECT Rect = {0, 19, 79, 39};
      34. switch (pMsg->MsgId) {
      35. case WM_PAINT:
      36. GUI_SetBkColor(aColor[Index++]);
      37. GUI_Clear();
      38. if (Index == GUI_COUNTOF(aColor)) {
      39. Index = 0;
      40. }
      41. break;
      42. case WM_TIMER:
      43. WM_InvalidateRect(WM_GetDialogItem(pMsg->hWin, GUI_ID_BUTTON0), &Rect);
      44. WM_RestartTimer((WM_HTIMER)pMsg->Data.v, 0);
      45. break;
      46. default:
      47. WM_DefaultProc(pMsg);
      48. break;
      49. }
      50. }
      51. /*********************************************************************
      52. *
      53. * _cbButton
      54. */
      55. static void _cbButton(WM_MESSAGE * pMsg) {
      56. const char * apString[] = {"String A", "String B"};
      57. static int Index;
      58. GUI_RECT Rect = {0, 19, 79, 39};
      59. switch (pMsg->MsgId) {
      60. case WM_PAINT:
      61. BUTTON_Callback(pMsg);
      62. GUI_SetTextMode(GUI_TM_TRANS);
      63. GUI_SetColor(GUI_BLACK);
      64. GUI_DispStringInRect(apString[Index++], &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
      65. if (Index == GUI_COUNTOF(apString)) {
      66. Index = 0;
      67. }
      68. break;
      69. default:
      70. BUTTON_Callback(pMsg);
      71. break;
      72. }
      73. }
      74. /*********************************************************************
      75. *
      76. * Public code
      77. *
      78. **********************************************************************
      79. */
      80. /*********************************************************************
      81. *
      82. * MainTask
      83. */
      84. void MainTask(void) {
      85. WM_HWIN hButton;
      86. GUI_Init();
      87. WM_SetCallback(WM_HBKWIN, _cbBk);
      88. WM_CreateTimer(WM_HBKWIN, 0, 500, 0);
      89. hButton = BUTTON_CreateEx(20, 20, 80, 40, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0);
      90. WM_SetCallback(hButton, _cbButton);
      91. while (1) {
      92. GUI_Delay(100);
      93. }
      94. }
      95. /*************************** End of file ****************************/
      Display All

      Regards,
      Sven
    • Thank. But I found a more elegant solution.
      Set the WM_CF_HASTRANS | WM_CF_CONST_OUTLINE flags for the text field. Thus, when changing the text, the screen does not update, and the text is placed on top of the previous text, without erasing it. To erase the previous text, I draw the background bypassing the API. If the background has a vertical gradient, I read one column of pixels, and then draw it the necessary number of times.
      Erase text occurs in WM_PAINT.

      But now I am working on using fonts that are generated by the utility from the EmWin kit. I found where the fonts are stored in memory, I understood how the fonts are encoded, it remains only to draw.

      It seems to me that these two methods are very beautiful. I think that they should be added to the library. Something like GUI_DispStringWithoutWM(). Or as one of the flags for TEXT Widget.

      The post was edited 1 time, last by Heavy ().

    • Finally, I finished the implementation of the necessary functions. Soon I will try to write a short instruction on how to get rid of the flickering of the screen when updating the text. In short, the idea is to draw text, bypassing EmWin, with fonts generated using EmWin Font Converter.