Problems with GUI_SetTextMode(GUI_TM_TRANS), please help....

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

  • Problems with GUI_SetTextMode(GUI_TM_TRANS), please help....

    Dear emWin-users,

    hereby I want to ask you for some help:

    First I set a background image (converted with the Bitmap converter into c-file) and everything is working perfect. So far so good....

    GUI_SelectLayer(0); // select background layer
    GUI_DrawBitmap(&bmScreen, 0, 0);


    After that I want to display a value, e.g. a counter ( int i) which is constantly changing. It also works perfect.
    The default background behind this value is black. (a rectangle area behind the white value)

    So I use the SetTextMode-function: GUI_SetTextMode(GUI_TM_TRANS) to remove this black background in order to have only the changing value "i" in white and my image background behind it-->
    And it really shows the value without the black rectangle , but the problem is that the previous value stays and it writes the new one over it (it is not removed and overwritten, so it becomes absolutely not readable). I thing the black rectangular area is serving for deleting the old value and writes the new one over it...
    could help with some suggestions....

    Greetz
    Ivo
  • Hi Ivo,

    The area behind the text needs to be cleared/redrawn. Otherwise the previous drawn text will still be visible when the text gets drawn the second time.

    I would recommend to use the window manager to handle the redrawing.

    In the sample below I have set a custom callback for the background which handles the look of the background. In this case a gradient from black to gray.

    The window I have created displays just the text. This window gets created with a transparent 'color', so the background (gradient) will be visible. The window manager handles the clearing of the window automatically and we can draw the text without taking care about clearing the area behind the text.

    C Source Code

    1. #include "DIALOG.h"
    2. static int _Value = 0;
    3. /*********************************************************************
    4. *
    5. * _cbWin
    6. */
    7. static void _cbWin(WM_MESSAGE * pMsg) {
    8. GUI_RECT Rect;
    9. int xPos;
    10. int yPos;
    11. switch (pMsg->MsgId) {
    12. case WM_PAINT:
    13. //
    14. // Receive client area and calculate x- and y-position for the text to be displayed at
    15. //
    16. WM_GetClientRect(&Rect);
    17. xPos = Rect.x1 / 2;
    18. yPos = Rect.y1 / 2;
    19. //
    20. // Set text mode
    21. //
    22. GUI_SetTextMode(GUI_TM_TRANS);
    23. //
    24. // Display the value
    25. //
    26. GUI_DispDecAt(_Value, xPos, yPos, 3);
    27. break;
    28. default:
    29. WM_DefaultProc(pMsg);
    30. break;
    31. }
    32. }
    33. /*********************************************************************
    34. *
    35. * _cbBk
    36. */
    37. static void _cbBk(WM_MESSAGE * pMsg) {
    38. int ySize;
    39. int xSize;
    40. switch (pMsg->MsgId) {
    41. case WM_PAINT:
    42. //
    43. // Draw a gradient in the back ground over the whole screen
    44. //
    45. xSize = LCD_GetXSize() - 1;
    46. ySize = LCD_GetYSize() - 1;
    47. GUI_DrawGradientH(0, 0, xSize, ySize, GUI_BLACK, GUI_GRAY);
    48. break;
    49. default:
    50. WM_DefaultProc(pMsg);
    51. break;
    52. }
    53. }
    54. /*********************************************************************
    55. *
    56. * MainTask
    57. */
    58. void MainTask(void) {
    59. WM_HWIN hWin;
    60. WM_SetCreateFlags(WM_CF_MEMDEV);
    61. GUI_Init();
    62. //
    63. // Set a callback for the background to make sure it gets redrawn properly.
    64. //
    65. WM_SetCallback(WM_HBKWIN, _cbBk);
    66. //
    67. // Create a window which handles drawing of the text.
    68. //
    69. hWin = WM_CreateWindowAsChild(10, 10, 80, 40, WM_HBKWIN, WM_CF_SHOW | WM_CF_HASTRANS, _cbWin, 0);
    70. while (1) {
    71. //
    72. // Increment _Value
    73. //
    74. _Value = (_Value < 100) ? _Value + 1 : 0;
    75. //
    76. // Invalidate window for redrawing the value
    77. //
    78. WM_Invalidate(hWin);
    79. //
    80. // GUI_Delay, redraws all invalid windows
    81. //
    82. GUI_Delay(500);
    83. }
    84. }
    Display All


    I hope this is what you are looking for.

    Regards,
    Sven
  • Dear Sven,



    I used your code to display a chinging value as you explained, but I have some problems at one point.

    Your code with displaying a counter (i++) and redrawing it every time when it changes works fine, but since I try to display a value from an external Temperature Sensor it does not work. This measured temperature I store into an Integer and when using a normal sprintf command it works, but I want to implement it into your _cbWin function.



    I will go through your code and write my comments.





    I will start with drawing the background gradient over the whole screen (800x480). This works very good.

    ----------------------------------------------------------------------



    /*********************************************************************
    *
    * _cbBk
    */
    static void _cbBk(WM_MESSAGE * pMsg) {


    int ySize = 480; --> my display is 800x480 (an external one)
    int xSize = 800;

    switch (pMsg->MsgId) {


    case WM_PAINT:
    //
    // Draw a gradient in the back ground over the whole screen
    //

    GUI_DrawGradientH(0, 0, xSize, ySize, GUI_BLACK, GUI_GRAY);
    break;
    default:
    WM_DefaultProc(pMsg);
    break;
    }
    }

    /*********************************************************************





    After that I try to display the measured value from the external temperature sensor into the _cbWin - function as you did with the counter (i-integer). I dont want to go much into detail how I get the value from the sensor in order not to get you absolutely confused, but when I use the following thing outside the _cbWin function it displays the value properly, but writes it of course over the old one when it changes without deleting the old one (since the window is not redrawn again and again, what you have already solved):

    -----------



    unsigned int value_temp; --> here the measured value is stored

    char value[10];



    GUI_SetTextMode(GUI_TM_TRANS);

    sprintf (value, "temp_value = %d", value_temp);

    GUI_DispStringAt(hnvt_str, 400, 240); --> it shows the temperature in the middle of the screen; --------------



    Here I do not exactly know how to implement the upper code into your _cbWin function: I did the following




    /*********************************************************************
    *
    * _cbWin
    */
    static void _cbWin(WM_MESSAGE * pMsg) {


    switch (pMsg->MsgId) {
    case WM_PAINT:
    //
    // Set text mode
    //
    GUI_SetTextMode(GUI_TM_TRANS);
    //
    // Display the value
    //
    GUI_DispDecAt(value_temp, 400, 240, 3); --> it shows directly zero at the beginning. It even doesnt change it.
    break;
    default:
    WM_DefaultProc(pMsg);
    break;
    }
    }




    ------------------------------------------------

    Now the main part:





    /*********************************************************************
    *
    * MainTask
    */
    void MainTask(void) {
    WM_HWIN hWin;

    WM_SetCreateFlags(WM_CF_MEMDEV);
    GUI_Init();
    //
    // Set a callback for the background to make sure it gets redrawn properly.
    //
    WM_SetCallback(WM_HBKWIN, _cbBk);
    //
    // Create a window which handles drawing of the text.
    //
    hWin = WM_CreateWindowAsChild(10, 10, 80, 40, WM_HBKWIN, WM_CF_SHOW | WM_CF_HASTRANS, _cbWin, 0);
    while (1) {
    //
    //

    //


    at this point I have to look if the value has changed and if yes to Invalidate the Window I suppose...



    //
    // Invalidate window for redrawing the value
    //
    WM_Invalidate(hWin);
    //
    // GUI_Delay, redraws all invalid windows
    //
    GUI_Delay(500);
    }
    }




    I hope you can help with this...

    Thank you in advance....



    Ivo
  • Hello Ivancho and Sven

    I am having the exact same problem.
    I tried the snippet posted by Sven.
    Doesn't work!
    The screen turns black. No image or text.
    I am trying to get over this problem endlessly for many days.

    My microcontroller is Infineon XMC4500 , with 1MB flash and 160KB RAM.

    Please reply so that I may find a solution.

    And apologies for highjacking your thread

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

  • Hello,

    Have you tried a more simple application like:

    C Source Code

    1. #include "GUI.h"
    2. void MainTask(void) {
    3. GUI_Init();
    4. //
    5. // Draw a line which should be visible behind transparent text
    6. //
    7. GUI_SetColor(GUI_GREEN);
    8. GUI_DrawHLine(4, 0, 20);
    9. //
    10. // Display a string
    11. //
    12. GUI_SetTextMode(GUI_TM_TRANS);
    13. GUI_SetColor(GUI_WHITE);
    14. GUI_DispString("Test");
    15. while (1) {
    16. GUI_Delay(100);
    17. }
    18. }
    Display All


    Regards,
    Sven
  • Hi,

    what color conversion are you using?

    Might it be possible that the alpha channel needs to be inverted?

    Try setting a back ground color for the text with inverted alpha channel. Either 0x00FFFFFF or 0xFFFFFFFF. This is just a guessing.

    If you set this color 0x00FF0000 and make a GUIClear() is the screen red or blue?
    If it is black try 0xFFFF0000.

    I'm asking this because emWin uses per default the color format ABGR, where A = 0x00 means fully opaque.
    emWin can be configured to the format ARGB with the alpha channel inverted (A = 0xFF -> fully opaque).
    You can change the format to be used by setting the compile time switch GUI_USE_ARGB to 1 and recompile the sources.
    Unfortunately, if you use a precompiled library there is not much you can do.

    Regards,
    Sven
  • Hello Sven
    My color conversion is correct it seems.
    If you set this color 0x00FF0000 and make a GUIClear() is the screen red or blue?
    If it is black try 0xFFFF0000.



    It is blue.


    Coming back to my problem.
    When I write the previous code which you shared, screen turns black. Nothing happens.
    All this beyond me right now
  • Hi,

    What GUIDRV_xx are you using?

    If you are using GUIDRV_Lin try enabling multiple buffers (3 recommended). You need a an interrupt routine which sets the new framebuffer address and enable multi buffering by WM_MULTIBUF_Enable(1).

    If you are using the GUIDRV_FlexColor use a cached version of this driver. This is done when setting up the driver in the LCDConf.c. Just write a 1 after the C in the last parameter:

    GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66720, GUIDRV_FLEXCOLOR_M24C1B8);

    Using a cached version will increase the amount of memory emWin needs to run, so it might be necessary to increase the memory allocated in GUIConf.c.

    Regards,
    Sven
  • Dear Sven

    I am using Infineon MCU
    XMC4500F100X1024
    1MB Flash, 160K SRAM
    and DAVE IDE.
    There is an app,(similar to Bean in Codewarrior) called
    GUI_SEGGERLIBRARY which gives you some options regarding configuration of the library.
    The one which I am using is without Read mode enabled, which doesn't enable Cache.

    According to your advice , I enabled Read mode to enable Cache of default 4096 bytes (it can be further increased)

    But once programmed, I get a trap signal relating to non serviced interrupt for an ADC.

    Does this mean that Enabling Read mode is required for touch screens?