2.3k views
in GUI Development by

Hi,

Using a TextView and a SlideTouchHandler allows me to implement a slideable Text within seconds.

However besides sliding through the text, I want also to show if there are more lines on the bottom or on the top. A good visual effect is to fade out the text.
This allows the user to see at first glance if he can slide along top or bottom.

Currently I fake this faded text via rectangle gradient, just like this:

How to do this the right way to get a smooth faded text?

1 Answer

0 votes
by
 
Best answer

Hello,
using the gradient to get a fade to dark impression is a simple way to do this, but this only works if there is a solid background.
To get real fade out effect, the colors of the text rendering funtions can be used.
Within the following example you can see a FadedVerticalText, derived from a Views::Text.

See attached example.

Here the interesting part is the usage of test rendering functions within the Draw() mothof of the view:

// Nothing to draw
if (( flowString == "" ) || ( pure Font == null ))
  return;

var Views::TextAlignment align    = pure Alignment;
var Resources::Font      font     = pure Font;
var rect                 rd       = pure Bounds + aOffset;
var color                ctl      = pure ColorTL;
var color                ctr      = pure ColorTR;
var color                cbr      = pure ColorBR;
var color                cbl      = pure ColorBL;
var int32                opacity  = ((( aOpacity + 1 ) * pure Opacity ) >> 8 ) + 1;
var int32                noOfRows = flowString[0];
var rect                 area     = GetContentArea() + aOffset;
var point                ofs      = rd.origin - area.origin - point( 0, font.Ascent );

// Modulate the color values by the opacity?
if ( opacity < 256 )
{
  ctl.alpha = uint8(( ctl.alpha * opacity ) >> 8 );
  ctr.alpha = uint8(( ctr.alpha * opacity ) >> 8 );
  cbr.alpha = uint8(( cbr.alpha * opacity ) >> 8 );
  cbl.alpha = uint8(( cbl.alpha * opacity ) >> 8 );
}

// Display a single text row
if ( noOfRows == 1 )
{
  var int32 count = int32( flowString[1]) - 2;

  // Don't show the <new line> sign at the end of a text row
  if ( flowString[ count + 2 ] == '\n' )
    count = count - 1;

  aCanvas.DrawText( aClip, font, flowString, 3, count, rd, ofs, 0,
    ctl, ctr, cbr, cbl, true );
}

// Nothing more to draw
if ( noOfRows < 2 )
  return;

var int32 leading = font.Leading;

// Overload the font metrics?
if ( pure RowDistance > 0 )
  leading = pure RowDistance - font.Ascent - font.Descent;

// Displaying multiline text. Process and display the text row by row
var int32 rowHeight = font.Ascent + font.Descent + leading;
var int32 y         = area.y1;
var int32 i         = 1;
var int32 c         = flowString[i];

// Fading is enabled when first/last row is almost invisible
var float fadingIndicator = 0.0;
var rect contentArea = GetContentArea();
var bool topFade = (int32)((float)rowHeight * fadingIndicator) < -contentArea.y1 + Bounds.origin.y;
var int32 fadableTextHeight = (contentArea.y2 - (int32)((float)rowHeight * fadingIndicator));
var bool bottomFade = Bounds.h + Bounds.origin.y < fadableTextHeight;

// Skip over rows lying outside the clipping area
while ((( y + rowHeight ) < aClip.y1 ) && ( c > 0 ))
{
  i = i + c;
  y = y + rowHeight;
  c = flowString[i];
}

