Stream text on the LCD_DISCO_F746NG TFT screeen.

Dependencies:   BSP_DISCO_F746NG

TftStream.h

Committer:
simon_stm
Date:
2018-12-04
Revision:
0:ad0cf038ea33
Child:
1:c8b8be3c4741

File content as of revision 0:ad0cf038ea33:

#include "mbed.h"
#include "LCD_DISCO_F746NG.h"

#include <sstream>
#include <queue>


//Serial pc(SERIAL_TX, SERIAL_RX); // DEBUG

class TftStream
{
public:
    // init empty screen with default font
    TftStream()
    :
    lineLengthMax(28),
    lineCntMax(11)
    {
        _lcd.Clear(LCD_COLOR_BLUE); 
        resetFont();
    }

    // use this like std::cout: TftStream stream; stream << "i:" << i << "\n";
    // the screen is only updated if there is a newline '\n' at the end
    template<typename T>
    TftStream& operator <<(const T& arg) 
    {
        _streamBuffer << arg;
        
        const bool newLineAtEnd = *(_streamBuffer.str().end() - 1) == '\n';
        
        if (newLineAtEnd == false)
        {
            return *this;
        }

        addNewLinesFromBuffer();

        while (_linesNew.size() > 1)
        {
            newLineToSrceenLines();
            drawLines();
        }
        
        if (newLineAtEnd)
        {
            newLineToSrceenLines();
            drawLines();
        }
            
        return *this;
    }
    
    // get the underlying screen object for direct manipulation
    LCD_DISCO_F746NG& getLcd()
    {
        return _lcd;
    }
    
    // clear the screen
    void clear()
    {
        _lcd.Clear(LCD_COLOR_BLUE);       
        _linesOnScreen.clear();
    }
    
    // reset to default font
    void resetFont()
    {
        _lcd.SetBackColor(LCD_COLOR_BLUE);
        _lcd.SetTextColor(LCD_COLOR_WHITE);
    }
    
private:
    void addNewLinesFromBuffer()
    {
        std::string line;
        std::istringstream lineStream(_streamBuffer.str());
        _streamBuffer.str("");
        
        while (std::getline(lineStream, line, '\n')) {
            if (line.empty())
            {
                line = std::string(lineLengthMax, ' ');
            }
            
            for (unsigned i = 0; i < line.length(); i += lineLengthMax ) 
            {
                std::string lineTrimmed = line.substr(i, lineLengthMax );
                lineTrimmed = lineTrimmed += std::string(lineLengthMax - lineTrimmed.length(), ' ');
                _linesNew.push(lineTrimmed);
                //pc.printf("  line tr: '%s'\n", lineTrimmed.c_str());
            }
        }
    }
    
    
    void drawLines()
    {
        int lineNb = 0;
        for (std::deque<std::string>::iterator lineIt = _linesOnScreen.begin(); lineIt != _linesOnScreen.end(); ++lineIt)
        {
            _lcd.DisplayStringAtLine(lineNb, (uint8_t *)(lineIt->c_str()));
            ++lineNb;
        }         
    }
    
    
    void newLineToSrceenLines()
    {
        _linesOnScreen.push_back(_linesNew.front());
        _linesNew.pop();
        
        if(_linesOnScreen.size() > lineCntMax)
        {
            _linesOnScreen.pop_front();
        }       
    }
    
    
    const int lineLengthMax;
    const int lineCntMax;
      
    std::ostringstream      _streamBuffer;
    std::queue<std::string> _linesNew;
    std::deque<std::string> _linesOnScreen;
    LCD_DISCO_F746NG        _lcd;    
};