Swipe between pages in a Window Dialog

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

    • Swipe between pages in a Window Dialog

      Hello,

      I would like to create something similar to what I've depicted below, a dialog made of 4 full-screen "pages" (each page has its own widgets) that the user can navigate through a swipe gesture.
      I usually create a Window dialog with its child objects with the GUI_WIDGET_CREATE_INFO approach for the individual pages but I'm not sure if this is the correct approach.
      So far I've taken the Move Windows sample as a reference:
      wiki.segger.com/WM_MOTION_-_Move_windows_(Sample)

      I've created a DialogBox and, in the WM_INIT_DIALOG case of the dialog, I've created a Child window and some buttons:

      Source Code

      1. //Dialog creation
      2. hWinMultiPage = GUI_CreateDialogBox(_aGUIMULTIPAGE_MainWinDialogCreate, GUI_COUNTOF(_aGUIMULTIPAGE_MainWinDialogCreate), _cbDialogGUIMULTIPAGE_MainWin, WM_GetDesktopWindowEx(0), 0, 0);
      3. ...
      4. //Dialog callback
      5. static void _cbDialogGUIMULTIPAGE_MainWin(WM_MESSAGE * pMsg) {
      6. WM_HWIN hItem;
      7. WM_HWIN hChildWin;
      8. // USER START (Optionally insert additional variables)
      9. int NCode;
      10. int Id;
      11. uint16_t ix;
      12. int xSize;
      13. int ySize;
      14. // USER END
      15. switch (pMsg->MsgId) {
      16. case WM_INIT_DIALOG:
      17. //
      18. // Initialization of 'Window'
      19. //
      20. hItem = pMsg->hWin;
      21. //Create window as child
      22. hChildWin = WM_CreateWindowAsChild(0, 0, (GUI_XSIZE_PHYS*4), GUI_YSIZE_PHYS, hItem, WM_CF_SHOW | WM_CF_MOTION_X, _cbChildWin, 0);
      23. //Add some buttons
      24. BUTTON_CreateEx(20, 20, 100, 100, hChildWin, WM_CF_SHOW, 0, GUIMULTIPAGE_ID_TEST_01_BTN);
      25. BUTTON_CreateEx(20 + 240*1, 20, 100, 100, hChildWin, WM_CF_SHOW, 0, GUIMULTIPAGE_ID_TEST_02_BTN);
      26. BUTTON_CreateEx(20 + 240*2, 20, 100, 100, hChildWin, WM_CF_SHOW, 0, GUIMULTIPAGE_ID_TEST_03_BTN);
      27. BUTTON_CreateEx(20 + 240*3, 20, 100, 100, hChildWin, WM_CF_SHOW, 0, GUIMULTIPAGE_ID_TEST_04_BTN);
      Display All
      I've used the same code of the example for the Child window adding the WM_NOTIFY_PARENT to get the buttons notifications and it looks fine to me.

      So, at the moment, the WM_MOTION looks like:

      Source Code

      1. //Inside _cbChildWin callback
      2. case WM_MOTION:
      3. pInfo = (WM_MOTION_INFO *)pMsg->Data.p;
      4. switch (pInfo->Cmd) {
      5. case WM_MOTION_INIT:
      6. WM_GetClientRectEx(pMsg->hWin, &Rect);
      7. //
      8. // Snap window at each quarter of the entire window
      9. // Therefore we get several 'pages', each as big as the screen
      10. //
      11. pInfo->SnapX = (Rect.x1 + 1) / 4;
      12. break;
      13. }
      14. break;
      Display All

      The two things I would like to achieve are:

      - I want the swipe movement to end at the start of the next page, no "in between" situations. So when I swipe from page#1 to page#2 I will see a full screen page#2.

      - I want to be able to start the visualization (entering from other windows of the GUI) from a different page than #1 (let's say Page #3 or Page#4) in some cases.

      Could anybody supply a guideline code to achieve the described behavior?
      Thank you in advance!
      Mark
      Images
      • 4pages_swipe.png

        15.53 kB, 800×400, viewed 336 times

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

    • I've managed to make the Snap function working, I was calling periodically WM_Exec() but not GUI_Delay(1) and I guess this was not refreshing some internal library counters.

      I've still a couple of questions if anybody can help me...
      Is there an effective way to know when the motion is in progress (and when it ends) to differentiate the touch button pressed/released from the motion event?
      I want to avoid the buttons to be activated when the user is swiping between the pages.

      Thank you!
      Mark
    • Hello,

      as for the getting whether the motion is in progress or not: I'd just define a variable and set / clear it when processing motion messages. Also as I've noticed the motion is blocking on its own and we need to use GUI_Exec1() for "diving into" that processing and get an access to that variable.

      As for the avoiding buttons react on touch when motion is in progress, oh, I think it's difficult: when you click on a window / widget first WM calls WM_MOTION message and only then it calls touch messages. I think this is because your hardware "doesn't know" what are you going to do: a swipe or just a release your PID back. We see the same things in our smartphones when we swipe on desktop and we see that an icon under the finger is changed its look when motion starts. Smartphone GUI engine differentiates between fast click on an icon to start an app and long click just for a swipe. I'd look at the problem form a different angle: just set a custom paint function for the same look in clicked / released state.

      My code looked like this:

      C Source Code

      1. #include "DIALOG.h"
      2. #include "stdio.h"
      3. WM_HWIN hWinSwipe, hWinParent;
      4. TEXT_Handle hText;
      5. int _Motion = 0, _xPos = 0;
      6. void _cbButton(WM_MESSAGE * pMsg) {
      7. GUI_RECT Rect;
      8. switch (pMsg->MsgId) {
      9. case WM_PAINT:
      10. WM_GetClientRect(&Rect);
      11. GUI_SetBkColor(GUI_LIGHTGRAY);
      12. GUI_ClearRectEx(&Rect);
      13. GUI_SetFont(GUI_FONT_20_ASCII);
      14. GUI_SetColor(GUI_BLACK);
      15. GUI_SetTextMode(GUI_TM_TRANS);
      16. GUI_DispStringInRect("Button", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
      17. break;
      18. case WM_MOTION:
      19. WM_SendToParent(pMsg->hWin, pMsg);
      20. break;
      21. default:
      22. BUTTON_Callback(pMsg);
      23. break;
      24. }
      25. }
      26. void _cbWinSwipe(WM_MESSAGE * pMsg) {
      27. WM_MOTION_INFO * pInfo;
      28. WM_HWIN hItem;
      29. int i, j;
      30. char str[10];
      31. switch (pMsg->MsgId) {
      32. case WM_CREATE:
      33. for (i = GUI_ID_BUTTON0, j = 0; i <= GUI_ID_BUTTON2; i++, j += 240) {
      34. hItem = BUTTON_CreateEx(60 + j, 200, 120, 80, pMsg->hWin, WM_CF_SHOW, 0, i);
      35. WM_SetCallback(hItem, _cbButton);
      36. }
      37. break;
      38. case WM_MOTION:
      39. pInfo = (WM_MOTION_INFO *)pMsg->Data.p;
      40. switch (pInfo->Cmd) {
      41. case WM_MOTION_INIT:
      42. pInfo->Flags = WM_CF_MOTION_X | WM_MOTION_MANAGE_BY_WINDOW;
      43. pInfo->SnapX = 240;
      44. pInfo->Overlap = 30;
      45. break;
      46. case WM_MOTION_MOVE:
      47. _Motion = 1;
      48. _xPos += pInfo->dx;
      49. if ((_xPos < -510) || (_xPos > 30)) {
      50. _xPos = (_xPos > 30) ? 30 : -510;
      51. pInfo->IsOutside = 1;
      52. pInfo->StopMotion = pInfo->IsDragging ^ 1;
      53. }
      54. if (pInfo->FinalMove)
      55. _Motion = 0;
      56. WM_MoveTo(pMsg->hWin, _xPos, 0);
      57. break;
      58. case WM_MOTION_GETPOS:
      59. pInfo->xPos = _xPos;
      60. break;
      61. }
      62. break;
      63. case WM_PAINT:
      64. GUI_SetBkColor(GUI_RED);
      65. GUI_ClearRect(0, 0, 239, 319);
      66. GUI_SetBkColor(GUI_ORANGE);
      67. GUI_ClearRect(240, 0, 479, 319);
      68. GUI_SetBkColor(GUI_DARKGREEN);
      69. GUI_ClearRect(480, 0, 719, 319);
      70. GUI_SetFont(GUI_FONT_20_ASCII);
      71. GUI_SetColor(GUI_BLACK);
      72. GUI_SetTextMode(GUI_TM_TRANS);
      73. for (i = 0, j = 0; i < 3; i++, j += 240) {
      74. sprintf(str, "Page %d", i + 1);
      75. GUI_DispStringHCenterAt(str, 120 + j, 50);
      76. }
      77. break;
      78. default:
      79. WM_DefaultProc(pMsg);
      80. break;
      81. }
      82. }
      83. void _CheckMotion(void) {
      84. char str[32];
      85. sprintf(str, "Motion: %s", _Motion ? "ongoing" : "stopped");
      86. TEXT_SetText(hText, str);
      87. }
      88. void MainTask(void) {
      89. GUI_Init();
      90. WM_MOTION_Enable(1);
      91. WM_MULTIBUF_Enable(1);
      92. WM_SetDesktopColor(GUI_BLACK);
      93. hWinParent = WINDOW_CreateEx(0, 0, 240, 320, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_USER + 0, NULL);
      94. WINDOW_SetBkColor(hWinParent, GUI_BLACK);
      95. hWinSwipe = WM_CreateWindowAsChild(0, 0, 720, 320, hWinParent, WM_CF_SHOW, _cbWinSwipe, 0);
      96. hText = TEXT_CreateEx(0, 320, 240, 30, WM_HBKWIN, WM_CF_SHOW, TEXT_CF_HCENTER | TEXT_CF_VCENTER, GUI_ID_TEXT0, "");
      97. TEXT_SetFont(hText, GUI_FONT_20_ASCII);
      98. TEXT_SetTextColor(hText, GUI_WHITE);
      99. while (1) {
      100. _CheckMotion();
      101. GUI_Exec1();
      102. }
      103. }
      Display All
      Regards,

      Anthony

      The post was edited 2 times, last by cilmagemlu ().