LISTVIEW - Blinking cells

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

    • LISTVIEW - Blinking cells

      How can I have the cells of a Listview blink with a given frequency? I tried changing the background color of a cell by recreating the listview in a timer interrupt: inside the interrupt I use the createListview function. it works for a few seconds then everything stops...
      Any idea?
      thanks
    • Hi,

      There is no need to recreate the LISTVIEW. Just create a timer and change the LISTVIEW color when the timer expires.

      Here is an example on how you could do it:

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Config
      5. *
      6. **********************************************************************
      7. */
      8. /*********************************************************************
      9. *
      10. * Defines
      11. *
      12. **********************************************************************
      13. */
      14. #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      15. #define ID_LISTVIEW_0 (GUI_ID_USER + 0x01)
      16. /*********************************************************************
      17. *
      18. * Static data
      19. *
      20. **********************************************************************
      21. */
      22. /*********************************************************************
      23. *
      24. * _aDialogCreate
      25. */
      26. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      27. { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
      28. { LISTVIEW_CreateIndirect, "Listview", ID_LISTVIEW_0, 39, 23, 151, 83, 0, 0x0, 0 },
      29. };
      30. /*********************************************************************
      31. *
      32. * Static code
      33. *
      34. **********************************************************************
      35. */
      36. /*********************************************************************
      37. *
      38. * _cbDialog
      39. */
      40. static void _cbDialog(WM_MESSAGE * pMsg) {
      41. WM_HWIN hItem;
      42. int NCode;
      43. int Id;
      44. GUI_COLOR aBlinkColor[] = {GUI_WHITE, GUI_BLUE};
      45. static int Index;
      46. switch (pMsg->MsgId) {
      47. case WM_INIT_DIALOG:
      48. //
      49. // Initialization of 'Listview'
      50. //
      51. hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
      52. LISTVIEW_AddColumn(hItem, 30, "Col 0", GUI_TA_HCENTER | GUI_TA_VCENTER);
      53. LISTVIEW_AddColumn(hItem, 30, "Col 1", GUI_TA_HCENTER | GUI_TA_VCENTER);
      54. LISTVIEW_AddColumn(hItem, 30, "Col 2", GUI_TA_HCENTER | GUI_TA_VCENTER);
      55. LISTVIEW_AddRow(hItem, NULL);
      56. LISTVIEW_SetGridVis(hItem, 1);
      57. LISTVIEW_SetItemText(hItem, 0, 0, "Item");
      58. LISTVIEW_SetItemText(hItem, 1, 0, "Item");
      59. //
      60. // uncomment for selecting single cells
      61. //
      62. //LISTVIEW_EnableCellSelect(hItem, 1);
      63. //
      64. // Create a timer
      65. //
      66. WM_CreateTimer(pMsg->hWin, 0, 500, 0);
      67. break;
      68. case WM_TIMER:
      69. //
      70. // If the timer expires we set another color for the background and the text
      71. //
      72. hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
      73. LISTVIEW_SetBkColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
      74. Index ^= 1;
      75. LISTVIEW_SetTextColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
      76. //
      77. // Restart the timer, 0 = period like on creation
      78. //
      79. WM_RestartTimer((WM_HTIMER)pMsg->Data.v, 0);
      80. break;
      81. case WM_NOTIFY_PARENT:
      82. Id = WM_GetId(pMsg->hWinSrc);
      83. NCode = pMsg->Data.v;
      84. switch(Id) {
      85. case ID_LISTVIEW_0: // Notifications sent by 'Listview'
      86. switch(NCode) {
      87. case WM_NOTIFICATION_CLICKED:
      88. break;
      89. case WM_NOTIFICATION_RELEASED:
      90. break;
      91. case WM_NOTIFICATION_SEL_CHANGED:
      92. break;
      93. }
      94. break;
      95. }
      96. break;
      97. default:
      98. WM_DefaultProc(pMsg);
      99. break;
      100. }
      101. }
      102. /*********************************************************************
      103. *
      104. * Public code
      105. *
      106. **********************************************************************
      107. */
      108. /*********************************************************************
      109. *
      110. * MainTask
      111. */
      112. void MainTask(void) {
      113. GUI_Init();
      114. GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      115. while (1) {
      116. GUI_Delay(100);
      117. }
      118. }
      119. /*************************** End of file ****************************/
      Display All


      EDIT:

      It stops working most likely because you run out of memory. Each time you create the LISTVIEW it uses a bit of the GUI_RAM. Since you never delete the LISTVIEW you will run out of RAM.

      To use a hardware timer to enable the blinking you can send a message to the window. Define a user message and send it to the widget and react in its callback on kthe message:

      C Source Code

      1. #define USER_MESSAGE WM_USER + 0x00
      2. WM_SendMessageNoPara(hListView, USER_MESSAGE);



      Regards
      Sven
    • I tried to use both methods but no results. I debugged and I never see the part of the code regarding "case: WM_TIMER" being run.
      Here is my code. What is wrong?

      int main(void)
      {

      /* Enable I-Cache-------------------------------------------------------------*/
      SCB_EnableICache();
      /* Enable D-Cache-------------------------------------------------------------*/
      SCB_EnableDCache();

      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();

      /* Configure the system clock */
      SystemClock_Config();

      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_RTC_Init();
      MX_TIM10_Init();
      MX_LTDC_Init();
      MX_DMA2D_Init();
      MX_FMC_Init();
      MX_DSIHOST_DSI_Init();
      MX_TIM6_Init();

      BSP_TS_Init(800, 480); //initialize touch panel
      BSP_SDRAM_Init(); /* Initializes the SDRAM device */
      __HAL_RCC_CRC_CLK_ENABLE();
      GUI_Init();
      GUI_Clear();
      GUI_SetLayerVisEx(1, 0);
      GUI_SelectLayer(0);

      WM_MULTIBUF_Enable(1);

      CreateLISTAWindow();

      HAL_TIM_Base_Init(&htim6);
      HAL_TIM_Base_Start_IT(&htim6);

      HAL_TIM_Base_Init(&htim10);
      HAL_TIM_Base_Start_IT(&htim10);

      while (1)
      {

      }


      In another file there is the LISTVIEW code:



      #include "DIALOG.h"

      /*********************************************************************
      *
      * Defines
      *
      **********************************************************************
      */
      #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      #define ID_LISTVIEW_0 (GUI_ID_USER + 0x01)
      #define USER_MESSAGE WM_USER + 0x00

      WM_HWIN hItem;


      // USER START (Optionally insert additional defines)
      // USER END

      /*********************************************************************
      *
      * Static data
      *
      **********************************************************************
      */

      // USER START (Optionally insert additional static data)
      // USER END

      /*********************************************************************
      *
      * _aDialogCreate
      */
      static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 100, 800, 380, 0, 0x0, 0 },
      { LISTVIEW_CreateIndirect, "Listview", ID_LISTVIEW_0, 5, 42, 790, 104, 0, 0x0, 0 },
      // USER START (Optionally insert additional widgets)
      // USER END
      };

      /*********************************************************************
      *
      * Static code
      *
      **********************************************************************
      */

      // USER START (Optionally insert additional static code)
      // USER END

      /*********************************************************************
      *
      * _cbDialog
      */
      static void _cbDialog(WM_MESSAGE * pMsg) {
      // WM_HWIN hItem;
      int NCode;
      int Id;

      GUI_COLOR aBlinkColor[] = {GUI_WHITE, GUI_BLUE};
      static int Index;
      // USER START (Optionally insert additional variables)
      // USER END

      switch (pMsg->MsgId) {
      case WM_INIT_DIALOG:
      //
      // Initialization of 'Listview'
      //
      hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
      LISTVIEW_AddColumn(hItem, 30, "Col 0", GUI_TA_HCENTER | GUI_TA_VCENTER);
      LISTVIEW_AddColumn(hItem, 30, "Col 1", GUI_TA_HCENTER | GUI_TA_VCENTER);
      LISTVIEW_AddColumn(hItem, 30, "Col 2", GUI_TA_HCENTER | GUI_TA_VCENTER);
      LISTVIEW_AddRow(hItem, NULL);
      LISTVIEW_SetGridVis(hItem, 1);
      LISTVIEW_SetItemText(hItem, 0, 0, "Item");
      LISTVIEW_SetItemText(hItem, 1, 0, "Item");
      // USER START (Optionally insert additional code for further widget initialization)
      // WM_CreateTimer(pMsg->hWin, 0, 500, 0);
      // USER END
      break;

      case WM_TIMER:
      //
      // If the timer expires we set another color for the background and the text
      //
      hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
      LISTVIEW_SetBkColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
      Index ^= 1;
      LISTVIEW_SetTextColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
      //
      // Restart the timer, 0 = period like on creation
      //
      WM_RestartTimer((WM_HTIMER)pMsg->Data.v, 0);
      break;

      case WM_USER:
      WM_CreateTimer(pMsg->hWin, 0, 500, 0);
      break;

      case WM_NOTIFY_PARENT:
      Id = WM_GetId(pMsg->hWinSrc);
      NCode = pMsg->Data.v;
      switch(Id) {
      case ID_LISTVIEW_0: // Notifications sent by 'Listview'
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
      // USER START (Optionally insert code for reacting on notification message)
      // USER END
      break;
      case WM_NOTIFICATION_RELEASED:
      // USER START (Optionally insert code for reacting on notification message)
      // USER END
      break;
      case WM_NOTIFICATION_SEL_CHANGED:
      // USER START (Optionally insert code for reacting on notification message)
      // USER END
      break;
      // USER START (Optionally insert additional code for further notification handling)
      // USER END
      }
      break;
      // USER START (Optionally insert additional code for further Ids)
      // USER END
      }
      break;
      // USER START (Optionally insert additional message handling)
      // USER END
      default:
      WM_DefaultProc(pMsg);
      break;
      }
      }

      /*********************************************************************
      *
      * Public code
      *
      **********************************************************************
      */
      /*********************************************************************
      *
      * CreateWindow
      */
      WM_HWIN CreateLISTAWindow(void);
      WM_HWIN CreateLISTAWindow(void) {
      WM_HWIN hWin;

      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      return hWin;
      }

      // USER START (Optionally insert additional public code)
      // USER END

      /*************************** End of file ****************************/
    • Hi,

      did you implemented the following functions properly?

      GUI_X_GetTime()
      GUI_X_Delay(int Period)

      The first function should return a a timer value which gets incremented each millisecond and the second should perform a delay for the given period in milliseconds.

      Without these functions, you can't use any timer related functions (like WM_CreateTimer()).

      You can either set up a hardware timer which increments a variable each ms or use the timer related API of an RTOS (like embOS).

      I have attached some example files which show how to implement the functions above (and some others as well).

      Regards
      Sven
      Files
      • GUI_X.zip

        (10.51 kB, downloaded 45 times, last: )
    • The functions are correct since I had already imported the GUI_X.c file. By the way if I use the GUI_Delay(100) I notive that the code gets stuck inside this function. For this reason I started using GUI_Exec() to update the widgets.

      Could my problem be related to the non-functioning of the GUI_Delay() function?
      And in this case, why does the code get stuck inside the function?
      Thanks
    • I tried with a timer interrupt that occurs every few seconds: in the interrupt the only thing I do is:

      C Source Code

      1. WM_SendMessageNoPara(hItem, USER_MESSAGE);



      Then inside static void _cbDialog(WM_MESSAGE * pMsg), I added a new case for USER_MESSAGE:

      C Source Code

      1. case WM_USER: hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0); LISTVIEW_SetBkColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]); Index ^= 1; LISTVIEW_SetTextColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]); break;



      The USER_MESSAGE is defined as:

      C Source Code

      1. #define USER_MESSAGE WM_USER + 0x00



      What I believe is that, once WM_SendMessageNoPara() inside the interrupt is called, the code does not move to the callback _cbDialog() and does not execute the code inside case WM_USER.


      My question is: why doesn't this happen? I think that once WM_SendMessageNoPara() is called the code automatically moves to the callback _cbDialog(), right?