Partial visualization of a bitmap / multilayer bar graph

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

    • Partial visualization of a bitmap / multilayer bar graph

      Hello,

      I have to develop a bar graph as depicted in the attached image, with two independent variables (red and light blue) that colorize the grey steps according to their value.
      I was thinking drawing the gray bar graph (as a bmp/png) on layer #0 and partially plotting on layer #1 the color bars (as a bmp/png) with transparent background but I couldn't find a function that draws only a part of the bitmap.
      Moreover the bitmaps are intended to start from the top left corner so it looks like that my idea is not feasible.

      Any idea/examples of how can this be achieved with fast computation as well?
      Memory devices usage?

      Thank you for your support.

      Best regards,
      Mark
      Images
      • demo_bargraph.png

        4.68 kB, 80×320, viewed 435 times
    • Hello,

      maybe we should place two scales (gray and colored) at one position in an exact matching using IMAGE widgets.

      Then invalidate colored bar image within the area related to the bar value using WM_SetUserClipRect() function.

      Just a simple code:

      C Source Code

      1. #include "DIALOG.h"
      2. // Bitmaps for the bars, in attach
      3. extern GUI_CONST_STORAGE GUI_BITMAP bmimg_bar_gray;
      4. extern GUI_CONST_STORAGE GUI_BITMAP bmimg_bar_red;
      5. // Image widgets' handlers;
      6. IMAGE_Handle hImgBrGr, hImgBrRd;
      7. // Bar value (0 - 100)
      8. // Delta for ticking the bar up / down
      9. // y0 for invalidating the red image widget area related to the bar value
      10. int _BarValue = 0, _Delta = 1, y0;
      11. // Red bar image widget callback
      12. void _cbImgRd(WM_MESSAGE * pMsg) {
      13. GUI_RECT Rect;
      14. switch (pMsg->MsgId) {
      15. case WM_PAINT:
      16. // Get whole image rect
      17. WM_GetClientRect(&Rect);
      18. // y0 correction related to the bar value
      19. Rect.y0 = y0;
      20. // Set area for invalidating the red bar image
      21. WM_SetUserClipRect(&Rect);
      22. // Draw the image within the area
      23. IMAGE_Callback(pMsg);
      24. // Restore default clipping area
      25. WM_SetUserClipRect(NULL);
      26. break;
      27. default:
      28. IMAGE_Callback(pMsg);
      29. break;
      30. }
      31. }
      32. void MainTask(void) {
      33. GUI_Init();
      34. WM_MULTIBUF_Enable(1);
      35. // Create gray and red bar image widgets and set related bitmaps
      36. hImgBrGr = IMAGE_CreateEx(50, 10, 36, 239, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_IMAGE0);
      37. IMAGE_SetBitmap(hImgBrGr, &bmimg_bar_gray);
      38. hImgBrRd = IMAGE_CreateEx(50, 10, 36, 239, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_IMAGE1);
      39. IMAGE_SetBitmap(hImgBrRd, &bmimg_bar_red);
      40. // Set callback for the red bar image widget
      41. WM_SetCallback(hImgBrRd, _cbImgRd);
      42. // Initial value for y0
      43. y0 = 238;
      44. while (1)
      45. {
      46. GUI_Delay(50);
      47. // Ticking the bar value up / down
      48. _BarValue += _Delta;
      49. // Calc y0 related to the bar value
      50. // 20 pixels is the height of the one "piece"
      51. // Invalidate the red bar image widget to redraw it
      52. if ((_BarValue % 8) == 0)
      53. {
      54. y0 -= 20 * _Delta;
      55. WM_Invalidate(hImgBrRd);
      56. }
      57. // Change ticking direction up / down
      58. // Reinit value for y0
      59. if ((_BarValue == 100) || (_BarValue == 0))
      60. {
      61. _Delta = -_Delta;
      62. y0 = y0 < 0 ? 0 : 238;
      63. }
      64. }
      65. }
      Display All
      Alex.
      Files
      • imgs.zip

        (9.71 kB, downloaded 418 times, last: )
    • LexaGb wrote:

      Hello,

      maybe we should place two scales (gray and colored) at one position in an exact matching using IMAGE widgets.

      Then invalidate colored bar image within the area related to the bar value using WM_SetUserClipRect() function.

      Just a simple code:

      C Source Code

      1. #include "DIALOG.h"
      2. // Bitmaps for the bars, in attach
      3. extern GUI_CONST_STORAGE GUI_BITMAP bmimg_bar_gray;
      4. extern GUI_CONST_STORAGE GUI_BITMAP bmimg_bar_red;
      5. // Image widgets' handlers;
      6. IMAGE_Handle hImgBrGr, hImgBrRd;
      7. // Bar value (0 - 100)
      8. // Delta for ticking the bar up / down
      9. // y0 for invalidating the red image widget area related to the bar value
      10. int _BarValue = 0, _Delta = 1, y0;
      11. // Red bar image widget callback
      12. void _cbImgRd(WM_MESSAGE * pMsg) {
      13. GUI_RECT Rect;
      14. switch (pMsg->MsgId) {
      15. case WM_PAINT:
      16. // Get whole image rect
      17. WM_GetClientRect(&Rect);
      18. // y0 correction related to the bar value
      19. Rect.y0 = y0;
      20. // Set area for invalidating the red bar image
      21. WM_SetUserClipRect(&Rect);
      22. // Draw the image within the area
      23. IMAGE_Callback(pMsg);
      24. // Restore default clipping area
      25. WM_SetUserClipRect(NULL);
      26. break;
      27. default:
      28. IMAGE_Callback(pMsg);
      29. break;
      30. }
      31. }
      32. void MainTask(void) {
      33. GUI_Init();
      34. WM_MULTIBUF_Enable(1);
      35. // Create gray and red bar image widgets and set related bitmaps
      36. hImgBrGr = IMAGE_CreateEx(50, 10, 36, 239, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_IMAGE0);
      37. IMAGE_SetBitmap(hImgBrGr, &bmimg_bar_gray);
      38. hImgBrRd = IMAGE_CreateEx(50, 10, 36, 239, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_IMAGE1);
      39. IMAGE_SetBitmap(hImgBrRd, &bmimg_bar_red);
      40. // Set callback for the red bar image widget
      41. WM_SetCallback(hImgBrRd, _cbImgRd);
      42. // Initial value for y0
      43. y0 = 238;
      44. while (1)
      45. {
      46. GUI_Delay(50);
      47. // Ticking the bar value up / down
      48. _BarValue += _Delta;
      49. // Calc y0 related to the bar value
      50. // 20 pixels is the height of the one "piece"
      51. // Invalidate the red bar image widget to redraw it
      52. if ((_BarValue % 8) == 0)
      53. {
      54. y0 -= 20 * _Delta;
      55. WM_Invalidate(hImgBrRd);
      56. }
      57. // Change ticking direction up / down
      58. // Reinit value for y0
      59. if ((_BarValue == 100) || (_BarValue == 0))
      60. {
      61. _Delta = -_Delta;
      62. y0 = y0 < 0 ? 0 : 238;
      63. }
      64. }
      65. }
      Display All
      Alex.
      Hi Alex,

      thank you for your answer and your useful example, I think that WM_SetUserClipRect() was the function I was looking for!

      Bests,
      Mark