ImpulseAdventure / GUIslice

GUIslice drag & drop embedded GUI in C for touchscreen TFT on Arduino, Raspberry Pi, ARM, ESP8266 / ESP32 / M5stack using Adafruit-GFX / TFT_eSPI / UTFT / SDL
https://www.impulseadventure.com/elec/guislice-gui.html
MIT License
1.12k stars 206 forks source link

ClipRect behaviour is strange #395

Open en-ot opened 3 years ago

en-ot commented 3 years ago

Hello!

Describe the bug

I am printing long strings to the GUI elements (gslc_ElemCreateTxt), and text gets out of element's boundaries. I see usage of ClipRect and setViewport in GUIslice, but gslc_DrvSetClipRect is always sets clipping region to 0,0,320,240 - whole screen. I can not understand how to use gslc_SetClipRect, because it takes only gslc_tsGui* pGui argument, not pElemRef - to stop the text running out of elements' boundaries.

Why clipping every element's contents is not the default behaviour of GUIslice? Or maybe it's GUIslice_drv_tft_espi.cpp bug?

If I change the line

m_disp.drawString(pStr,nTxtX,nTxtY);

in gslc_DrvDrawTxtAlign function to this:

m_disp.setViewport(nX0, nY0, nX1-nX0, nY1-nY0, false); m_disp.drawString(pStr,nTxtX,nTxtY); m_disp.resetViewport();

I can get the desired behaviour, but is it the right way?

Device hardware

Checklist to try first

  1. Open the example ex19_ard_smooth
  2. Change the text from "Quit" to "Quit12345"
  3. Build and run IMG_20210624_143705

Expected behavior

Element's contents are clipped by element's boundaries IMG_20210624_143912

ImpulseAdventure commented 2 years ago

@en-ot thank you for the detailed summary!

Many display libraries don’t support clipping (especially when it comes to rendering characters), but thankfully TFT_eSPI recently added it with the setViewport() functionality.

GUIslice already uses this mode when redrawing portions of the display that were updated, but not necessarily in the initial draw (where the clip / invalidation region is the entire screen).

For example, if you had set your initial text to “Quit” and then later called ElemSetTxtStr(“Quit12345”) after a later Update(), you would probably see the text clipping as you expected.

You make a good point as I think we should be able to also use this on the initial draw as well, making the clipping always active. I’ll take a look at the best way to implement this as we might not want to override the viewport in DrvDrawTxtAlign() as it could interfere with cases where multiple items are being redrawn concurrently.

Thanks!