Animation : filling a rectangle with an ellipse

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

  • Animation : filling a rectangle with an ellipse

    Hello.
    I need to play a little animation : I want to fill a rectangle at the bottom using an ellipse.

    Here is my code :


    GUI_SetColor(0);
    GUI_DrawRect(100,100,200,150);
    for (idx = 0; idx <100; idx++)
    {
    GUI_AA_FillEllipse(100+50,150+20-idx,50,20);
    GUI_ClearRect(100,151,200,350);
    GUI_ClearRect(100,0,200,99);
    GUI_Delay(50);
    }


    while(1);


    My Rectangle is filled , but I can see sometimes the ellipse before to be cleaned...
    I think I need to use 2 buffers or Memdev service but I don't know how I can use it.
    Is anybody can help me ?
    Thanks a lot in advance.
  • Hi,

    You can enable automatic use of memory devices by calling WM_SetCreateFlags(WM_CF_MEMDEV). Call this function before GUI_Init() so the desktop window (WM_HBKWIN) can make use of the memory devices, too.

    Here is a simple sample which does almost what you want. I use a window for the drawing operation and an animation for calculating the y-position for the ellipse. The filling process starts on a button press.

    C Source Code

    1. #include "DIALOG.h"
    2. #define ANIMATION_TIME 1000
    3. #define RADIUS_ELLIPSE 20
    4. static int _DoAnim;
    5. static int _AnimDir;
    6. static int _yPos;
    7. /*********************************************************************
    8. *
    9. * _AnimateWin
    10. */
    11. static void _AnimateWin(GUI_ANIM_INFO * pInfo, void * pVoid) {
    12. WM_HWIN hWin;
    13. int ySize;
    14. hWin = WM_GetFirstChild(WM_HBKWIN);
    15. ySize = WM_GetWindowSizeY(hWin) + RADIUS_ELLIPSE;
    16. //
    17. // Calculate the y-position for the ellipse
    18. //
    19. if (_AnimDir) {
    20. _yPos = ySize - ((ySize * pInfo->Pos) / GUI_ANIM_RANGE);
    21. } else {
    22. _yPos = (ySize * pInfo->Pos) / GUI_ANIM_RANGE;
    23. }
    24. switch (pInfo->State) {
    25. case GUI_ANIM_START:
    26. break;
    27. case GUI_ANIM_END:
    28. //
    29. // At the end of an animation we change the 'direction' for the next animation
    30. //
    31. _AnimDir = (_AnimDir) ? 0 : 1;
    32. break;
    33. }
    34. hWin = WM_GetFirstChild(WM_HBKWIN);
    35. WM_Invalidate(hWin);
    36. //
    37. // Avoid compiler warnings
    38. //
    39. GUI_USE_PARA(pVoid);
    40. }
    41. /*********************************************************************
    42. *
    43. * _cbWin
    44. */
    45. static void _cbWin(WM_MESSAGE * pMsg) {
    46. GUI_RECT Rect;
    47. switch (pMsg->MsgId) {
    48. case WM_PAINT:
    49. //
    50. // Set a back ground color and clear the window area with it.
    51. // It clears only the window area.
    52. //
    53. GUI_SetBkColor(GUI_BLACK);
    54. GUI_Clear();
    55. //
    56. // Receive client area of this window
    57. //
    58. WM_GetClientRect(&Rect);
    59. //
    60. // Set a foreground color and draw a frame and the ellipse at the calculated y-position.
    61. //
    62. GUI_SetColor(GUI_WHITE);
    63. GUI_DrawRectEx(&Rect);
    64. GUI_AA_FillEllipse(Rect.x1 / 2, Rect.y1 - _yPos + RADIUS_ELLIPSE, Rect.x1 / 2, RADIUS_ELLIPSE);
    65. //
    66. // The ellipse covers just a small area so we fill the rest with a restangle
    67. //
    68. GUI_FillRect(Rect.x0, Rect.y1 - _yPos + RADIUS_ELLIPSE, Rect.x1, Rect.y1);
    69. break;
    70. default:
    71. //
    72. // Any other messages are getting handled by the default callback
    73. //
    74. WM_DefaultProc(pMsg);
    75. break;
    76. }
    77. }
    78. /*********************************************************************
    79. *
    80. * _cbBk
    81. */
    82. static void _cbBk(WM_MESSAGE * pMsg) {
    83. int NCode;
    84. int Id;
    85. int xSize;
    86. int ySize;
    87. switch (pMsg->MsgId) {
    88. case WM_PAINT:
    89. GUI_Clear();
    90. break;
    91. case WM_NOTIFY_PARENT:
    92. Id = WM_GetId(pMsg->hWinSrc);
    93. NCode = pMsg->Data.v;
    94. switch(Id) {
    95. case GUI_ID_BUTTON0: // Notifications sent by 'Button'
    96. switch(NCode) {
    97. case WM_NOTIFICATION_CLICKED:
    98. break;
    99. case WM_NOTIFICATION_RELEASED:
    100. //
    101. // Set flag for starting animation
    102. //
    103. _DoAnim = 1;
    104. break;
    105. }
    106. break;
    107. }
    108. break;
    109. default:
    110. WM_DefaultProc(pMsg);
    111. break;
    112. }
    113. }
    114. /*********************************************************************
    115. *
    116. * Public code
    117. *
    118. **********************************************************************
    119. */
    120. /*********************************************************************
    121. *
    122. * MainTask()
    123. */
    124. void MainTask(void);
    125. void MainTask(void) {
    126. GUI_ANIM_HANDLE hAnim;
    127. WM_HWIN hWin;
    128. WM_HWIN hButton;
    129. //
    130. // Set create flag to use automatically memory devices, this is one way to avoid flickering.
    131. // Call this before GUI_Init() to set this flag for the desktop window, too. The desktop
    132. // window gets created in GUI_Init().
    133. //
    134. WM_SetCreateFlags(WM_CF_MEMDEV);
    135. GUI_Init();
    136. //
    137. // Set a callback for the desktop window. The callback handles the drawing of the window
    138. // and message send from the button.
    139. //
    140. WM_SetCallback(WM_HBKWIN, _cbBk);
    141. //
    142. // Create a simple window which does the drawing of the ellipse.
    143. //
    144. WM_CreateWindowAsChild(100, 100, 200, 150, WM_HBKWIN, WM_CF_SHOW, _cbWin, 0);
    145. //
    146. // Create a button as child of the desktop window. This button starts the animation.
    147. //
    148. hButton = BUTTON_CreateAsChild(10, 10, 60, 30, WM_HBKWIN, GUI_ID_BUTTON0, WM_CF_SHOW);
    149. BUTTON_SetText(hButton, "Start");
    150. while(1) {
    151. //
    152. // If the flag is set we create and start an animation
    153. //
    154. if (_DoAnim) {
    155. hAnim = GUI_ANIM_Create(ANIMATION_TIME, 10, 0, 0); // Create an animation which should last for the given time period.
    156. GUI_ANIM_AddItem(hAnim, 0, ANIMATION_TIME, ANIM_LINEAR, 0, _AnimateWin); // Add an animation item, this handles the calculation of an intensity.
    157. GUI_ANIM_Start(hAnim); // Start the animation
    158. while (GUI_ANIM_Exec(hAnim) == 0) { // As long as the animation lasts we call GUI_Delay(). This allows the
    159. GUI_Delay(5); // window manager to redraw the screen and other tasks can be escuted, too.
    160. }
    161. //
    162. // Once finished, delete animation and restore flag
    163. //
    164. GUI_ANIM_Delete(hAnim);
    165. _DoAnim = 0;
    166. } else {
    167. GUI_Delay(5);
    168. }
    169. }
    170. }
    Display All


    Regards,
    Sven
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.