DROPDOWNs and EDITs

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

    • DROPDOWNs and EDITs

      Hi Folks,

      My question is the same as:

      Problem using dropdown and edit widget

      I'm wondering what the solution to such a problem might be. I'm thinking of just disabling (WM_DisableWindow()) on all widgets except the dropdown, though again this is a bit fiddly. The other (better) solution would be to just disable widgets which are hidden by the dropdown.

      What I'd like to know is if anyone has a better way of fixing this!

      Cheers,
      Peter.
    • Hi,

      I gave it try but on my end everything is fine. After selecting an item from the dropdown only the dropdown widget has the focus. The edit widget underneath the listbox of the dropdown only gets the focus if I manually select it.

      I tried it in the simulation and on hardware, both is working fine.

      Which version of emWin are you using?
      How do process the touch input and how it gets passed to emWin?

      Maybe you get to many touch events and accidentally the edit widget gets selected selected.

      Regards,
      Sven
    • Thanks Sven,

      Unfortunately we are still running STemWin 5.40. I'm using both GUI_TOUCH_StoreStateEx() and GUI_MTOUCH_StoreEvent() to notify emWin of touch events, we are doing this from an RTOS task which is awoken on touch interrupts occurring.

      Good point about too many touches, however in order to support pan gestures I need to capture a lot of touches (for swiping/dragging) - I'll investigate to see if I can reduce the frequency of the updates to the emWin GUI task.


      Thanks,
      Peter.
    • Hi,

      The call of GUI_TOUCH_StoreStateEx() shouldn't be required.

      GUI_TOUCH_StoreStateEx() and GUI_MTOUCH_StoreEvent() are calling both GUI_PID_StoreState() indirectly.

      I'm not entirely sure, but if GUI_PID_StoreState() gets called twice with the same coordinates I can imagine that this can cause the behavior you are experiencing.


      Regards,
      Sven
    • OK, that makes sense. I'm having a few other strange errors which could be down to this. I disabled use of GUI_TOUCH_StoreStateEx() and now just use GUI_MTOUCH_StoreEvent(), however now I don't seem to be able to read a multitouch event from the buffer when reacting to WM_TOUCH or WM_GESTURE events:

      In the code below GUI_MTOUCH_IsEmpty() never returns false unfortunately.

      Source Code

      1. // Init example.
      2. WM_SetSize(WM_HBKWIN, LCD_XSIZE, LCD_YSIZE);
      3. // Enable multi buffering to hide the appearance of tearing and flickering.
      4. WM_MULTIBUF_Enable(1);
      5. // Enable motion, this allows SWIPELIST widgets to work.
      6. WM_MOTION_Enable(1);
      7. // Enable multi touch.
      8. GUI_MTOUCH_Enable(1);
      9. // Enable gestures (for swiping).
      10. WM_GESTURE_Enable(1);
      11. // Allow all windows to accept gestures.
      12. WM_SetCreateFlags(WM_CF_GESTURE);
      13. (void) GUI_Init();
      14. // React on button releases rather than touches.
      15. BUTTON_SetReactOnLevel();
      16. // We want to use UTF8.
      17. GUI_UC_SetEncodeUTF8();
      18. // Set anti-aliasing factor to GUI_AA_FACTOR.
      19. GUI_AA_SetFactor(GUI_AA_FACTOR);
      20. // Touch handling RTOS task is calling
      21. GUI_MTOUCH_StoreEvent(&pEvent, &pInput);
      22. // Example callback:
      23. static void
      24. _cbScreenCalibration (WM_MESSAGE * pMsg)
      25. {
      26. static uint8_t CalibSample = 0;
      27. GUI_MTOUCH_EVENT TouchEvent;
      28. GUI_MTOUCH_INPUT TouchState;
      29. WM_GESTURE_INFO *pGInfo;
      30. uint32_t xSize = 0;
      31. uint32_t ySize = 0;
      32. xSize = WM_GetWindowSizeX(pMsg->hWin);
      33. ySize = WM_GetWindowSizeY(pMsg->hWin);
      34. switch (pMsg->MsgId)
      35. {
      36. case WM_TOUCH:
      37. {
      38. if (!GUI_MTOUCH_IsEmpty())
      39. {
      40. GUI_MTOUCH_GetEvent(&TouchEvent);
      41. GUI_MTOUCH_GetTouchInput(&TouchEvent, &TouchState, 1);
      42. if (TouchState.Flags & GUI_MTOUCH_FLAG_UP)
      43. {
      44. // Do stuff.
      45. }
      46. }
      47. }
      Display All

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

    • Hi Sven,

      I had some more time to look into this but still cannot resolve the issue unfortunately, I've disabled multi-touch and am now just using single touch to input events to emWin. I've verified I'm getting a single touch and release event (so no spurious touch events are occurring).

      My edit widgets get their own callback:

      Source Code

      1. static void
      2. cbEdit (WM_MESSAGE * pMsg)
      3. {
      4. GUI_PID_STATE *pState;
      5. switch (pMsg->MsgId)
      6. {
      7. //**********************************************************************
      8. // Handle a touch release on the EDIT window, display the keyboard.
      9. case WM_TOUCH:
      10. {
      11. pState = (GUI_PID_STATE *) pMsg->Data.p;
      12. if (pState)
      13. {
      14. if (!pState->Pressed)
      15. {
      16. ui_Keyboard(lgWLScan, pMsg->hWin, Validate);
      17. }
      18. }
      19. break;
      20. }
      21. //**********************************************************************
      22. // Draw the custom underline bar for the edit windows.
      23. case WM_POST_PAINT:
      24. {
      25. int X, Y, Dist;
      26. X = WM_GetWindowOrgX(pMsg->hWinSrc);
      27. Y = WM_GetWindowOrgY(pMsg->hWinSrc) + \
      28. WM_GetWindowSizeY(pMsg->hWinSrc) - 1;
      29. Dist = WM_GetWindowSizeX(pMsg->hWinSrc);
      30. GUI_SetColor(GUI_LIGHTGRAY);
      31. GUI_DrawHLine(Y, X, Dist);
      32. break;
      33. }
      34. //**********************************************************************
      35. // Hand over to the default EDIT widget handler in emWin.
      36. default:
      37. {
      38. EDIT_Callback(pMsg);
      39. break;
      40. }
      41. }
      42. }
      Display All


      So on EDIT release I'm displaying a keyboard screen to take user input.

      The dropdown's get their own callback as well, but it doesn't do anything special:

      Source Code

      1. hItem = WM_GetDialogItem(pMsg->hWin, ID_SCAN_SPEED_DROPDOWN);
      2. DROPDOWN_SetItemSpacing(hItem, DROPDOWN_ITEM_SPACING);
      3. DROPDOWN_AddString(hItem, "1800 nm/min");
      4. DROPDOWN_AddString(hItem, "300 nm/min");
      5. DROPDOWN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
      6. DROPDOWN_SetBkColor(hItem, DROPDOWN_CI_UNSEL, TREC_GUI_LIGHT_BG_COLOUR);
      7. DROPDOWN_SetBkColor(hItem, DROPDOWN_CI_SEL, TREC_GUI_LIGHT_BG_COLOUR);
      8. DROPDOWN_SetBkColor(hItem, DROPDOWN_CI_SELFOCUS, TREC_GUI_LIGHT_BG_COLOUR);
      9. DROPDOWN_SetItemSpacing(hItem, DROPDOWN_ITEM_SPACING);
      10. ListHeight = (DROPDOWN_GetNumItems(hItem) \
      11. * (GUI_GetYSizeOfFont(GUI_FONT_24_1) + DROPDOWN_ITEM_SPACING));
      12. DROPDOWN_SetListHeight(hItem, ListHeight);
      13. WM_SetCallback(hItem, cbScanSpeedDropdown);
      Display All
      The DROPDOWN callback is:

      Source Code

      1. void
      2. cbScanSpeedDropdown (WM_MESSAGE *pMsg)
      3. {
      4. switch (pMsg->MsgId)
      5. {
      6. //**********************************************************************
      7. // A notification to the dropdown has been received.
      8. case WM_NOTIFY_PARENT:
      9. {
      10. switch (pMsg->Data.v)
      11. {
      12. //**************************************************************
      13. // The dropdown has been released.
      14. case WM_NOTIFICATION_SEL_CHANGED:
      15. {
      16. enum ScanSpeed ScanSpeed;
      17. ScanSpeed = (enum ScanSpeed) DROPDOWN_GetSelExp(pMsg->hWin);
      18. gWLScanParams.ScanSpeed = ScanSpeed;
      19. break;
      20. }
      21. }
      22. }
      23. //**********************************************************************
      24. // Default handling.
      25. default:
      26. {
      27. DROPDOWN_Callback(pMsg);
      28. break;
      29. }
      30. }
      31. }
      Display All
      I've attached a picture to show the issue, when the scan speed dropdown is selected and an item which sits over the sample name EDIT widget, then when I release the dropdown item the sample name edit also receives the touch release event.

      I'm puzzled.
    • A little more debugging shows me that my EDIT widgets are getting a release notification (i.e. WM_TOUCH with pState->Pressed == 0) immediately after the dropdown processing happens. There is no pState->Pressed == 1 notification from before.

      So I can probably work around this by ignoring the "spurious" release event, though at this point I am sure my touch driver is not generating a spurious release.
    • Hi Peter,

      The only way how to avoid this is to set a flag when the EDIT widget has been clicked and check this flag if it is set when you get a release from the EDIT widget.

      If the release occurs when touching the overlaying EDIT widget you will get only the release message. So, if no clicked occurred you can sort this one out.

      The release happens becasue the LISTBOX of the dropdown gets deleted right on a click on it. Now the touch is still pressed and the next release gets processed on the position of touch. In this case the EDIT is right at the touch release point and therefore the parent of the EDIT gets the WM_NOTIFICATION_RELEASED message.

      Try this:

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Externals
      5. *
      6. **********************************************************************
      7. */
      8. /*********************************************************************
      9. *
      10. * Defines
      11. *
      12. **********************************************************************
      13. */
      14. #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      15. #define ID_EDIT_0 (GUI_ID_USER + 0x01)
      16. #define ID_DROPDOWN_0 (GUI_ID_USER + 0x02)
      17. /*********************************************************************
      18. *
      19. * Static data
      20. *
      21. **********************************************************************
      22. */
      23. /*********************************************************************
      24. *
      25. * _aDialogCreate
      26. */
      27. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      28. { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
      29. { EDIT_CreateIndirect, "Edit", ID_EDIT_0, 120, 120, 80, 20, 0, 0x64, 0 },
      30. { DROPDOWN_CreateIndirect, "Dropdown", ID_DROPDOWN_0, 120, 80, 80, 80, 0, 0x0, 0 },
      31. };
      32. /*********************************************************************
      33. *
      34. * Static code
      35. *
      36. **********************************************************************
      37. */
      38. /*********************************************************************
      39. *
      40. * _cbDialog
      41. */
      42. static void _cbDialog(WM_MESSAGE * pMsg) {
      43. WM_HWIN hItem;
      44. int NCode;
      45. int Id;
      46. static int Clicked;
      47. switch (pMsg->MsgId) {
      48. case WM_INIT_DIALOG:
      49. //
      50. // Inti stuff..
      51. //
      52. break;
      53. case WM_NOTIFY_PARENT:
      54. Id = WM_GetId(pMsg->hWinSrc);
      55. NCode = pMsg->Data.v;
      56. switch(Id) {
      57. case ID_EDIT_0: // Notifications sent by 'Edit'
      58. switch(NCode) {
      59. case WM_NOTIFICATION_CLICKED:
      60. Clicked = 1;
      61. break;
      62. case WM_NOTIFICATION_RELEASED:
      63. if (Clicked) {
      64. Clicked = 0;
      65. //
      66. // React on release here
      67. //
      68. }
      69. break;
      70. case WM_NOTIFICATION_VALUE_CHANGED:
      71. break;
      72. }
      73. break;
      74. }
      75. break;
      76. default:
      77. WM_DefaultProc(pMsg);
      78. break;
      79. }
      80. }
      81. /*********************************************************************
      82. *
      83. * _cbBk
      84. */
      85. static void _cbBk(WM_MESSAGE * pMsg) {
      86. switch (pMsg->MsgId) {
      87. case WM_PAINT:
      88. GUI_SetBkColor(GUI_BLACK);
      89. GUI_Clear();
      90. break;
      91. default:
      92. WM_DefaultProc(pMsg);
      93. break;
      94. }
      95. }
      96. /*********************************************************************
      97. *
      98. * Public code
      99. *
      100. **********************************************************************
      101. */
      102. /*********************************************************************
      103. *
      104. * MainTask
      105. */
      106. void MainTask(void) {
      107. WM_SetCreateFlags(WM_CF_GESTURE);
      108. GUI_Init();
      109. WM_MULTIBUF_Enable(1);
      110. WM_MOTION_Enable(1);
      111. WM_SetCallback(WM_HBKWIN, _cbBk);
      112. GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      113. while (1) {
      114. GUI_Delay(100);
      115. }
      116. }
      117. /*************************** End of file ****************************/
      Display All

      Regards,
      Sven
    • Hi Sven,

      Thanks for replying, yeah I thought this might be the issue - I'll try to implement something like this and will get back to you. I wanted to use the user data of the edit widget to store this value, but sadly I'm already using the user data for something else! I'll give this a shot.

      Thanks,
      Peter.