[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> #include <appl/Debug.h>
appl::Buffer::Buffer(void) : 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) void appl::Buffer::MoveCursorRight(appl::Buffer::moveMode _mode)
{ {
m_cursorPreferredCol = -1;
etk::UniChar value; etk::UniChar value;
esize_t nbElement; esize_t nbElement;
switch (_mode) { switch (_mode) {
@ -62,6 +64,7 @@ void appl::Buffer::MoveCursorRight(appl::Buffer::moveMode _mode)
void appl::Buffer::MoveCursorLeft(appl::Buffer::moveMode _mode) void appl::Buffer::MoveCursorLeft(appl::Buffer::moveMode _mode)
{ {
m_cursorPreferredCol = -1;
etk::UniChar value; etk::UniChar value;
esize_t nbElement; esize_t nbElement;
switch (_mode) { switch (_mode) {
@ -83,68 +86,54 @@ void appl::Buffer::MoveCursorLeft(appl::Buffer::moveMode _mode)
void appl::Buffer::MoveCursorUp(esize_t _nbLine) void appl::Buffer::MoveCursorUp(esize_t _nbLine)
{ {
/*
// Find the position of the start of the line. // 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 ... // check if we can go up ...
if (lineStartPos == 0) { if (lineStartPos == 0) {
return; return;
} }
// Decide what column to move to, if there's a preferred column use that // Decide what column to move to, if there's a preferred column use that
int32_t column = m_cursorPreferredCol;
if (m_cursorPreferredCol < 0) { 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 // 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); //APPL_INFO("Move Line UP result : prevLineStartPos=" << prevLineStartPos);
// Get the display char position // 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); //APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
// move the cursor //SetInsertPosition(newPos);
SetInsertPosition(newPos); m_cursorPos = newPos;
// if a preferred column wasn't aleady established, establish it
if (m_cursorPreferredCol < 0) {
m_cursorPreferredCol = column;
}
return;
*/
} }
void appl::Buffer::MoveCursorDown(esize_t _nbLine) void appl::Buffer::MoveCursorDown(esize_t _nbLine)
{ {
/*
// check if we are not at the end of Buffer // check if we are not at the end of Buffer
if (m_cursorPos == m_EdnBuf.Size() ) { if (m_cursorPos == m_data.Size() ) {
return; return;
} }
// Find the position of the start of the line. // 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) { 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 : // 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); //APPL_INFO("Move Line DOWN result : nextLineStartPos=" << nextLineStartPos);
// Get the display char position // 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); //APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
//SetInsertPosition(newPos);
SetInsertPosition(newPos); m_cursorPos = newPos;
// if a preferred column wasn't aleady established, establish it
if (m_cursorPreferredCol < 0) {
m_cursorPreferredCol = column;
}
return;
*/
} }
esize_t appl::Buffer::StartLine(esize_t _pos) esize_t appl::Buffer::StartLine(esize_t _pos)
{ {
esize_t startPos; esize_t startPos;
if (false == SearchBackward(pos, etk::UniChar::Return, &startPos)) { if (false == SearchBack(_pos, etk::UniChar::Return, startPos)) {
return 0; return 0;
} }
return startPos + 1; 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 appl::Buffer::EndLine(esize_t _pos)
{ {
esize_t endPos; esize_t endPos;
if (false == SearchForward(pos, etk::UniChar::Return, &endPos)) { if (false == Search(_pos, etk::UniChar::Return, endPos)) {
endPos = m_data.Size(); endPos = m_data.Size();
} }
return endPos; 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 // move in the string
esize_t nbElementBuffer = 0; esize_t nbElementBuffer = 0;
@ -170,6 +159,9 @@ bool appl::Buffer::SearchForward(esize_t _pos, const etk::UniChar& _search, esiz
_result = iii; _result = iii;
return true; return true;
} }
if (nbElementBuffer<=0) {
nbElementBuffer = 1;
}
} }
_result = m_data.Size(); _result = m_data.Size();
return false; return false;
@ -186,6 +178,9 @@ bool appl::Buffer::SearchBack(esize_t _pos, const etk::UniChar& _search, esize_t
_result = iii-nbElementBuffer; _result = iii-nbElementBuffer;
return true; return true;
} }
if (nbElementBuffer<=0) {
nbElementBuffer = 1;
}
} }
_result = 0; _result = 0;
return false; 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) 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) { if (_event.GetType() == ewol::keyEvent::keyboardChar) {
//APPL_DEBUG("KB EVENT : \"" << UTF8_data << "\" size=" << strlen(UTF8_data) << "type=" << (int32_t)typeEvent); //APPL_DEBUG("KB EVENT : \"" << UTF8_data << "\" size=" << strlen(UTF8_data) << "type=" << (int32_t)typeEvent);
if (_event.GetStatus() != ewol::keyEvent::statusDown) { 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: public:
esize_t m_cursorPos; //!< cursor position. 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); bool OnEventEntry(const ewol::EventEntry& _event);
/** /**
* @brief Get the next element in the buffer. * @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) * @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; 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: private:
enum moveMode { enum moveMode {
moveLetter, moveLetter,
moveWord, moveWord,
moveEnd moveEnd
} };
/** /**
* Move the cursor right in the line (no stop of a new line) * Move the cursor right in the line (no stop of a new line)
* @param[in] _mode Moving mode char, word, ... * @param[in] _mode Moving mode char, word, ...
@ -107,7 +115,7 @@ namespace appl
* @param[out] _result Research position. * @param[out] _result Research position.
* @return true if pos if fined. * @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. * @brief Search a character in the buffer in back mode.
* @param[in] _pos Position to start the search of the element. * @param[in] _pos Position to start the search of the element.
@ -116,6 +124,36 @@ namespace appl
* @return true if pos if fined. * @return true if pos if fined.
*/ */
bool SearchBack(esize_t _pos, const etk::UniChar& _search, esize_t& _result); 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); mySizerHori->SubWidgetAdd(mySizerVert2);
// main buffer Area : // main buffer Area :
myTextView = new appl::TextViewer("FreeMono;DejaVuSansMono", 11); myTextView = new appl::TextViewer("FreeSerif;FreeMono;DejaVuSansMono", 11);
myTextView->SetExpand(bvec2(true,true)); myTextView->SetExpand(bvec2(true,true));
myTextView->SetFill(bvec2(true,true)); myTextView->SetFill(bvec2(true,true));
mySizerVert2->SubWidgetAdd(myTextView); mySizerVert2->SubWidgetAdd(myTextView);

View File

@ -87,59 +87,6 @@ void appl::TextViewer::OnDraw(void)
WidgetScrooled::OnDraw(); 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) void appl::TextViewer::OnRegenerateDisplay(void)
{ {
if (false == NeedRedraw()) { if (false == NeedRedraw()) {
@ -197,7 +144,7 @@ void appl::TextViewer::OnRegenerateDisplay(void)
// need to display the cursor : // need to display the cursor :
tmpCursorPosition = positionCurentDisplay; tmpCursorPosition = positionCurentDisplay;
} }
bufferElementSize = m_buffer->Get(iii, currentValue, unicode::EDN_CHARSET_UTF8); bufferElementSize = m_buffer->Get(iii, currentValue);
//APPL_DEBUG(" element size : " << iii << " : " << bufferElementSize); //APPL_DEBUG(" element size : " << iii << " : " << bufferElementSize);
if (currentValue == etk::UniChar::Return) { if (currentValue == etk::UniChar::Return) {
countNbLine += 1; countNbLine += 1;
@ -210,12 +157,13 @@ void appl::TextViewer::OnRegenerateDisplay(void)
m_displayText.SetPos(positionCurentDisplay); m_displayText.SetPos(positionCurentDisplay);
continue; continue;
} }
appl::TextViewer::Expand(countColomn, currentValue, stringToDisplay); m_buffer->Expand(countColomn, currentValue, stringToDisplay);
//APPL_DEBUG("display : '" << currentValue << "' ==> '" << stringToDisplay << "'");
//m_displayText.SetPos(positionCurentDisplay); //m_displayText.SetPos(positionCurentDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.Size(); ++kkk) { for (esize_t kkk=0; kkk<stringToDisplay.Size(); ++kkk) {
m_displayText.Print(stringToDisplay[kkk]); m_displayText.Print(stringToDisplay[kkk]);
} }
positionCurentDisplay.setX(positionCurentDisplay.x()+tmpLetterSize.x()*(float)stringToDisplay.Size()); positionCurentDisplay = m_displayText.GetPos();
countColomn += stringToDisplay.Size(); countColomn += stringToDisplay.Size();
if (bufferElementSize ==0) { if (bufferElementSize ==0) {
@ -224,7 +172,7 @@ void appl::TextViewer::OnRegenerateDisplay(void)
} }
if (tmpCursorPosition.z()!=-1) { if (tmpCursorPosition.z()!=-1) {
// display the cursor: // display the cursor:
APPL_DEBUG("display cursor at position : " << tmpCursorPosition); //APPL_DEBUG("display cursor at position : " << tmpCursorPosition);
m_displayText.SetPos(tmpCursorPosition); m_displayText.SetPos(tmpCursorPosition);
m_displayText.SetColor(etk::Color<>(0xFF0000FF)); m_displayText.SetColor(etk::Color<>(0xFF0000FF));
m_displayText.SetColorBg(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 OnEventClipboard(ewol::clipBoard::clipboardListe_te clipboardID);
virtual void OnGetFocus(void); virtual void OnGetFocus(void);
virtual void OnLostFocus(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: private:
bool m_insertMode; //!< the insert mode is enable bool m_insertMode; //!< the insert mode is enable
}; };