Handle redraw of specific parts of a dialog

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

    • Handle redraw of specific parts of a dialog

      Hello,

      I have a GIF animation which I want to continuously show on a dialog window based on a variable. Currently the animation works but it slows down the system.
      I have a function which is called every 25msec in my super loop while(1). In the function I get the Sub image from the GIF image and call WM_InvalidateArea to update only the rectangle area of the GIF image shown. I have other areas too for which I call the same WM_InvalidateArea to be updated based on other variables but this is not frequent and need to be done only on variable change.

      When WM_InvalidateArea is called it triggers the PAINT event and on paint I draw the image using GUI_GIF_DrawSub.

      So the requirements are,

      1) Update GIF area by WM_InvalidateArea called every 25msec. once the variable is set then animation is to be continuously shown until variable gets cleared.

      GUI_GIF_DrawSub is called in PAINT to handle above point.

      2) Update other area1 by WM_InvalidateArea called on 25msec but WM_InvalidateArea is called only when change in variable. Called only once if change.

      DrawOtherArea1() is called in PAINT which calls GUI_Draw_Arc1(), GUI_Draw_Arc2(), GUI_Draw_Arc3() to handle above point.

      3) Update other area2 by WM_InvalidateArea called on 25msec but WM_InvalidateArea is called only when change in variable. Called only once if change. MEMDEV is updated here

      DrawOtherArea2() is called in PAINT to handle above point.
      (This uses GUI_MEMDEV_WriteAt function)


      My PAINT function is as below

      GUI_SetBkColor(color);
      GUI_Clear();
      GUI_GIF_DrawSub(...) // Handle point 1 above

      DrawOtherArea1(); // Handle point 2 above // GUI_Draw_Arc is called 3 times to draw 3 arcs.
      DrawOtherArea2(); // Handle point 3 above // GUI_MEMDEV_WriteAt is called.

      This takes up some time due to which the system becomes slow.
      I am not sure how to handle all the 3 points at once in PAINT as currently all get drawn.

      Even if there are no updates for point 2 and point 3 whether still I have to call DrawOtherArea1() DrawOtherArea2() in PAINT?
      Are there any better ways to handle such scenario?

      Thanks
      Regards,

      Anuj

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

    • Hi,

      drawing of GIF images can become quite slow, depending on the GIF image. The more colors differ in a horizontal line, the longer it takes to draw the image. An animated gradient for example would have a big impact on performance.

      Also, the higher the index of one image to be drawn is, the longer it could take as well, since the search for the sub-image takes longer.

      To increase performance, I would suggest to convert and save the sub-images as C bitmaps or external XBF files, if your target does not have enough flash memory. Then you can display each image using a timer.

      Best regards,
      Florian
    • Hello,

      Thanks for your reply.

      Is my code correct above. if I want to update an area continuously and update different areas intermittently do I need to draw all areas in PAINT as shown in above code.

      As currently GUI_Clear is called I may have to redraw everything.
      Can GUI_Clear be avoided and clear only specific areas which have to be updated and draw only those areas.

      Thanks
      Regards,
      Anuj
    • Hi,

      a WM_PAINT case handles all the drawing operations that are done in a window. So you don't have to consider in the WM_PAINT case, which parts of the window you want to redraw.

      If you want to redraw a certain part of a window, you can use WM_InvalidateRect(). WM_InvalidateArea() redraws the specified area, but for all windows that are within the given area.

      When you're invalidating a rectangle/an area, the WM_PAINT case of the affected window (or windows) is executed as normal, except that the parts outside of the invalidated area are disregarded since they are clipped.

      Best regards,
      Florian
    • Hello,

      I was not able to understand clearly.

      My paint event is

      SetBkColor(color);
      GUI_Clear();


      if(variable1)
      {
      GIF_drawsub();
      }

      if( variable2)
      {
      variable2 = 0;
      drawArc()
      }

      if( variable3)
      {
      variable2 = 0;
      GUI_MEMDEV_WriteAt();
      }

      I want to retain the arc and memdev image drawn earlier on LCD. How do I do that?.
      As in above code I am drawing everything each time PAINT is called it takes time.

      Thanks
      Regards,
      Anuj
    • Hi,

      when calling WM_InvalidateRect() with the area specified to one of your drawings, only the parts in the area should be redrawed, as mentioned above.

      Is it possible to create a separate window for each of the three drawings you want to do? That way, you could redraw each drawing as you would like by invalidating the respective window.

      Best regards,
      Florian
    • Hi,

      Thanks for your reply.

      By "separate window" do you mean using image widget for each of the drawings? ? If yes then not sure if possible as for the first drawing I can use image widget as it is GIF which I want to show but for drawing other 2 areas I use GUI_draw_arc and GUI_MEMDEV_Writeat functions

      If you mean using separate child windows for drawing 3 areas then I think it can be done but handling will be little complex.

      Regards,
      Anuj
    • Hi,

      widgets are essentially windows, but each with specific "widget properties" (like button color etc.).

      For the GIF animation it would normally make sense to use an IMAGE widget. But since you mentioned that the performance of the animation wasn't too good, it might make sense to use a normal window instead and display the animation by drawing each frame as a bitmap, like I mentioned above. See the attached example to see how this can be done.

      For 2D-drawings it would make sense to create a window and overwrite the WM_PAINT case in the window callback to execute the drawing.

      So as long as the drawings are not overlapping, this will make it easier for you to control which part should be redrawn by just calling WM_Invalidate() on the desired window. If the drawings overlap though, the windows have to be transparent, which can take a huge toll on performance.

      Best regards,
      Florian
      Files