Drawing graphs using GUI_AA_DrawLine redrawing issue

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

    • Drawing graphs using GUI_AA_DrawLine redrawing issue


      I'm developing an application with an x-y graph using GUI_AA_DrawLine of the single data steps (I need something different than the visual appearance of the GRAPH widget).

      I call this function inside the WM_PAINT case of the respective window callback but the desired result is obtained only if I draw also the previous steps of the graph (I use WM_InvalidateWindow when I want to redraw the window).
      Here is some code:

      Source Code

      1. case WM_PAINT:
      2. GUI_SetColor(GUI_RED);
      3. GUI_SetPenSize(2);
      4. for (ix = 0; ix < point_index; ix++)
      5. {
      6. GUI_AA_DrawLine(aRedPoints[ix].x,
      7. aRedPoints[ix].y,aRedPoints[ix+1].x, aRedPoints[ix+1].y);
      8. }
      9. break;
      10. case WM_TIMER:
      11. WM_RestartTimer(pMsg->Data.v, 100);
      12. if (point_index > 48)
      13. point_index = 0;
      14. else
      15. point_index++;
      16. break;
      Display All

      Is there any way to retain the previous steps of the graph without having to redrawing all the steps every time?
      I want to plot up to 3 graphs like that on the same window so I need to decrease the drawing operations every time I need to update a graph.

      Also any similar examples of continuous line drawing will be highly appreciated!

      Thank you!

    • Hello,

      first you can just create a memory device (if your emWin package contains that option) filled with transparency.

      C Source Code

      1. GUI_MEMDEV_Handle hMem;
      2. ...
      3. // suppose your window or graph area size is 320 * 240
      4. hMem = GUI_MEMDEV_CreateFixed32(0, 0, 320, 240);
      5. GUI_MEMDEV_Select(hMem);
      6. GUI_SetBkColor(GUI_TRANSPARENT);
      7. GUI_Clear();
      8. GUI_MEMDEV_Select(0);
      9. ...

      Then you draw the curve lines into the memory device and copy its content to the screen in WM_PAINT.
      Memory device will keep the previous curve line

      C Source Code

      1. ...
      2. case WM_PAINT:
      3. GUI_MEMDEV_Select(hMem);
      4. GUI_SetColor(GUI_RED);
      5. GUI_SetPenSize(2);
      6. // initial value of ix must be 0
      7. GUI_AA_DrawLine(aRedPoints[ix].x,
      8. aRedPoints[ix].y,aRedPoints[ix+1].x, aRedPoints[ix+1].y);
      9. ix++; // just here or in WM_TIMER
      10. GUI_MEMDEV_Select(0);
      11. GUI_MEMDEV_Write(hMem);
      12. // or GUI_MEMDEV_WriteAt() if the original points of the graph and memory device are not matching
      13. break;
      14. ...
      Display All

      Just curious why GRAPH widget with XY data is no good for you... :)


      The post was edited 5 times, last by LexaGb ().

    • LexaGb wrote:

      Just curious why GRAPH widget with XY data is no good for you... :)
      Thank you for your answer, Alex!

      I did not use GRAPH widget because it looked easier to me to start from an empty object rather than customize an existing one (there's a fixed grid image on the background and one graph has a different starting point among the others...).

      I tried your proposed solution but it gave me some problems when I change application window and I create again the window with the MEMDEV.
      I didn't understand yet if it something related to multilayer management or if I'm missing something regarding MEMDEV.

      Basically the application with the graph has two layers: one for the background and one for the objects (buttons, text and the graph itself).

      Source Code

      1. hWinSupply_Layer_N0 = GUI_CreateDialogBox(_aWinSupplyDialogCreate_Layer_N0, GUI_COUNTOF(_aWinSupplyDialogCreate_Layer_N0), _cbDialogWinSupply_Layer_N0, WM_GetDesktopWindowEx(0), 0, 0);
      2. hWinSupply_Layer_N1 = GUI_CreateDialogBox(_aWinSupplyDialogCreate_Layer_N1, GUI_COUNTOF(_aWinSupplyDialogCreate_Layer_N1), _cbDialogWinSupply_Layer_N1, WM_GetDesktopWindowEx(1), 0, 0);

      In the layer #0 callback there is just an image and a couple of drawing instructions

      In the layer #1 callback there is the implementation of the graph:

      Source Code

      1. static void _cbDialogWinSupply_Layer_N1(WM_MESSAGE * pMsg)
      2. {
      3. ...
      4. case WM_INIT_DIALOG:
      5. ...
      6. hGraphMemDev = GUI_MEMDEV_CreateFixed32(79, 11, 79+258, 11+88);
      7. GUI_MEMDEV_Select(hGraphMemDev);
      8. GUI_SetBkColor(GUI_TRANSPARENT);
      9. GUI_Clear();
      10. GUI_MEMDEV_Select(0);
      11. ...
      12. break;
      13. case WM_PAINT:
      14. GUI_MEMDEV_Select(hGraphMemDev);
      15. // Some drawing operations GUI_DrawLine etc..
      16. GUI_MEMDEV_Select(0);
      17. GUI_MEMDEV_Write(hGraphMemDev);
      18. break;
      19. ...
      20. }
      Display All
      Before closing this application and going to another application of the GUI (that have only one layer) :

      Source Code

      1. WM_HWIN hItem;
      2. //Hide layer #1
      3. GUI_SetLayerVisEx (1, 0);
      4. //Delete GUI_MEMDEV
      5. if (hGraphMemDev != 0)
      6. GUI_MEMDEV_Delete(hGraphMemDev);
      7. hItem = WM_GetDialogItem(hWinSupply_Layer_N0,IDGUISUPPLY_LAYER_N0_WINDOW);
      8. WM_EnableWindow(hItem);
      9. hItem = WM_GetDialogItem(hWinSupply_Layer_N1, IDGUISUPPLY_LAYER_N1_WINDOW);
      10. WM_EnableWindow(hItem);
      11. ...
      12. //Create dialog of the other application page
      13. hWinMain = GUI_CreateDialogBox(_aWinMainDialogCreate, GUI_COUNTOF(_aWinMainDialogCreate), _cbDialogWinMain, WM_GetDesktopWindowEx(0), 0, 0);
      14. WM_Exec();
      15. //Delete previous pages
      16. GUI_EndDialog (hWinSupply_Layer_N0, 0);
      17. GUI_EndDialog (hWinSupply_Layer_N1, 0);
      Display All

      When I come from a single layer page and I generate this two layer page, the redrawing of the layer #0 doesn't happen so the result is I have the old application layer #0 and the new application layer #1

      If I don't use the MEMDEV functions in the WM_PAINT as I did, I don't encounter any problem (both layers were drawn correctly).

      Any idea or any suggestion on what it may cause this behavior or any mistake I made?

      Thank you!

      Best regards,
    • Hello, Mark,

      yes, GRAPH widget is not so easy, but when you get it about user draw function, you will able to draw a custom grid and manipulate the data to move the curves along the axes.

      Regarding the layers' contents: it's hard for me to say why the layer #0 data is visible together with the layer #1 data on your side.

      Just made a simple code with two layers (in simulation using SoftLayer feature).

      Layer #0 with a background window, layer #1 with a background window and main window with a memory device writing in WM_PAINT.

      And there is no problem with switching the layers on my side.