[DEV] display element utf8 and up-down cursor

This commit is contained in:
Edouard DUPIN 2013-09-30 00:08:52 +02:00
parent bd066da738
commit 7643f5a736
5 changed files with 225 additions and 102 deletions

View File

@ -11,7 +11,8 @@
#include <appl/Debug.h>
appl::Buffer::Buffer(void) :
m_cursorPos(3)
m_cursorPos(0),
m_cursorPreferredCol(-1)
{
}
@ -40,6 +41,7 @@ void appl::Buffer::SetFileName(const etk::UString& _name)
void appl::Buffer::MoveCursorRight(appl::Buffer::moveMode _mode)
{
m_cursorPreferredCol = -1;
etk::UniChar value;
esize_t nbElement;
switch (_mode) {
@ -62,6 +64,7 @@ void appl::Buffer::MoveCursorRight(appl::Buffer::moveMode _mode)
void appl::Buffer::MoveCursorLeft(appl::Buffer::moveMode _mode)
{
m_cursorPreferredCol = -1;
etk::UniChar value;
esize_t nbElement;
switch (_mode) {
@ -83,68 +86,54 @@ void appl::Buffer::MoveCursorLeft(appl::Buffer::moveMode _mode)
void appl::Buffer::MoveCursorUp(esize_t _nbLine)
{
/*
// Find the position of the start of the line.
esize_t lineStartPos = m_EdnBuf.StartOfLine(m_cursorPos);
esize_t lineStartPos = StartLine(m_cursorPos);
// check if we can go up ...
if (lineStartPos == 0) {
return;
}
// Decide what column to move to, if there's a preferred column use that
int32_t column = m_cursorPreferredCol;
if (m_cursorPreferredCol < 0) {
column = m_EdnBuf.CountDispChars(lineStartPos, m_cursorPos);
m_cursorPreferredCol = CountDispChars(lineStartPos, m_cursorPos);
}
EWOL_DEBUG("ploop : " << m_cursorPreferredCol);
// Get the previous line
esize_t prevLineStartPos = m_EdnBuf.CountBackwardNLines(lineStartPos, _nbLine);
esize_t prevLineStartPos = CountBackwardNLines(lineStartPos, _nbLine);
//APPL_INFO("Move Line UP result : prevLineStartPos=" << prevLineStartPos);
// Get the display char position
esize_t newPos = m_EdnBuf.CountForwardDispChars(prevLineStartPos, column);
esize_t newPos = CountForwardDispChars(prevLineStartPos, m_cursorPreferredCol);
//APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
// move the cursor
SetInsertPosition(newPos);
// if a preferred column wasn't aleady established, establish it
if (m_cursorPreferredCol < 0) {
m_cursorPreferredCol = column;
}
return;
*/
//SetInsertPosition(newPos);
m_cursorPos = newPos;
}
void appl::Buffer::MoveCursorDown(esize_t _nbLine)
{
/*
// check if we are not at the end of Buffer
if (m_cursorPos == m_EdnBuf.Size() ) {
if (m_cursorPos == m_data.Size() ) {
return;
}
// Find the position of the start of the line.
esize_t lineStartPos = m_EdnBuf.StartOfLine(m_cursorPos);
esize_t lineStartPos = StartLine(m_cursorPos);
int32_t column = m_cursorPreferredCol;
if (m_cursorPreferredCol < 0) {
column = m_EdnBuf.CountDispChars(lineStartPos, m_cursorPos);
m_cursorPreferredCol = CountDispChars(lineStartPos, m_cursorPos);
}
EWOL_DEBUG("ploop : " << m_cursorPreferredCol);
// get the next line :
esize_t nextLineStartPos = m_EdnBuf.CountForwardNLines(lineStartPos, _nbLine);
esize_t nextLineStartPos = CountForwardNLines(lineStartPos, _nbLine);
//APPL_INFO("Move Line DOWN result : nextLineStartPos=" << nextLineStartPos);
// Get the display char position
esize_t newPos = m_EdnBuf.CountForwardDispChars(nextLineStartPos, column);
esize_t newPos = CountForwardDispChars(nextLineStartPos, m_cursorPreferredCol);
//APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
SetInsertPosition(newPos);
// if a preferred column wasn't aleady established, establish it
if (m_cursorPreferredCol < 0) {
m_cursorPreferredCol = column;
}
return;
*/
//SetInsertPosition(newPos);
m_cursorPos = newPos;
}
esize_t appl::Buffer::StartLine(esize_t _pos)
{
esize_t startPos;
if (false == SearchBackward(pos, etk::UniChar::Return, &startPos)) {
if (false == SearchBack(_pos, etk::UniChar::Return, startPos)) {
return 0;
}
return startPos + 1;
@ -153,13 +142,13 @@ esize_t appl::Buffer::StartLine(esize_t _pos)
esize_t appl::Buffer::EndLine(esize_t _pos)
{
esize_t endPos;
if (false == SearchForward(pos, etk::UniChar::Return, &endPos)) {
if (false == Search(_pos, etk::UniChar::Return, endPos)) {
endPos = m_data.Size();
}
return endPos;
}
bool appl::Buffer::SearchForward(esize_t _pos, const etk::UniChar& _search, esize_t& _result)
bool appl::Buffer::Search(esize_t _pos, const etk::UniChar& _search, esize_t& _result)
{
// move in the string
esize_t nbElementBuffer = 0;
@ -170,6 +159,9 @@ bool appl::Buffer::SearchForward(esize_t _pos, const etk::UniChar& _search, esiz
_result = iii;
return true;
}
if (nbElementBuffer<=0) {
nbElementBuffer = 1;
}
}
_result = m_data.Size();
return false;
@ -186,6 +178,9 @@ bool appl::Buffer::SearchBack(esize_t _pos, const etk::UniChar& _search, esize_t
_result = iii-nbElementBuffer;
return true;
}
if (nbElementBuffer<=0) {
nbElementBuffer = 1;
}
}
_result = 0;
return false;
@ -194,7 +189,7 @@ bool appl::Buffer::SearchBack(esize_t _pos, const etk::UniChar& _search, esize_t
bool appl::Buffer::OnEventEntry(const ewol::EventEntry& _event) // TODO : , vec2 _displaySize)
{
APPL_DEBUG(" event : " << _event);
//APPL_DEBUG(" event : " << _event);
if (_event.GetType() == ewol::keyEvent::keyboardChar) {
//APPL_DEBUG("KB EVENT : \"" << UTF8_data << "\" size=" << strlen(UTF8_data) << "type=" << (int32_t)typeEvent);
if (_event.GetStatus() != ewol::keyEvent::statusDown) {
@ -331,5 +326,155 @@ esize_t appl::Buffer::GetBack(esize_t _pos, etk::UniChar& _value, unicode::chars
}
static const char *ControlCodeTable[32] = {
"NUL", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs", "ht", "nl", "vt", "np", "cr", "so", "si",
"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em", "sub", "esc", "fs", "gs", "rs", "us"};
void appl::Buffer::Expand(esize_t& _indent, const etk::UniChar& _value, etk::UString& _out) const
{
_out.Clear();
int32_t tabDist = 4;
if (_value == etk::UniChar::Tabulation) {
int32_t nSpaces = tabDist - (_indent % tabDist);
for (int32_t iii=0; iii<nSpaces; iii++) {
_out.Append(etk::UniChar::Space);
}
return;
}
// Convert ASCII control codes to readable character sequences
if (_value == etk::UniChar::Null) {
_out.Append(etk::UniChar('<'));
_out.Append(etk::UniChar('n'));
_out.Append(etk::UniChar('u'));
_out.Append(etk::UniChar('l'));
_out.Append(etk::UniChar('>'));
return;
}
if (_value == etk::UniChar::Return) {
// nothing to display...
return;
}
if (_value.Get() <= 31) {
_out.Append(etk::UniChar('<'));
const char * tmp = ControlCodeTable[_value.Get()];
while (*tmp!='\0') {
_out.Append(etk::UniChar(*tmp));
tmp++;
}
_out.Append(etk::UniChar('>'));
return;
}
if (_value == etk::UniChar::Delete) {
_out.Append(etk::UniChar('<'));
_out.Append(etk::UniChar('d'));
_out.Append(etk::UniChar('e'));
_out.Append(etk::UniChar('l'));
_out.Append(etk::UniChar('>'));
return;
}
// nothing to do ...
_out.Append(_value);
//APPL_DEBUG("plop : " << _out);
}
int32_t appl::Buffer::CountDispChars(esize_t _posStart, esize_t _posEnd)
{
int32_t charCount = 0;
etk::UString expanded;
esize_t bufferElementSize;
etk::UniChar value;
//APPL_DEBUG("_posStart="<< _posStart << " _posEnd=" << _posEnd);
for(int32_t iii=_posStart; iii<_posEnd && iii<m_data.Size() ; iii+=bufferElementSize ) {
// get the element value:
bufferElementSize = Get(iii, value);
//APPL_DEBUG(" get : " << value << " size=" << bufferElementSize);
Expand(charCount, value, expanded);
charCount += expanded.Size();
if (bufferElementSize<=0) {
bufferElementSize = 1;
}
}
//APPL_DEBUG(" result=" << charCount);
return charCount;
}
esize_t appl::Buffer::CountForwardDispChars(esize_t _posStart, int32_t _nChars)
{
int32_t charCount = 0;
etk::UString expanded;
esize_t bufferElementSize;
etk::UniChar value;
int32_t iii;
for(iii = _posStart; charCount<_nChars && iii<m_data.Size() ; iii+=bufferElementSize ) {
// get the element value:
bufferElementSize = Get(iii, value);
if (value == etk::UniChar::Return) {
return iii;
}
Expand(charCount, value, expanded);
charCount += expanded.Size();
if (bufferElementSize<=0) {
bufferElementSize = 1;
}
}
//APPL_DEBUG(" result=" << charCount);
return iii;
}
esize_t appl::Buffer::CountForwardNLines(esize_t _startPos, int32_t _nLines)
{
if (_nLines <= 0) {
return _startPos;
} else if (_startPos > m_data.Size() ) {
return m_data.Size();
}
esize_t bufferElementSize;
etk::UniChar value;
int32_t lineCount = 0;
//APPL_INFO("startPos=" << startPos << " nLines=" << nLines);
for(int32_t iii = _startPos+1; iii<m_data.Size() ; iii+=bufferElementSize ) {
// get the element value:
bufferElementSize = Get(iii, value);
if (value == etk::UniChar::Return) {
lineCount++;
if (lineCount == _nLines) {
//APPL_INFO(" ==> (1) at position=" << myPosIt.Position()+1 );
return iii+1;
}
}
if (bufferElementSize<=0) {
bufferElementSize = 1;
}
}
//APPL_INFO(" ==> (2) at position=" << myPosIt.Position() );
return m_data.Size();
}
esize_t appl::Buffer::CountBackwardNLines(esize_t _startPos, int32_t _nLines)
{
if (_startPos <= 0) {
return 0;
} else if (_startPos > m_data.Size() ) {
_startPos = m_data.Size();
}
//APPL_INFO("startPos=" << startPos << " nLines=" << nLines);
esize_t bufferElementSize;
etk::UniChar value;
int32_t lineCount = 0;
for(int32_t iii = _startPos-1; iii>=0 ; iii-=bufferElementSize ) {
// get the element value:
bufferElementSize = GetBack(iii, value);
if (value == etk::UniChar::Return) {
lineCount++;
if (lineCount >= _nLines) {
//APPL_INFO(" ==> (1) at position=" << myPosIt.Position()+1 );
return iii+1;
}
}
if (bufferElementSize<=0) {
bufferElementSize = 1;
}
}
//APPL_INFO(" ==> (2) at position=0");
return 0;
}

View File

@ -45,6 +45,7 @@ namespace appl
*/
public:
esize_t m_cursorPos; //!< cursor position.
int32_t m_cursorPreferredCol; //!< position of the cursor when up and down is done.
bool OnEventEntry(const ewol::EventEntry& _event);
/**
* @brief Get the next element in the buffer.
@ -62,12 +63,19 @@ namespace appl
* @return number of element read in the buffer (to increment the position)
*/
esize_t GetBack(esize_t _pos, etk::UniChar& _value, unicode::charset_te _charset = unicode::EDN_CHARSET_UTF8) const;
/**
* @brief Expand the specify char to have a user frendly display for special char and tabs
* @param[in] _indent Curent indentation in the line
* @param[in] _value Current value to transform
* @param[out] _out String that represent the curent value to display
*/
void Expand(esize_t& _indent, const etk::UniChar& _value, etk::UString& _out) const;
private:
enum moveMode {
moveLetter,
moveWord,
moveEnd
}
};
/**
* Move the cursor right in the line (no stop of a new line)
* @param[in] _mode Moving mode char, word, ...
@ -107,7 +115,7 @@ namespace appl
* @param[out] _result Research position.
* @return true if pos if fined.
*/
bool SearchForward(esize_t _pos, const etk::UniChar& _search, esize_t& _result);
bool Search(esize_t _pos, const etk::UniChar& _search, esize_t& _result);
/**
* @brief Search a character in the buffer in back mode.
* @param[in] _pos Position to start the search of the element.
@ -116,6 +124,36 @@ namespace appl
* @return true if pos if fined.
*/
bool SearchBack(esize_t _pos, const etk::UniChar& _search, esize_t& _result);
/**
* @brief Count the number of displayed characters between buffer position
* Displayed characters are the characters shown on the screen to represent characters in the
* buffer, where tabs and control characters are expanded
* @param[in] _posStart start position
* @param[in] _posEnd End position
* @return the ID in the buffer of the requested char
*/
int32_t CountDispChars(esize_t _posStart, esize_t _posEnd);
/**
* @brief Return the position of the nth diplaye char
* @param[in] _posStart Position of the start
* @param[in] _nChars search in the next nChars elements
* @return position of the char i the buffer
*/
esize_t CountForwardDispChars(esize_t _posStart, int32_t _nChars);
/**
* @brief Find the first character of the line "nLines" forward
* @param[in,out] _startPos Start position.
* @param[in,out] _nLines Number of line to count.
* @return position of the starting the line.
*/
esize_t CountForwardNLines(esize_t _startPos, int32_t _nLines);
/**
* @brief Find the first character of the line "nLines" backwards
* @param[in,out] _startPos Start position to count (this caracter is not counted)
* @param[in,out] _nLines Number of line to count (if ==0 means find the beginning of the line)
* @return position of the starting the line
*/
esize_t CountBackwardNLines(esize_t _startPos, int32_t _nLines);
};
};

View File

@ -139,7 +139,7 @@ MainWindows::MainWindows(void)
mySizerHori->SubWidgetAdd(mySizerVert2);
// main buffer Area :
myTextView = new appl::TextViewer("FreeMono;DejaVuSansMono", 11);
myTextView = new appl::TextViewer("FreeSerif;FreeMono;DejaVuSansMono", 11);
myTextView->SetExpand(bvec2(true,true));
myTextView->SetFill(bvec2(true,true));
mySizerVert2->SubWidgetAdd(myTextView);

View File

@ -87,59 +87,6 @@ void appl::TextViewer::OnDraw(void)
WidgetScrooled::OnDraw();
}
static const char *ControlCodeTable[32] = {
"NUL", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs", "ht", "nl", "vt", "np", "cr", "so", "si",
"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "can", "em", "sub", "esc", "fs", "gs", "rs", "us"};
void appl::TextViewer::Expand(esize_t& _indent, const etk::UniChar& _value, etk::UString& _out) const
{
_out.Clear();
int32_t tabDist = 4;
if (_value == etk::UniChar::Tabulation) {
int32_t nSpaces = tabDist - (_indent % tabDist);
for (int32_t iii=0; iii<nSpaces; iii++) {
_out.Append(etk::UniChar::Space);
}
return;
}
// Convert ASCII control codes to readable character sequences
if (_value == etk::UniChar::Null) {
_out.Append(etk::UniChar('<'));
_out.Append(etk::UniChar('n'));
_out.Append(etk::UniChar('u'));
_out.Append(etk::UniChar('l'));
_out.Append(etk::UniChar('>'));
return;
}
if (_value == etk::UniChar::Return) {
// nothing to display...
return;
}
if (_value.Get() <= 31) {
_out.Append(etk::UniChar('<'));
const char * tmp = ControlCodeTable[_value.Get()];
while (*tmp!='\0') {
_out.Append(etk::UniChar(*tmp));
tmp++;
}
_out.Append(etk::UniChar('>'));
return;
}
if (_value == etk::UniChar::Delete) {
_out.Append(etk::UniChar('<'));
_out.Append(etk::UniChar('d'));
_out.Append(etk::UniChar('e'));
_out.Append(etk::UniChar('l'));
_out.Append(etk::UniChar('>'));
return;
}
// nothing to do ...
_out.Append(_value);
//APPL_DEBUG("plop : " << _out);
}
void appl::TextViewer::OnRegenerateDisplay(void)
{
if (false == NeedRedraw()) {
@ -197,7 +144,7 @@ void appl::TextViewer::OnRegenerateDisplay(void)
// need to display the cursor :
tmpCursorPosition = positionCurentDisplay;
}
bufferElementSize = m_buffer->Get(iii, currentValue, unicode::EDN_CHARSET_UTF8);
bufferElementSize = m_buffer->Get(iii, currentValue);
//APPL_DEBUG(" element size : " << iii << " : " << bufferElementSize);
if (currentValue == etk::UniChar::Return) {
countNbLine += 1;
@ -210,12 +157,13 @@ void appl::TextViewer::OnRegenerateDisplay(void)
m_displayText.SetPos(positionCurentDisplay);
continue;
}
appl::TextViewer::Expand(countColomn, currentValue, stringToDisplay);
m_buffer->Expand(countColomn, currentValue, stringToDisplay);
//APPL_DEBUG("display : '" << currentValue << "' ==> '" << stringToDisplay << "'");
//m_displayText.SetPos(positionCurentDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.Size(); ++kkk) {
m_displayText.Print(stringToDisplay[kkk]);
}
positionCurentDisplay.setX(positionCurentDisplay.x()+tmpLetterSize.x()*(float)stringToDisplay.Size());
positionCurentDisplay = m_displayText.GetPos();
countColomn += stringToDisplay.Size();
if (bufferElementSize ==0) {
@ -224,7 +172,7 @@ void appl::TextViewer::OnRegenerateDisplay(void)
}
if (tmpCursorPosition.z()!=-1) {
// display the cursor:
APPL_DEBUG("display cursor at position : " << tmpCursorPosition);
//APPL_DEBUG("display cursor at position : " << tmpCursorPosition);
m_displayText.SetPos(tmpCursorPosition);
m_displayText.SetColor(etk::Color<>(0xFF0000FF));
m_displayText.SetColorBg(etk::Color<>(0xFF0000FF));

View File

@ -46,14 +46,6 @@ namespace appl
virtual void OnEventClipboard(ewol::clipBoard::clipboardListe_te clipboardID);
virtual void OnGetFocus(void);
virtual void OnLostFocus(void);
private:
/**
* @brief Expand the specify char to have a user frendly display for special char and tabs
* @param[in] _indent Curent indentation in the line
* @param[in] _value Current value to transform
* @param[out] _out String that represent the curent value to display
*/
void Expand(esize_t& _indent, const etk::UniChar& _value, etk::UString& _out) const;
private:
bool m_insertMode; //!< the insert mode is enable
};