// Now draw all following text rows which are enclosed within the clipping 
// area
while (( y < aClip.y2 ) && ( c > 0 ))
{
  var int32 minWidth = 0;
  var int32 cc   = c - 2;
  var point ofs2 = ofs;

  ofs2.y = ofs2.y + area.y1 - y;
          
  // If the text row was terminated with the <new line> sign -> Ignore it! Do 
  // not display <new line> signs!
  if ( flowString[ i + c - 1 ] == '\n' )
    cc = cc - 1;

  // Ignore empty rows (\n only) ...
  if ( cc <= 0 )
    ;

  // Should the text be stretched to fill the whole view's width?
  // In this case no text row width calculation is necessary.
  else if ( align.contains( Views::TextAlignment[ AlignHorzJustified ]))
  {
    // The text row was terminated with the <new line> sign, or it
    // is the last text row -> In this case do not stretch the text row!
    if (( cc < ( c - 2 )) || ( flowString[ i + c ] == '\0' ))
      {} //default way

    // This text row can be stretched ...
    else
      minWidth = area.w;
  }

  // Should the text be aligned to the right?
  else if ( align.contains( Views::TextAlignment[ AlignHorzRight ]))
  {
    // Using the text width, calculate the horizontal text drawing position.
    ofs2.x = ofs2.x - area.w + font.GetTextAdvance( flowString, i + 2, cc );
  }

  // Should the text be centered?
  else if ( align.contains( Views::TextAlignment[ AlignHorzCenter ]))
  {
    var int32 tw = font.GetTextAdvance( flowString, i + 2, cc );

    // Using the text width, calculate the horizontal text drawing position.
    ofs2.x = ofs2.x - (( area.w - tw ) / 2 );
  }

  // Prepare to draw the text
  var int32 topFadedHeight = (int32)(this.Bounds.h * FadePercentage / 100);
  var int32 bottomFadedHeight = (int32)(this.Bounds.h - ( this.Bounds.h * FadePercentage / 100 ));
  var int32 textY1 = y - rd.y1;
  var color ctf = ctl;
  ctf.alpha = 0;

  //fading top                     
  if ( textY1 < topFadedHeight && topFade )
  {
    var rect topRect         = rect(rd.x1, rd.y1, rd.x2, rd.y1+topFadedHeight);
    var rect bottomRect      = rect(rd.x1, rd.y1+topFadedHeight, rd.x2, rd.y2);

    //draw faded text 
    aCanvas.DrawText( aClip, font, flowString, i + 2, cc, topRect, ofs2, minWidth, 
      ctf, ctf, cbr, cbl, true );

    //draw remaining plain text part
    aCanvas.DrawText( aClip & bottomRect, font, flowString, i + 2, cc, rd, ofs2, minWidth,
      ctl, ctr, cbr, cbl, true );
  }
  
  //fading bottom
  else if ( textY1 + rowHeight > bottomFadedHeight && bottomFade )
  {
    var rect topRect         = rect(rd.x1, rd.y1, rd.x2, rd.y1+bottomFadedHeight);
    var rect bottomRect      = rect(rd.x1, rd.y1+bottomFadedHeight, rd.x2, rd.y2);
    var point offsetAdjustment  = point( ofs2.x, ofs2.y+bottomFadedHeight );

    //draw faded text 
    aCanvas.DrawText( aClip, font, flowString, i + 2, cc, bottomRect, 
      offsetAdjustment, minWidth, ctl, ctr, ctf, ctf, true );

    //draw remaining plain text part
    aCanvas.DrawText( aClip, font, flowString, i + 2, cc, topRect, ofs2, minWidth, 
      ctl, ctr, cbr, cbl, true );
  }

  //no fading in center area, just draw text
  else
    aCanvas.DrawText( aClip, font, flowString, i + 2, cc, rd, ofs2, minWidth,
      ctl, ctr, cbr, cbl, true );

  // ... and continue with the next row.
  i = i + c;
  y = y + rowHeight;
  c = flowString[i];
}               

 

Ask Embedded Wizard - Archive

Welcome to the Ask Embedded Wizard archive. This community forum served us well for many years, but we've evolved our support approach!

Your resources:

The Embedded Wizard Online Documentation provides comprehensive documentation, tutorials, examples and ready-to-use software packages.

For dedicated assistance, explore our Embedded Wizard Product Support.

You can still browse the valuable discussions from our community history here.

Embedded Wizard Website | Privacy Policy | Imprint

...