[DEV] add plugin and rewrite to support the plugin

This commit is contained in:
Edouard DUPIN 2013-10-20 18:14:22 +02:00
parent 408a22015c
commit 4704eca027
16 changed files with 1377 additions and 595 deletions

View File

@ -30,7 +30,7 @@ appl::Buffer::Iterator& appl::Buffer::Iterator::operator-- (void) {
while( etk::UChar::theoricUTF8First(m_data->m_data[m_current+iii]) == false while( etk::UChar::theoricUTF8First(m_data->m_data[m_current+iii]) == false
&& iii >= -6 && iii >= -6
&& m_current-iii>0) { && m_current-iii>0) {
++iii; --iii;
}; };
m_current += iii; m_current += iii;
} }
@ -66,6 +66,17 @@ appl::Buffer::Iterator appl::Buffer::end(void) {
return position( m_data.size()-1 ); return position( m_data.size()-1 );
} }
appl::Buffer::Iterator appl::Buffer::cursor(void) {
return position( m_cursorPos );
}
appl::Buffer::Iterator appl::Buffer::selectStart(void) {
return position( getStartSelectionPos() );
}
appl::Buffer::Iterator appl::Buffer::selectStop(void) {
return position( getStopSelectionPos() );
}
appl::Buffer::Buffer(void) : appl::Buffer::Buffer(void) :
@ -92,116 +103,26 @@ void appl::Buffer::setFileName(const etk::UString& _name) {
// TODO : ... // TODO : ...
} }
void appl::Buffer::moveCursorRight(appl::Buffer::moveMode _mode) {
Iterator it;
esize_t nbElement;
switch (_mode) {
default:
case moveLetter:
it = position(m_cursorPos);
++it;
moveCursor(it.getPos());
break;
case moveWord:
// TODO : ...
break;
case moveEnd:
// TODO : ...
nbElement = endLine(m_cursorPos);
moveCursor(nbElement);
break;
}
}
void appl::Buffer::moveCursorLeft(appl::Buffer::moveMode _mode) { appl::Buffer::Iterator appl::Buffer::getStartLine(const appl::Buffer::Iterator& _pos) {
etk::UChar value; appl::Buffer::Iterator startPos;
Iterator it;
esize_t nbElement;
switch (_mode) {
default:
case moveLetter:
it = position(m_cursorPos);
--it;
moveCursor(it.getPos());
break;
case moveWord:
// TODO : ...
break;
case moveEnd:
nbElement = startLine(m_cursorPos);
moveCursor(nbElement+1);
break;
}
}
void appl::Buffer::moveCursorUp(esize_t _nbLine, ewol::Text& _textDrawer) {
// find the position of the start of the line.
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
if (m_cursorPreferredCol < 0) {
// TODO : Remove this +1 !!!
m_cursorPreferredCol = getScreenSize(lineStartPos+1, m_cursorPos, _textDrawer);
}
EWOL_DEBUG("ploop : " << m_cursorPreferredCol);
// get the previous line
esize_t prevLineStartPos = countBackwardNLines(lineStartPos, _nbLine);
//APPL_INFO("Move line UP result : prevLineStartPos=" << prevLineStartPos);
// get the display char position
esize_t newPos = getPosSize(prevLineStartPos, m_cursorPreferredCol, _textDrawer);
//APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
float posStore = m_cursorPreferredCol;
moveCursor(newPos);
m_cursorPreferredCol = posStore;
}
void appl::Buffer::moveCursorDown(esize_t _nbLine, ewol::Text& _textDrawer) {
// check if we are not at the end of Buffer
if (m_cursorPos == m_data.size() ) {
return;
}
// find the position of the start of the line.
esize_t lineStartPos = startLine(m_cursorPos);
if (m_cursorPreferredCol < 0) {
// TODO : Remove this +1 !!!
m_cursorPreferredCol = getScreenSize(lineStartPos+1, m_cursorPos, _textDrawer);
}
EWOL_DEBUG("ploop : " << m_cursorPreferredCol);
// get the next line :
esize_t nextLineStartPos = countForwardNLines(lineStartPos, _nbLine);
//APPL_INFO("Move line DOWN result : nextLineStartPos=" << nextLineStartPos);
// get the display char position
esize_t newPos = getPosSize(nextLineStartPos, m_cursorPreferredCol, _textDrawer);
//APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
float posStore = m_cursorPreferredCol;
moveCursor(newPos);
m_cursorPreferredCol = posStore;
}
esize_t appl::Buffer::startLine(esize_t _pos) {
esize_t startPos;
if (false == searchBack(_pos, etk::UChar::Return, startPos)) { if (false == searchBack(_pos, etk::UChar::Return, startPos)) {
return 0; return begin();
} }
return startPos; return startPos;
} }
esize_t appl::Buffer::endLine(esize_t _pos) { appl::Buffer::Iterator appl::Buffer::getEndLine(const appl::Buffer::Iterator& _pos) {
esize_t endPos; appl::Buffer::Iterator endPos;
if (false == search(_pos, etk::UChar::Return, endPos)) { if (false == search(_pos, etk::UChar::Return, endPos)) {
endPos = m_data.size(); endPos = end();
} }
return endPos; return endPos;
} }
bool appl::Buffer::search(esize_t _pos, const etk::UChar& _search, esize_t& _result) {
bool appl::Buffer::search(const appl::Buffer::Iterator& _pos, const etk::UChar& _search, appl::Buffer::Iterator& _result) {
// move in the string // move in the string
esize_t nbElementBuffer = 0;
etk::UChar value; etk::UChar value;
for (Iterator it = position(m_cursorPos); for (Iterator it = position(m_cursorPos);
it != end(); it != end();
@ -215,9 +136,8 @@ bool appl::Buffer::search(esize_t _pos, const etk::UChar& _search, esize_t& _res
return false; return false;
} }
bool appl::Buffer::searchBack(esize_t _pos, const etk::UChar& _search, esize_t& _result) { bool appl::Buffer::searchBack(const appl::Buffer::Iterator& _pos, const etk::UChar& _search, appl::Buffer::Iterator& _result) {
// move in the string // move in the string
esize_t nbElementBuffer = 0;
etk::UChar value; etk::UChar value;
for (Iterator it = --position(m_cursorPos); for (Iterator it = --position(m_cursorPos);
it != begin(); it != begin();
@ -229,198 +149,7 @@ bool appl::Buffer::searchBack(esize_t _pos, const etk::UChar& _search, esize_t&
return true; return true;
} }
} }
_result = 0; _result = begin();
return false;
}
// TODO : vec2 _displaySize
bool appl::Buffer::onEventEntry(const ewol::EventEntry& _event, ewol::Text& _testDrawer) {
//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) {
return false;
}
etk::UChar localValue = _event.getChar();
if (localValue == etk::UChar::Tabulation) {
if (hasTextSelected()) {
// TODO : Special tabulation multiline indentation ...
/*
int32_t nbSelectedLines = m_EdnBuf.CountLines(SelectionStart, SelectionEnd);
if (1 < nbSelectedLines) {
if (true == _event.getSpecialKey().isSetShift() ) {
m_cursorPos = m_EdnBuf.UnIndent();
} else {
m_cursorPos = m_EdnBuf.Indent();
}
}
*/
return true;
}
} else if (localValue == etk::UChar::Return) {
if (true == _event.getSpecialKey().isSetShift()) {
localValue = etk::UChar::CarrierReturn;
} else {
/*
m_data.insert(m_cursorPos, '\n');
if (true == globals::isSetAutoIndent() ) {
int32_t l_lineStart;
// get the begin of the line or the begin of the line befor selection
if (false == haveSelectionActive) {
l_lineStart = m_EdnBuf.StartOfLine(m_cursorPos);
} else {
l_lineStart = m_EdnBuf.StartOfLine(SelectionStart);
}
// add same characters in the temporar buffer
for (int32_t kk=l_lineStart; kk<m_cursorPos; kk++) {
if (' ' == m_EdnBuf[kk]) {
tmpVect.pushBack(' ');
} else if('\t' == m_EdnBuf[kk]) {
tmpVect.pushBack('\t');
} else {
break;
}
}
}
m_selectMode = false;
moveCursor(m_cursorPos + 1);
return true;
*/
}
} else if (localValue == etk::UChar::Suppress ) {
//APPL_INFO("keyEvent : <suppr> pos=" << m_cursorPos);
if (hasTextSelected()) {
removeSelection();
} else {
int32_t dimention = (esize_t)(++position(m_cursorPos)) - m_cursorPos;
if (dimention > 0) {
m_data.remove(m_cursorPos, dimention);
}
}
return true;
} else if (localValue == etk::UChar::Delete) {
//APPL_INFO("keyEvent : <del> pos=" << m_cursorPos);
if (hasTextSelected()) {
removeSelection();
} else {
int32_t dimention = m_cursorPos - (esize_t)(--position(m_cursorPos));
if (dimention > 0) {
m_data.remove(m_cursorPos-dimention, dimention);
}
}
return true;
}
m_selectMode = false;
// normal adding char ...
char output[5];
int32_t nbElement = localValue.getUtf8(output);
if ( hasTextSelected() == false
&& _event.getSpecialKey().isSetInsert() == true) {
int32_t dimention = (esize_t)(++position(m_cursorPos)) - m_cursorPos;
m_data.replace(m_cursorPos, dimention, (int8_t*)output, nbElement);
moveCursor(m_cursorPos+nbElement);
} else {
etk::UString myString = output;
paste(myString);
}
return true;
}
// move events ...
if (_event.getStatus() == ewol::keyEvent::statusDown) {
bool needUpdatePosition = true;
// check selection event ...
switch(_event.getType()) {
case ewol::keyEvent::keyboardLeft:
//APPL_INFO("keyEvent : <LEFT>");
moveCursorLeft();
break;
case ewol::keyEvent::keyboardRight:
//APPL_INFO("keyEvent : <RIGHT>");
moveCursorRight();
break;
case ewol::keyEvent::keyboardUp:
//APPL_INFO("keyEvent : <UP>");
moveCursorUp(1, _testDrawer);
break;
case ewol::keyEvent::keyboardDown:
//APPL_INFO("keyEvent : <DOWN>");
moveCursorDown(1, _testDrawer);
break;
case ewol::keyEvent::keyboardPageUp:
//APPL_INFO("keyEvent : <PAGE-UP>");
//TextDMoveUp(m_displaySize.y());
break;
case ewol::keyEvent::keyboardPageDown:
//APPL_INFO("keyEvent : <PAGE-DOWN>");
//TextDMoveDown(m_displaySize.y());
break;
case ewol::keyEvent::keyboardStart:
//APPL_INFO("keyEvent : <Start of line>");
moveCursorLeft(moveEnd);
break;
case ewol::keyEvent::keyboardEnd:
//APPL_INFO("keyEvent : <End of line>");
moveCursorRight(moveEnd);
break;
default:
break;
}
/*
if ( true == needUpdatePosition) {
RequestUpdateOfThePosition();
}
*/
return true;
}
return false;
}
bool appl::Buffer::onEventInput(const ewol::EventInput& _event, ewol::Text& _textDrawer, const vec2& _relativePos)
{
if (_event.getId() == 1) {
// mouse selection :
if (_event.getType() == ewol::keyEvent::typeMouse) {
if (_event.getStatus() == ewol::keyEvent::statusDown) {
esize_t newPos = getMousePosition(_relativePos, _textDrawer);
moveCursor(newPos);
m_selectMode = true;
return true;
} else if (_event.getStatus() == ewol::keyEvent::statusUp) {
esize_t newPos = getMousePosition(_relativePos, _textDrawer);
moveCursor(newPos);
m_selectMode = false;
// TODO : Copy selection :
//tmpBuffer->Copy(ewol::clipBoard::clipboardSelection);
return true;
}
}
if (_event.getStatus() == ewol::keyEvent::statusSingle) {
if (_event.getType() == ewol::keyEvent::typeMouse) {
esize_t newPos = getMousePosition(_relativePos, _textDrawer);
moveCursor(newPos);
return true;
}
} else if (_event.getStatus() == ewol::keyEvent::statusDouble) {
mouseEventDouble();
return true;
} else if (_event.getStatus() == ewol::keyEvent::statusTriple) {
mouseEventTriple();
return true;
} else if (_event.getStatus() == ewol::keyEvent::statusMove) {
if (m_selectMode == true) {
esize_t newPos = getMousePosition(_relativePos, _textDrawer);
moveCursor(newPos);
return true;
}
}
} else if (2 == _event.getId()) {
if (ewol::keyEvent::statusSingle == _event.getStatus()) {
esize_t newPos = getMousePosition(_relativePos, _textDrawer);
moveCursor(newPos);
ewol::clipBoard::request(ewol::clipBoard::clipboardSelection);
}
}
return false; return false;
} }
@ -443,9 +172,11 @@ void appl::Buffer::moveCursor(esize_t _pos) {
m_cursorSelectPos = -1; m_cursorSelectPos = -1;
} }
bool appl::Buffer::selectAround(int32_t _startPos, int32_t &_beginPos, int32_t &_endPos) { bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos,
appl::Buffer::Iterator &_beginPos,
appl::Buffer::Iterator &_endPos) {
etk::UChar currentValue = *position(_startPos); etk::UChar currentValue = *position(_startPos);
_beginPos = 0; _beginPos = begin();
_endPos = end(); _endPos = end();
if ( currentValue == etk::UChar::Tabulation if ( currentValue == etk::UChar::Tabulation
|| currentValue == etk::UChar::Space) { || currentValue == etk::UChar::Space) {
@ -523,124 +254,17 @@ bool appl::Buffer::selectAround(int32_t _startPos, int32_t &_beginPos, int32_t &
} }
return true; return true;
} }
_beginPos = 0; _beginPos = begin();
_endPos = 0; _endPos = begin();
return false; return false;
} }
void appl::Buffer::mouseEventDouble(void) { void appl::Buffer::setSelectionPos(const appl::Buffer::Iterator& _pos) {
//m_selectMode = false; m_cursorSelectPos = _pos;
esize_t beginPos, endPos;
if (true == selectAround(m_cursorPos, beginPos, endPos)) {
moveCursor(endPos);
m_cursorSelectPos = beginPos;
}
// TODO : copy(ewol::clipBoard::clipboardSelection);
} }
void appl::Buffer::mouseEventTriple(void) { void appl::Buffer::unSelect(void) {
//m_selectMode = false; m_cursorSelectPos = -1;
moveCursor(endLine(m_cursorPos));
m_cursorSelectPos = startLine(m_cursorPos);
// TODO : copy(ewol::clipBoard::clipboardSelection);
}
// TODO : Rename ...
esize_t appl::Buffer::getPosSize(esize_t _startLinePos, float _distance, ewol::Text& _textDrawer)
{
esize_t bufferElementSize;
etk::UChar currentValue;
esize_t countColomn = 0;
etk::UString stringToDisplay;
_textDrawer.clear();
_textDrawer.forceLineReturn();
for (Iterator it = position(_startLinePos);
it != end();
++it) {
currentValue = *it;
expand(countColomn, currentValue, stringToDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.size(); ++kkk) {
if (stringToDisplay[kkk] == etk::UChar::Return) {
return it;
} else {
_textDrawer.print(stringToDisplay[kkk]);
}
}
if (_textDrawer.getPos().x() >= _distance) {
return it;
}
countColomn += stringToDisplay.size();
}
return end();
}
// TODO : Rename ...
float appl::Buffer::getScreenSize(esize_t _startLinePos, esize_t _stopPos, ewol::Text& _textDrawer)
{
float ret = 0;
etk::UChar currentValue;
esize_t countColomn = 0;
etk::UString stringToDisplay;
_textDrawer.clear();
for (Iterator it = position(_startLinePos);
it != end();
++it) {
currentValue = *it;
//APPL_DEBUG("parse : " << currentValue);
expand(countColomn, currentValue, stringToDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.size(); ++kkk) {
if (stringToDisplay[kkk] == etk::UChar::Return) {
return _textDrawer.getPos().x() + 2; // TODO : Add the +2 for the end of line ...
} else {
_textDrawer.print(stringToDisplay[kkk]);
}
}
ret = _textDrawer.getPos().x();
countColomn += stringToDisplay.size();
}
return ret;
}
// TODO : Rename && rework ...
esize_t appl::Buffer::getMousePosition(const vec2& _relativePos, ewol::Text& _textDrawer) {
etk::UChar currentValue;
vec3 positionCurentDisplay(0,0,0);
vec3 tmpLetterSize = _textDrawer.calculateSize((etk::UChar)'A');
esize_t countColomn = 0;
etk::UString stringToDisplay;
_textDrawer.clear();
_textDrawer.forceLineReturn();
for (Iterator it = begin();
it != end();
++it) {
currentValue = *it;
expand(countColomn, currentValue, stringToDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.size(); ++kkk) {
if (stringToDisplay[kkk] == etk::UChar::Return) {
// TODO : Remove this, use the automatic line manager ...
_textDrawer.forceLineReturn();
countColomn = 0;
} else {
_textDrawer.print(stringToDisplay[kkk]);
}
}
if (-_relativePos.y() >= positionCurentDisplay.y()) {
if (-_relativePos.y() < positionCurentDisplay.y()+tmpLetterSize.y()) {
//APPL_DEBUG("line position : " << _textDrawer.getPos() << " " << positionCurentDisplay );
if ( _relativePos.x() >= positionCurentDisplay.x()
&& _relativePos.x() < _textDrawer.getPos().x() ) {
return it;
}
} else {
return --it;
}
}
positionCurentDisplay = _textDrawer.getPos();
countColomn += stringToDisplay.size();
}
return end();
} }
static const char *ControlCodeTable[32] = { static const char *ControlCodeTable[32] = {
@ -694,45 +318,7 @@ void appl::Buffer::expand(esize_t& _indent, const etk::UChar& _value, etk::UStri
//APPL_DEBUG("plop : " << _out); //APPL_DEBUG("plop : " << _out);
} }
// TODO : No more used !!! appl::Buffer::Iterator appl::Buffer::countForwardNLines(const appl::Buffer::Iterator& _startPos, int32_t _nLines) {
int32_t appl::Buffer::countDispChars(esize_t _startPos, esize_t _posEnd) {
int32_t charCount = 0;
etk::UString expanded;
etk::UChar value;
for (Iterator it = position(_startPos);
it != end();
++it) {
value = *it;
expand(charCount, value, expanded);
charCount += expanded.size();
}
return charCount;
}
// TODO : No more used !!!
esize_t appl::Buffer::countForwardDispChars(esize_t _startPos, int32_t _nChars) {
int32_t charCount = 0;
etk::UString expanded;
etk::UChar value;
for (Iterator it = position(_startPos);
it != end();
++it) {
value = *it;
if (value == etk::UChar::Return) {
return it;
}
expand(charCount, value, expanded);
charCount += expanded.size();
}
return end();
}
esize_t appl::Buffer::countForwardNLines(esize_t _startPos, int32_t _nLines) {
if (_nLines <= 0) {
return _startPos;
} else if (_startPos > m_data.size() ) {
return end();
}
etk::UChar value; etk::UChar value;
int32_t lineCount = 0; int32_t lineCount = 0;
//APPL_INFO("startPos=" << startPos << " nLines=" << nLines); //APPL_INFO("startPos=" << startPos << " nLines=" << nLines);
@ -744,7 +330,7 @@ esize_t appl::Buffer::countForwardNLines(esize_t _startPos, int32_t _nLines) {
lineCount++; lineCount++;
if (lineCount == _nLines) { if (lineCount == _nLines) {
//APPL_INFO(" == > (1) at position=" << myPosIt.Position()+1 ); //APPL_INFO(" == > (1) at position=" << myPosIt.Position()+1 );
return (esize_t)it + 1; return ++it;
} }
} }
} }
@ -752,12 +338,7 @@ esize_t appl::Buffer::countForwardNLines(esize_t _startPos, int32_t _nLines) {
return end(); return end();
} }
esize_t appl::Buffer::countBackwardNLines(esize_t _startPos, int32_t _nLines) { appl::Buffer::Iterator appl::Buffer::countBackwardNLines(const appl::Buffer::Iterator& _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); //APPL_INFO("startPos=" << startPos << " nLines=" << nLines);
etk::UChar value; etk::UChar value;
int32_t lineCount = 0; int32_t lineCount = 0;
@ -795,18 +376,20 @@ bool appl::Buffer::copy(etk::UString& _data) {
return false; return false;
} }
bool appl::Buffer::paste(const etk::UString& _data) { bool appl::Buffer::write(const etk::UString& _data, const appl::Buffer::Iterator& _pos) {
etk::Char output = _data.c_str(); etk::Char output = _data.c_str();
if (hasTextSelected() == true) { m_data.insert(_pos, (int8_t*)((void*)output), output.size());
esize_t startPos = getStartSelectionPos();
esize_t endPos = getStopSelectionPos();
m_data.replace(m_cursorPos, endPos-startPos, (int8_t*)((void*)output), output.size());
} else {
m_data.insert(m_cursorPos, (int8_t*)((void*)output), output.size());
}
m_selectMode = false; m_selectMode = false;
moveCursor(m_cursorPos+output.size()); moveCursor((esize_t)_pos+output.size());
return false; return true;
}
bool appl::Buffer::replace(const etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd) {
etk::Char output = _data.c_str();
m_data.replace(_pos, (esize_t)_posEnd-(esize_t)_pos, (int8_t*)((void*)output), output.size());
m_selectMode = false;
moveCursor((esize_t)_pos+output.size());
return true;
} }
void appl::Buffer::removeSelection(void) { void appl::Buffer::removeSelection(void) {

View File

@ -21,7 +21,6 @@
namespace appl { namespace appl {
class Buffer : public ewol::EObject { class Buffer : public ewol::EObject {
public: public:
class Iterator { class Iterator {
// Private data : // Private data :
private: private:
@ -66,7 +65,7 @@ namespace appl {
* @brief basic boolean cast * @brief basic boolean cast
* @return true if the element is present in buffer * @return true if the element is present in buffer
*/ */
operator bool (void) { operator bool (void) const {
if (m_data == NULL) { if (m_data == NULL) {
return false; return false;
} }
@ -76,7 +75,7 @@ namespace appl {
* @brief basic boolean cast * @brief basic boolean cast
* @return true if the element is present in buffer * @return true if the element is present in buffer
*/ */
operator esize_t (void) { operator esize_t (void) const {
if (m_data == NULL) { if (m_data == NULL) {
return 0; return 0;
} }
@ -114,7 +113,7 @@ namespace appl {
* @brief egality iterator * @brief egality iterator
* @return true if the iterator is identical pos * @return true if the iterator is identical pos
*/ */
bool operator== (const Iterator& _obj) { bool operator== (const Iterator& _obj) const {
if ( m_current == _obj.m_current if ( m_current == _obj.m_current
&& m_data == _obj.m_data) { && m_data == _obj.m_data) {
return true; return true;
@ -125,7 +124,7 @@ namespace appl {
* @brief egality iterator * @brief egality iterator
* @return true if the iterator is identical pos * @return true if the iterator is identical pos
*/ */
bool operator!= (const Iterator& _obj) { bool operator!= (const Iterator& _obj) const {
if ( m_current != _obj.m_current if ( m_current != _obj.m_current
|| m_data != _obj.m_data) { || m_data != _obj.m_data) {
return true; return true;
@ -141,9 +140,31 @@ namespace appl {
* @brief Get the position in the buffer * @brief Get the position in the buffer
* @return The requested position. * @return The requested position.
*/ */
esize_t getPos(void) { esize_t getPos(void) const {
return m_current; return m_current;
} }
/**
* @brief move the element position
* @return a new iterator.
*/
Iterator operator+ (const int32_t _val) const {
Iterator tmpp(*this);
for (int32_t iii=0; iii<_val; ++iii) {
++tmpp;
}
return tmpp;
}
/**
* @brief move the element position
* @return a new iterator.
*/
Iterator operator- (const int32_t _val) const {
Iterator tmpp(*this);
for (int32_t iii=0; iii<_val; ++iii) {
--tmpp;
}
return tmpp;
}
private: private:
Iterator(Buffer* _obj, int32_t _pos) : Iterator(Buffer* _obj, int32_t _pos) :
m_current(_pos), m_current(_pos),
@ -172,23 +193,34 @@ namespace appl {
etk::Buffer& getData(void) { etk::Buffer& getData(void) {
return m_data; return m_data;
}; };
/*
appl::History m_history;
Highlight m_highlight;
ejson::Value* m_property;
appl::Selection m_selection;
*/
public: public:
esize_t m_cursorPos; //!< cursor position. esize_t m_cursorPos; //!< cursor position.
int32_t m_cursorSelectPos; //!< cursor position. int32_t m_cursorSelectPos; //!< cursor position.
public:
void setSelectionPos(const Iterator& _pos);
void unSelect(void);
protected:
float m_cursorPreferredCol; //!< position of the cursor when up and down is done. float m_cursorPreferredCol; //!< position of the cursor when up and down is done.
public:
void setFavoriteUpDownPos(float _val) {
m_cursorPreferredCol = _val;
}
float getFavoriteUpDownPos(void) {
return m_cursorPreferredCol;
}
private:
bool m_selectMode; //!< when true, the select mode keep the moving selecting bool m_selectMode; //!< when true, the select mode keep the moving selecting
public:
bool getSelectMode(void) {
return m_selectMode;
}
void setSelectMode(bool _status) {
m_selectMode = _status;
}
// note : We need the text drawer interface due to the fact that the move depend on the text display properties. // note : We need the text drawer interface due to the fact that the move depend on the text display properties.
bool onEventEntry(const ewol::EventEntry& _event, ewol::Text& _textDrawer); bool onEventEntry(const ewol::EventEntry& _event, ewol::Text& _textDrawer);
bool onEventInput(const ewol::EventInput& _event, ewol::Text& _textDrawer, const vec2& _relativePos); //bool onEventInput(const ewol::EventInput& _event, ewol::Text& _textDrawer, const vec2& _relativePos);
void moveCursor(esize_t _pos); void moveCursor(esize_t _pos);
void mouseEventDouble(void);
void mouseEventTriple(void);
/** /**
* @brief Get the status of selection. * @brief Get the status of selection.
* @return true if we have a curent selection, false otherwise. * @return true if we have a curent selection, false otherwise.
@ -210,30 +242,7 @@ namespace appl {
esize_t getStopSelectionPos(void) { esize_t getStopSelectionPos(void) {
return etk_max(m_cursorPos, m_cursorSelectPos); return etk_max(m_cursorPos, m_cursorSelectPos);
} }
bool selectAround(int32_t _startPos, int32_t &_beginPos, int32_t &_endPos); bool getPosAround(const Iterator& _startPos, Iterator &_beginPos, Iterator &_endPos);
/**
* @brief Get the position in the buffer of a display distance from the start of the line
* @param[in] _startLinePos start of the line
* @param[in] _distance Distane from the start of the line
* @param[in] _textDrawer Drawer compositing element
* @return position in the buffer
*/
esize_t getPosSize(esize_t _startLinePos, float _distance, ewol::Text& _textDrawer);
/**
* @brief Get the real distance displayed from the start of the line to the element requested
* @param[in] _startLinePos start of the line
* @param[in] _stopPos Position that we want to have te distance
* @param[in] _textDrawer Drawer compositing element
* @return Distance from the start of the line
*/
float getScreenSize(esize_t _startLinePos, esize_t _stopPos, ewol::Text& _textDrawer);
/**
* @brief Get the position on the buffer with the position on the mose in the screen
* @param[in] _relativePos mouse position( standard GUI position (not ewol generic pos !!!)
* @param[in] _textDrawer Drawer compositing element
* @return Position in the buffer
*/
esize_t getMousePosition(const vec2& _relativePos, ewol::Text& _textDrawer);
/** /**
* @brief Expand the specify char to have a user frendly display for special char and tabs * @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] _indent Curent indentation in the line
@ -241,44 +250,19 @@ namespace appl {
* @param[out] _out String that represent the curent value to display * @param[out] _out String that represent the curent value to display
*/ */
void expand(esize_t& _indent, const etk::UChar& _value, etk::UString& _out) const; void expand(esize_t& _indent, const etk::UChar& _value, etk::UString& _out) const;
private: public:
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, ...
*/
void moveCursorRight(moveMode _mode = moveLetter);
/**
* Move the cursor left in the line (no stop of a new line)
* @param[in] _mode Moving mode char, word, ...
*/
void moveCursorLeft(moveMode _mode = moveLetter);
/**
* @brief Move the cursor at an other position upper.
* @param[in] _nbLine number of up line that might be moved
*/
void moveCursorUp(esize_t _nbLine, ewol::Text& _textDrawer);
/**
* @brief Move the cursor at an other position under.
* @param[in] _nbLine number of down line that might be moved
*/
void moveCursorDown(esize_t _nbLine, ewol::Text& _textDrawer);
/** /**
* @brief get the start of a line with the position in the buffer. * @brief get the start of a line with the position in the buffer.
* @param[in] _pos position in the buffer. * @param[in] _pos position in the buffer.
* @return The position in the buffer of the start of the line. * @return The position in the buffer of the start of the line.
*/ */
esize_t startLine(esize_t _pos); Iterator getStartLine(const Iterator& _pos);
/** /**
* @brief get the end of a line with the position in the buffer. * @brief get the end of a line with the position in the buffer.
* @param[in] _pos position in the buffer. * @param[in] _pos position in the buffer.
* @return The position in the buffer of the end of the line. * @return The position in the buffer of the end of the line.
*/ */
esize_t endLine(esize_t _pos); Iterator getEndLine(const Iterator& _pos);
/** /**
* @brief Search a character in the buffer. * @brief Search a character in the buffer.
* @param[in] _pos Position to start the search of the element. * @param[in] _pos Position to start the search of the element.
@ -286,7 +270,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 search(esize_t _pos, const etk::UChar& _search, esize_t& _result); bool search(const Iterator& _pos, const etk::UChar& _search, Iterator& _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.
@ -294,37 +278,21 @@ 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 searchBack(esize_t _pos, const etk::UChar& _search, esize_t& _result); bool searchBack(const Iterator& _pos, const etk::UChar& _search, Iterator& _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 * @brief find the first character of the line "nLines" forward
* @param[in,out] _startPos Start position. * @param[in,out] _startPos Start position.
* @param[in,out] _nLines Number of line to count. * @param[in,out] _nLines Number of line to count.
* @return position of the starting the line. * @return position of the starting the line.
*/ */
esize_t countForwardNLines(esize_t _startPos, int32_t _nLines); Iterator countForwardNLines(const Iterator& _startPos, int32_t _nLines);
/** /**
* @brief find the first character of the line "nLines" backwards * @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] _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) * @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 * @return position of the starting the line
*/ */
esize_t countBackwardNLines(esize_t _startPos, int32_t _nLines); Iterator countBackwardNLines(const Iterator& _startPos, int32_t _nLines);
public: public:
/** /**
* @brief copy data in the _data ref value. * @brief copy data in the _data ref value.
@ -332,33 +300,46 @@ namespace appl {
* @return true of no error occured. * @return true of no error occured.
*/ */
bool copy(etk::UString& _data); bool copy(etk::UString& _data);
/**
* @brief past data from the _data ref value.
* @param[in] _data Input stream to copy.
* @return true of no error occured.
*/
bool paste(const etk::UString& _data);
/** /**
* @brief Remove the selection of the buffer. (do nothing if no secection) * @brief Remove the selection of the buffer. (do nothing if no secection)
*/ */
void removeSelection(void); void removeSelection(void);
bool write(const etk::UString& _data, const appl::Buffer::Iterator& _pos);
bool replace(const etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd);
public: // iterator section : public: // iterator section :
/** /**
* @brief Get an iterator an an specific position * @brief Get an iterator an an specific position
* @param[in] _pos Requested position of the iterator in the vector * @param[in] _pos Requested position of the iterator.
* @return The Iterator * @return The Iterator
*/ */
Iterator position(esize_t _pos); Iterator position(esize_t _pos);
/** /**
* @brief Get an Iterator on the start position of the Vector * @brief Get an Iterator on the start position.
* @return The Iterator * @return The Iterator
*/ */
Iterator begin(void); Iterator begin(void);
/** /**
* @brief Get an Iterator on the end position of the Vector * @brief Get an Iterator on the end position.
* @return The Iterator * @return The Iterator
*/ */
Iterator end(void); Iterator end(void);
/**
* @brief Get an Iterator on the cursor position.
* @return The Iterator
*/
Iterator cursor(void);
/**
* @brief Get an Iterator on the start selection.
* @return The Iterator
*/
Iterator selectStart(void);
/**
* @brief Get an Iterator on the stop selection.
* @return The Iterator
*/
Iterator selectStop(void);
}; };
}; };

View File

@ -0,0 +1,45 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#include <appl/Buffer/TextPlugin.h>
#include <appl/Debug.h>
appl::TextViewerPlugin::TextViewerPlugin(void) :
m_isEnable(false),
m_activateOnEventEntry(false),
m_activateOnEventInput(false),
m_activateOnWrite(false),
m_activateOnReplace(false),
m_activateOnRemove(false),
m_activateOnReceiveMessage(false),
m_activateOnCursorMove(false) {
}
appl::TextViewerPlugin::~TextViewerPlugin(void) {
if (m_isEnable == false) {
return;
}
m_isEnable = false;
onPluginDisable();
}
void appl::TextViewerPlugin::setEnableStatus(bool _status) {
if (_status == m_isEnable) {
return;
}
m_isEnable = _status;
if (m_isEnable == true) {
onPluginEnable();
} else {
onPluginDisable();
}
}

View File

@ -0,0 +1,217 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#ifndef __APPL_TEXT_PLUGIN_H__
#define __APPL_TEXT_PLUGIN_H__
#include <etk/types.h>
#include <ewol/renderer/EObject.h>
#include <appl/Gui/TextViewer.h>
#include <ewol/compositing/Text.h>
namespace appl {
class TextViewerPlugin : public ewol::EObject {
friend class appl::TextViewer;
public:
TextViewerPlugin(void);
~TextViewerPlugin(void);
private:
bool m_isEnable; //!< The plugin is enable or not (for all viewer).
public:
/**
* @brief Set activity status of the plugin
* @param[in] _status new activity status
*/
void setEnableStatus(bool _status);
/**
* @brief Get the activity status.
* @return true if the plugin is active, false otherwise.
*/
bool isEnable(void) {
return m_isEnable;
};
public:
/**
* @brief On plugin global enable.
*/
virtual void onPluginEnable(void) {
// nothing to do here ...
};
/**
* @brief On plugin global disable.
*/
virtual void onPluginDisable(void) {
// nothing to do here ...
};
/**
* @brief On plugin enable on a specific text viewer.
* @param[in] _widget Reference on the widget caller.
*/
virtual void onPluginEnable(appl::TextViewer& _textDrawer) {
// nothing to do here ...
};
/**
* @brief On plugin disable on a specific text viewer.
* @param[in] _widget Reference on the widget caller.
*/
virtual void onPluginDisable(appl::TextViewer& _textDrawer) {
// nothing to do here ...
};
protected:
bool m_activateOnEventEntry; //!< onEventEntry is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnEventEntry(void) {
return m_activateOnEventEntry;
}
/**
* @brief On entry event call.
* @param[in] _widget Reference on the widget caller.
* @param[in] _event Generic event.
* @return true if the event might not propagate anymore.
*/
virtual bool onEventEntry(appl::TextViewer& _textDrawer,
const ewol::EventEntry& _event) {
return false;
};
protected:
bool m_activateOnEventInput; //!< onEventInput is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnEventInput(void) {
return m_activateOnEventInput;
}
/**
* @brief On Input event call.
* @param[in] _widget Reference on the widget caller.
* @param[in] _event Generic event.
* @return true if the event might not propagate anymore
*/
virtual bool onEventInput(appl::TextViewer& _textDrawer,
const ewol::EventInput& _event) {
return false;
};
protected:
bool m_activateOnWrite; //!< onWrite is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnWrite(void) {
return m_activateOnWrite;
}
/**
* @brief Called when data is written in the buffer.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos Position in the buffer where data might be witten.
* @param[in] _data Input stream written.
* @return true if the event might not propagate anymore
*/
virtual bool onWrite(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const etk::UString& _data) {
return false;
};
protected:
bool m_activateOnReplace; //!< onReplace is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnReplace(void) {
return m_activateOnReplace;
}
/**
* @brief Called when data is written in the buffer, and some are removed.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos Position in the buffer where data might be witten.
* @param[in] _data Input stream written.
* @param[in] _posEnd end replace position.
* @return true if the event might not propagate anymore
*/
virtual bool onReplace(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const etk::UString& _data,
const appl::Buffer::Iterator& _posEnd) {
return false;
};
protected:
bool m_activateOnRemove; //!< onRemove is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnRemove(void) {
return m_activateOnRemove;
}
/**
* @brief Called when data is removed.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos Position in the buffer where data might be witten.
* @param[in] _posEnd end replace position.
* @return true if the event might not propagate anymore
*/
virtual bool onRemove(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const appl::Buffer::Iterator& _posEnd) {
return false;
};
protected:
bool m_activateOnReceiveMessage; //!< onReceiveMessage is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnReceiveMessage(void) {
return m_activateOnReceiveMessage;
}
/**
* @brief Called when a message arrive.
* @param[in] _widget Reference on the widget caller.
* @param[in] _msg Generic message.
* @return true if the event might not propagate anymore
*/
virtual bool onReceiveMessage(appl::TextViewer& _textDrawer,
const ewol::EMessage& _msg) {
return false;
}
protected:
bool m_activateOnCursorMove; //!< onCursorMove is availlable for this plugin.
public:
/**
* @brief Get the availlability of a callback
* @return true if availlable
*/
bool isAvaillableOnCursorMove(void) {
return m_activateOnCursorMove;
}
/**
* @brief Called when Cursor move of position.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos New cursor position.
* @return true if the event might not propagate anymore
*/
virtual bool onCursorMove(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos) {
return false;
}
};
};
#endif

View File

@ -0,0 +1,38 @@
// just forward event == > manage directly in the buffer
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) {
return false;
}
etk::UChar localValue = _event.getChar();
if (localValue == etk::UChar::Return) {
if (true == _event.getSpecialKey().isSetShift()) {
localValue = etk::UChar::CarrierReturn;
} else {
/*
m_data.insert(m_cursorPos, '\n');
if (true == globals::isSetAutoIndent() ) {
int32_t l_lineStart;
// get the begin of the line or the begin of the line befor selection
if (false == haveSelectionActive) {
l_lineStart = m_EdnBuf.StartOfLine(m_cursorPos);
} else {
l_lineStart = m_EdnBuf.StartOfLine(SelectionStart);
}
// add same characters in the temporar buffer
for (int32_t kk=l_lineStart; kk<m_cursorPos; kk++) {
if (' ' == m_EdnBuf[kk]) {
tmpVect.pushBack(' ');
} else if('\t' == m_EdnBuf[kk]) {
tmpVect.pushBack('\t');
} else {
break;
}
}
}
m_selectMode = false;
moveCursor(m_cursorPos + 1);
return true;
*/
}

View File

@ -0,0 +1,54 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#include <appl/Buffer/TextPluginCopy.h>
#include <ewol/clipBoard.h>
#include <appl/Gui/TextViewer.h>
appl::TextPluginCopy::TextPluginCopy(void) {
m_activateOnReceiveMessage = true;
}
void appl::TextPluginCopy::onPluginEnable(appl::TextViewer& _textDrawer) {
// add event :
_textDrawer.registerMultiCast(ednMsgGuiCopy);
_textDrawer.registerMultiCast(ednMsgGuiPaste);
_textDrawer.registerMultiCast(ednMsgGuiCut);
_textDrawer.shortCutAdd("ctrl+x", ednMsgGuiCut, "STD");
_textDrawer.shortCutAdd("ctrl+c", ednMsgGuiCopy, "STD");
_textDrawer.shortCutAdd("ctrl+v", ednMsgGuiPaste, "STD");
}
void appl::TextPluginCopy::onPluginDisable(appl::TextViewer& _textDrawer) {
// TODO : unknow function ...
}
bool appl::TextPluginCopy::onReceiveMessage(appl::TextViewer& _textDrawer, const ewol::EMessage& _msg) {
if ( _msg.getMessage() == ednMsgGuiCopy
|| _msg.getMessage() == ednMsgGuiCut) {
if (_textDrawer.m_buffer != NULL) {
etk::UString value;
_textDrawer.m_buffer->copy(value);
if (value.size() != 0) {
ewol::clipBoard::set(ewol::clipBoard::clipboardStd, value);
}
}
if (_msg.getMessage() == ednMsgGuiCut) {
_textDrawer.m_buffer->removeSelection();
}
return true;
} else if (_msg.getMessage() == ednMsgGuiPaste) {
if (_textDrawer.m_buffer != NULL) {
ewol::clipBoard::request(ewol::clipBoard::clipboardStd);
}
return true;
}
return false;
}

View File

@ -0,0 +1,33 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#ifndef __APPL_TEXT_PLUGIN_COPY_H__
#define __APPL_TEXT_PLUGIN_COPY_H__
#include <etk/types.h>
#include <ewol/renderer/EObject.h>
#include <appl/Gui/TextViewer.h>
#include <ewol/compositing/Text.h>
#include <appl/Buffer/TextPlugin.h>
namespace appl {
class TextPluginCopy : public appl::TextViewerPlugin {
public:
TextPluginCopy(void);
~TextPluginCopy(void) {
// nothing to do ...
};
public:
virtual void onPluginEnable(appl::TextViewer& _textDrawer);
virtual void onPluginDisable(appl::TextViewer& _textDrawer);
virtual bool onReceiveMessage(appl::TextViewer& _textDrawer, const ewol::EMessage& _msg);
};
};
#endif

View File

@ -0,0 +1,221 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#include <appl/Buffer/TextPluginManager.h>
#include <appl/Debug.h>
#include <appl/Buffer/TextPluginCopy.h>
static etk::Vector<appl::TextViewerPlugin *>& getList(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnEventEntry(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnEventInput(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnWrite(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnReplace(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnRemove(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnReceiveMessage(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
static etk::Vector<appl::TextViewerPlugin *>& getListOnCursorMove(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
return s_list;
}
void appl::textPluginManager::init(void) {
}
void appl::textPluginManager::unInit(void) {
// remove all sub plugin class:
getListOnEventEntry().clear();
getListOnEventInput().clear();
getListOnWrite().clear();
getListOnReplace().clear();
getListOnRemove().clear();
getListOnReceiveMessage().clear();
getListOnCursorMove().clear();
// remove all plugin:
for (esize_t iii=0; iii<getList().size(); ++iii) {
if (getList()[iii] == NULL) {
continue;
}
delete(getList()[iii]);
getList()[iii] = NULL;
}
getList().clear();
}
void appl::textPluginManager::addDefaultPlugin(void) {
appl::textPluginManager::addPlugin(new appl::TextPluginCopy());
}
void appl::textPluginManager::addPlugin(appl::TextViewerPlugin* _plugin) {
if (_plugin == NULL) {
return;
}
getList().pushBack(_plugin);
if (_plugin->isAvaillableOnEventEntry() == true) {
getListOnEventEntry().pushBack(_plugin);
}
if (_plugin->isAvaillableOnEventInput() == true) {
getListOnEventInput().pushBack(_plugin);
}
if (_plugin->isAvaillableOnWrite() == true) {
getListOnWrite().pushBack(_plugin);
}
if (_plugin->isAvaillableOnReplace() == true) {
getListOnReplace().pushBack(_plugin);
}
if (_plugin->isAvaillableOnRemove() == true) {
getListOnRemove().pushBack(_plugin);
}
if (_plugin->isAvaillableOnReceiveMessage() == true) {
getListOnReceiveMessage().pushBack(_plugin);
}
if (_plugin->isAvaillableOnCursorMove() == true) {
getListOnCursorMove().pushBack(_plugin);
}
}
void appl::textPluginManager::connect(appl::TextViewer& _widget) {
for (esize_t iii=0; iii<getList().size(); ++iii) {
if (getList()[iii] == NULL) {
continue;
}
getList()[iii]->onPluginEnable(_widget);
}
}
void appl::textPluginManager::disconnect(appl::TextViewer& _widget) {
for (esize_t iii=0; iii<getList().size(); ++iii) {
if (getList()[iii] == NULL) {
continue;
}
getList()[iii]->onPluginDisable(_widget);
}
}
bool appl::textPluginManager::onEventEntry(appl::TextViewer& _textDrawer,
const ewol::EventEntry& _event) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnEventEntry();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onEventEntry(_textDrawer, _event) == true ) {
return true;
}
}
return false;
}
bool appl::textPluginManager::onEventInput(appl::TextViewer& _textDrawer,
const ewol::EventInput& _event) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnEventInput();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onEventInput(_textDrawer, _event) == true ) {
return true;
}
}
return false;
}
bool appl::textPluginManager::onWrite(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const etk::UString& _data) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnWrite();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onWrite(_textDrawer, _pos, _data) == true ) {
return true;
}
}
return false;
}
bool appl::textPluginManager::onReplace(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const etk::UString& _data,
const appl::Buffer::Iterator& _posEnd) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnReplace();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onReplace(_textDrawer, _pos, _data, _posEnd) == true ) {
return true;
}
}
return false;
}
bool appl::textPluginManager::onRemove(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const appl::Buffer::Iterator& _posEnd) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnRemove();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onRemove(_textDrawer, _pos, _posEnd) == true ) {
return true;
}
}
return false;
}
bool appl::textPluginManager::onReceiveMessage(appl::TextViewer& _textDrawer,
const ewol::EMessage& _msg) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnReceiveMessage();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onReceiveMessage(_textDrawer, _msg) == true ) {
return true;
}
}
return false;
}
bool appl::textPluginManager::onCursorMove(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos) {
etk::Vector<appl::TextViewerPlugin *>& list = getListOnCursorMove();
for (esize_t iii=0; iii<list.size(); ++iii) {
if (list[iii] == NULL) {
continue;
}
if (list[iii]->onCursorMove(_textDrawer, _pos) == true ) {
return true;
}
}
return false;
}

View File

@ -0,0 +1,115 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#ifndef __APPL_TEXT_PLUGIN_MANAGER_H__
#define __APPL_TEXT_PLUGIN_MANAGER_H__
#include <etk/types.h>
#include <ewol/renderer/EObject.h>
#include <appl/Gui/TextViewer.h>
#include <ewol/compositing/Text.h>
#include <appl/Buffer/TextPlugin.h>
namespace appl {
namespace textPluginManager {
/**
* @brief Init the plugin manager for writer.
*/
void init(void);
/**
* @brief UnInit the plugin manager for writer.
*/
void unInit(void);
/**
* @brief Add default plugin list
*/
void addDefaultPlugin(void);
/**
* @brief Add a plugin.
* @param[in] _plugin Plugin pointer to add.
*/
void addPlugin(appl::TextViewerPlugin* _plugin);
/**
* @brief connect a new widget to the plugin.
* @param[in] _widget Reference on the widget caller.
*/
void connect(appl::TextViewer& _widget);
/**
* @brief dis-connect a new widget to the plugin.
* @param[in] _widget Reference on the widget caller.
*/
void disconnect(appl::TextViewer& _widget);
/**
* @brief On entry event call.
* @param[in] _widget Reference on the widget caller.
* @param[in] _event Generic event.
* @return true if the event might not propagate anymore.
*/
bool onEventEntry(appl::TextViewer& _widget,
const ewol::EventEntry& _event);
/**
* @brief On Input event call.
* @param[in] _widget Reference on the widget caller.
* @param[in] _event Generic event.
* @return true if the event might not propagate anymore
*/
bool onEventInput(appl::TextViewer& _textDrawer,
const ewol::EventInput& _event);
/**
* @brief Called when data is written in the buffer.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos Position in the buffer where data might be witten.
* @param[in] _data Input stream written.
* @return true if the event might not propagate anymore
*/
bool onWrite(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const etk::UString& _data);
/**
* @brief Called when data is written in the buffer, and some are removed.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos Position in the buffer where data might be witten.
* @param[in] _data Input stream written.
* @param[in] _posEnd end replace position.
* @return true if the event might not propagate anymore
*/
bool onReplace(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const etk::UString& _data,
const appl::Buffer::Iterator& _posEnd);
/**
* @brief Called when data is removed.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos Position in the buffer where data might be witten.
* @param[in] _posEnd end replace position.
* @return true if the event might not propagate anymore
*/
bool onRemove(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos,
const appl::Buffer::Iterator& _posEnd);
/**
* @brief Called when a message arrive.
* @param[in] _widget Reference on the widget caller.
* @param[in] _msg Generic message.
* @return true if the event might not propagate anymore
*/
bool onReceiveMessage(appl::TextViewer& _textDrawer,
const ewol::EMessage& _msg);
/**
* @brief Called when Cursor move of position.
* @param[in] _widget Reference on the widget caller.
* @param[in] _pos New cursor position.
* @return true if the event might not propagate anymore
*/
bool onCursorMove(appl::TextViewer& _textDrawer,
const appl::Buffer::Iterator& _pos);
};
};
#endif

View File

@ -0,0 +1,22 @@
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) {
return false;
}
etk::UChar localValue = _event.getChar();
if (localValue == etk::UChar::Tabulation) {
if (hasTextSelected()) {
// TODO : Special tabulation multiline indentation ...
/*
int32_t nbSelectedLines = m_EdnBuf.CountLines(SelectionStart, SelectionEnd);
if (1 < nbSelectedLines) {
if (true == _event.getSpecialKey().isSetShift() ) {
m_cursorPos = m_EdnBuf.UnIndent();
} else {
m_cursorPos = m_EdnBuf.Indent();
}
}
*/
markToRedraw();
return true;
}

View File

@ -16,6 +16,7 @@
#include <ewol/widget/WidgetManager.h> #include <ewol/widget/WidgetManager.h>
#include <ewol/renderer/EObject.h> #include <ewol/renderer/EObject.h>
#include <appl/Buffer/TextPluginManager.h>
#undef __class__ #undef __class__
#define __class__ "TextViewer" #define __class__ "TextViewer"
@ -26,9 +27,6 @@ appl::TextViewer::TextViewer(const etk::UString& _fontName, int32_t _fontSize) :
m_insertMode(false) { m_insertMode(false) {
setCanHaveFocus(true); setCanHaveFocus(true);
registerMultiCast(ednMsgBufferId); registerMultiCast(ednMsgBufferId);
registerMultiCast(ednMsgGuiCopy);
registerMultiCast(ednMsgGuiPaste);
registerMultiCast(ednMsgGuiCut);
registerMultiCast(ednMsgGuiRedo); registerMultiCast(ednMsgGuiRedo);
registerMultiCast(ednMsgGuiUndo); registerMultiCast(ednMsgGuiUndo);
registerMultiCast(ednMsgGuiRm); registerMultiCast(ednMsgGuiRm);
@ -41,9 +39,6 @@ appl::TextViewer::TextViewer(const etk::UString& _fontName, int32_t _fontSize) :
shortCutAdd("ctrl+w", ednMsgGuiRm, "Line"); shortCutAdd("ctrl+w", ednMsgGuiRm, "Line");
shortCutAdd("ctrl+shift+w", ednMsgGuiRm, "Paragraph"); shortCutAdd("ctrl+shift+w", ednMsgGuiRm, "Paragraph");
shortCutAdd("ctrl+x", ednMsgGuiCut, "STD");
shortCutAdd("ctrl+c", ednMsgGuiCopy, "STD");
shortCutAdd("ctrl+v", ednMsgGuiPaste, "STD");
shortCutAdd("ctrl+a", ednMsgGuiSelect, "ALL"); shortCutAdd("ctrl+a", ednMsgGuiSelect, "ALL");
shortCutAdd("ctrl+shift+a", ednMsgGuiSelect, "NONE"); shortCutAdd("ctrl+shift+a", ednMsgGuiSelect, "NONE");
@ -56,10 +51,11 @@ appl::TextViewer::TextViewer(const etk::UString& _fontName, int32_t _fontSize) :
} }
m_buffer->loadFile("./example.txt"); m_buffer->loadFile("./example.txt");
appl::textPluginManager::connect(*this);
} }
appl::TextViewer::~TextViewer(void) { appl::TextViewer::~TextViewer(void) {
appl::textPluginManager::disconnect(*this);
} }
bool appl::TextViewer::calculateMinSize(void) { bool appl::TextViewer::calculateMinSize(void) {
@ -177,8 +173,103 @@ bool appl::TextViewer::onEventEntry(const ewol::EventEntry& _event) {
if (m_buffer == NULL) { if (m_buffer == NULL) {
return false; return false;
} }
// First call plugin
if (appl::textPluginManager::onEventEntry(*this, _event) == true) {
markToRedraw();
return true;
}
// just forward event == > manage directly in the buffer // just forward event == > manage directly in the buffer
if (m_buffer->onEventEntry(_event, m_displayText) == true) { 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) {
return false;
}
etk::UChar localValue = _event.getChar();
if (localValue == etk::UChar::Return) {
if (true == _event.getSpecialKey().isSetShift()) {
localValue = etk::UChar::CarrierReturn;
}
} else if (localValue == etk::UChar::Suppress ) {
//APPL_INFO("keyEvent : <suppr> pos=" << m_cursorPos);
if (m_buffer->hasTextSelected()) {
m_buffer->removeSelection();
} else {
appl::Buffer::Iterator pos = m_buffer->cursor();
appl::Buffer::Iterator posEnd = pos;
++posEnd;
replace("", pos, posEnd);
}
return true;
} else if (localValue == etk::UChar::Delete) {
//APPL_INFO("keyEvent : <del> pos=" << m_cursorPos);
if (m_buffer->hasTextSelected()) {
m_buffer->removeSelection();
} else {
appl::Buffer::Iterator pos = m_buffer->cursor();
appl::Buffer::Iterator posEnd = pos;
--pos;
replace("", pos, posEnd);
}
markToRedraw();
return true;
}
m_buffer->setSelectMode(false);
// normal adding char ...
char output[5];
int32_t nbElement = localValue.getUtf8(output);
if ( m_buffer->hasTextSelected() == false
&& _event.getSpecialKey().isSetInsert() == true) {
appl::Buffer::Iterator pos = m_buffer->cursor();
appl::Buffer::Iterator posEnd = pos;
++posEnd;
replace(localValue, pos, posEnd);
} else {
etk::UString myString = output;
write(myString);
}
markToRedraw();
return true;
}
// move events ...
if (_event.getStatus() == ewol::keyEvent::statusDown) {
bool needUpdatePosition = true;
// check selection event ...
switch(_event.getType()) {
case ewol::keyEvent::keyboardLeft:
//APPL_INFO("keyEvent : <LEFT>");
moveCursorLeft();
break;
case ewol::keyEvent::keyboardRight:
//APPL_INFO("keyEvent : <RIGHT>");
moveCursorRight();
break;
case ewol::keyEvent::keyboardUp:
//APPL_INFO("keyEvent : <UP>");
moveCursorUp(1);
break;
case ewol::keyEvent::keyboardDown:
//APPL_INFO("keyEvent : <DOWN>");
moveCursorDown(1);
break;
case ewol::keyEvent::keyboardPageUp:
//APPL_INFO("keyEvent : <PAGE-UP>");
//TextDMoveUp(m_displaySize.y());
break;
case ewol::keyEvent::keyboardPageDown:
//APPL_INFO("keyEvent : <PAGE-DOWN>");
//TextDMoveDown(m_displaySize.y());
break;
case ewol::keyEvent::keyboardStart:
//APPL_INFO("keyEvent : <Start of line>");
moveCursorLeft(moveEnd);
break;
case ewol::keyEvent::keyboardEnd:
//APPL_INFO("keyEvent : <End of line>");
moveCursorRight(moveEnd);
break;
default:
break;
}
markToRedraw(); markToRedraw();
return true; return true;
} }
@ -190,44 +281,144 @@ bool appl::TextViewer::onEventInput(const ewol::EventInput& _event) {
return false; return false;
} }
keepFocus(); keepFocus();
vec2 relativePos = relativePosition(_event.getPos()); // First call plugin
// invert for the buffer event ... if (appl::textPluginManager::onEventInput(*this, _event) == true) {
relativePos.setY(m_size.y()-relativePos.y());
// just forward event == > manage directly in the buffer
if (m_buffer->onEventInput(_event, m_displayText, relativePos) == true) {
markToRedraw(); markToRedraw();
return true; return true;
} }
return true; vec2 relativePos = relativePosition(_event.getPos());
// invert for the buffer event ...
relativePos.setY(m_size.y()-relativePos.y());
if (relativePos.x()<0) {
relativePos.setX(0);
}
// just forward event == > manage directly in the buffer
if (_event.getId() == 1) {
// mouse selection :
if (_event.getType() == ewol::keyEvent::typeMouse) {
if (_event.getStatus() == ewol::keyEvent::statusDown) {
appl::Buffer::Iterator newPos = getMousePosition(relativePos);
moveCursor(newPos);
m_buffer->setSelectMode(true);
markToRedraw();
return true;
} else if (_event.getStatus() == ewol::keyEvent::statusUp) {
appl::Buffer::Iterator newPos = getMousePosition(relativePos);
moveCursor(newPos);
m_buffer->setSelectMode(false);
// TODO : Copy selection :
//tmpBuffer->Copy(ewol::clipBoard::clipboardSelection);
markToRedraw();
return true;
}
}
if (_event.getStatus() == ewol::keyEvent::statusSingle) {
if (_event.getType() == ewol::keyEvent::typeMouse) {
appl::Buffer::Iterator newPos = getMousePosition(relativePos);
moveCursor(newPos);
markToRedraw();
return true;
}
} else if (_event.getStatus() == ewol::keyEvent::statusDouble) {
mouseEventDouble();
markToRedraw();
return true;
} else if (_event.getStatus() == ewol::keyEvent::statusTriple) {
mouseEventTriple();
markToRedraw();
return true;
} else if (_event.getStatus() == ewol::keyEvent::statusMove) {
if (m_buffer->getSelectMode() == true) {
appl::Buffer::Iterator newPos = getMousePosition(relativePos);
moveCursor(newPos);
markToRedraw();
return true;
}
}
} else if (2 == _event.getId()) {
if (ewol::keyEvent::statusSingle == _event.getStatus()) {
appl::Buffer::Iterator newPos = getMousePosition(relativePos);
moveCursor(newPos);
ewol::clipBoard::request(ewol::clipBoard::clipboardSelection);
markToRedraw();
return true;
}
}
return false;
}
void appl::TextViewer::mouseEventDouble(void) {
//m_selectMode = false;
appl::Buffer::Iterator beginPos, endPos;
if (true == m_buffer->getPosAround(m_buffer->cursor(), beginPos, endPos)) {
moveCursor(endPos);
m_buffer->setSelectionPos(beginPos);
}
// TODO : copy(ewol::clipBoard::clipboardSelection);
}
void appl::TextViewer::mouseEventTriple(void) {
//m_selectMode = false;
moveCursor(m_buffer->getEndLine(m_buffer->cursor()));
m_buffer->setSelectionPos(m_buffer->getStartLine(m_buffer->cursor()));
// TODO : copy(ewol::clipBoard::clipboardSelection);
}
appl::Buffer::Iterator appl::TextViewer::getMousePosition(const vec2& _relativePos) {
etk::UChar currentValue;
vec3 positionCurentDisplay(0,0,0);
vec3 tmpLetterSize = m_displayText.calculateSize((etk::UChar)'A');
esize_t countColomn = 0;
etk::UString stringToDisplay;
m_displayText.clear();
m_displayText.forceLineReturn();
for (appl::Buffer::Iterator it = m_buffer->begin();
it != m_buffer->end();
++it) {
currentValue = *it;
m_buffer->expand(countColomn, currentValue, stringToDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.size(); ++kkk) {
if (stringToDisplay[kkk] == etk::UChar::Return) {
// TODO : Remove this, use the automatic line manager ...
m_displayText.forceLineReturn();
countColomn = 0;
} else {
m_displayText.print(stringToDisplay[kkk]);
}
}
if (-_relativePos.y() >= positionCurentDisplay.y()) {
if (-_relativePos.y() < positionCurentDisplay.y()+tmpLetterSize.y()) {
//APPL_DEBUG("line position : " << _textDrawer.getPos() << " " << positionCurentDisplay );
if ( _relativePos.x() >= positionCurentDisplay.x()
&& _relativePos.x() < m_displayText.getPos().x() ) {
return it;
}
} else {
return --it;
}
}
positionCurentDisplay = m_displayText.getPos();
countColomn += stringToDisplay.size();
}
return m_buffer->end();
} }
void appl::TextViewer::onEventClipboard(ewol::clipBoard::clipboardListe_te _clipboardID) { void appl::TextViewer::onEventClipboard(ewol::clipBoard::clipboardListe_te _clipboardID) {
if (m_buffer != NULL) { if (m_buffer != NULL) {
etk::UString data = ewol::clipBoard::get(_clipboardID); etk::UString data = ewol::clipBoard::get(_clipboardID);
m_buffer->paste(data); write(data);
} }
markToRedraw(); markToRedraw();
} }
void appl::TextViewer::onReceiveMessage(const ewol::EMessage& _msg) { void appl::TextViewer::onReceiveMessage(const ewol::EMessage& _msg) {
// force redraw of the widget // First call plugin
if ( _msg.getMessage() == ednMsgGuiCopy if (appl::textPluginManager::onReceiveMessage(*this, _msg) == true) {
|| _msg.getMessage() == ednMsgGuiCut) { markToRedraw();
if (m_buffer != NULL) { return;
etk::UString value; }
m_buffer->copy(value); if (_msg.getMessage() == ednMsgGuiUndo) {
if (value.size() != 0) {
ewol::clipBoard::set(ewol::clipBoard::clipboardStd, value);
}
}
if (_msg.getMessage() == ednMsgGuiCut) {
m_buffer->removeSelection();
}
} else if (_msg.getMessage() == ednMsgGuiPaste) {
if (m_buffer != NULL) {
ewol::clipBoard::request(ewol::clipBoard::clipboardStd);
}
} else if (_msg.getMessage() == ednMsgGuiUndo) {
if (m_buffer != NULL) { if (m_buffer != NULL) {
//m_buffer->undo(); //m_buffer->undo();
} }
@ -258,3 +449,231 @@ void appl::TextViewer::setFontName(const etk::UString& _fontName) {
m_displayText.setFontName(_fontName); m_displayText.setFontName(_fontName);
} }
bool appl::TextViewer::moveCursor(const appl::Buffer::Iterator& _pos) {
if (m_buffer == NULL) {
return false;
}
if (appl::textPluginManager::onCursorMove(*this, _pos) == true) {
return true;
}
m_buffer->moveCursor((esize_t)_pos);
return true;
}
bool appl::TextViewer::write(const etk::UString& _data) {
if (m_buffer == NULL) {
return false;
}
if (m_buffer->hasTextSelected() == true) {
return replace(_data);
}
return write(_data, m_buffer->cursor());
}
bool appl::TextViewer::write(const etk::UString& _data, const appl::Buffer::Iterator& _pos) {
if (m_buffer == NULL) {
return false;
}
bool ret = false;
if (appl::textPluginManager::onWrite(*this, _pos, _data) == true) {
ret = true;
} else {
ret = m_buffer->write(_data, _pos);
}
appl::textPluginManager::onCursorMove(*this, m_buffer->cursor());
return ret;
}
bool appl::TextViewer::replace(const etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd) {
if (m_buffer == NULL) {
return false;
}
bool ret = false;
if (appl::textPluginManager::onReplace(*this, _pos, _data, _posEnd) == true) {
ret = true;
} else {
ret = m_buffer->replace(_data, _pos, _posEnd);
}
appl::textPluginManager::onCursorMove(*this, m_buffer->cursor());
return ret;
}
bool appl::TextViewer::replace(const etk::UString& _data) {
if (m_buffer == NULL) {
return false;
}
if (m_buffer->hasTextSelected() == false) {
return write(_data);
}
return replace(_data, m_buffer->selectStart(), m_buffer->selectStop());
}
void appl::TextViewer::remove(void) {
if (m_buffer == NULL) {
return;
}
if (m_buffer->hasTextSelected() == false) {
// nothing to do ...
return;
}
if (appl::textPluginManager::onRemove(*this, m_buffer->selectStart(), m_buffer->selectStop()) == false) {
m_buffer->removeSelection();
}
appl::textPluginManager::onCursorMove(*this, m_buffer->cursor());
}
void appl::TextViewer::moveCursorRight(appl::TextViewer::moveMode _mode) {
if (m_buffer == NULL) {
return;
}
appl::Buffer::Iterator it;
switch (_mode) {
default:
case moveLetter:
it = m_buffer->cursor();
++it;
moveCursor(it);
break;
case moveWord:
// TODO : ...
break;
case moveEnd:
it = m_buffer->getEndLine(m_buffer->cursor());
moveCursor(it);
break;
}
}
void appl::TextViewer::moveCursorLeft(appl::TextViewer::moveMode _mode) {
if (m_buffer == NULL) {
return;
}
appl::Buffer::Iterator it;
switch (_mode) {
default:
case moveLetter:
it = m_buffer->cursor();;
--it;
moveCursor(it);
break;
case moveWord:
// TODO : ...
break;
case moveEnd:
it = m_buffer->getStartLine(m_buffer->cursor());
moveCursor(++it);
break;
}
}
void appl::TextViewer::moveCursorUp(esize_t _nbLine) {
if (m_buffer == NULL) {
return;
}
// find the position of the start of the line.
appl::Buffer::Iterator lineStartPos = m_buffer->getStartLine(m_buffer->cursor());
// check if we can go up ...
if (lineStartPos == m_buffer->begin()) {
return;
}
// Decide what column to move to, if there's a preferred column use that
if (m_buffer->getFavoriteUpDownPos() < 0) {
// TODO : Remove this +1 !!!
m_buffer->setFavoriteUpDownPos(getScreenSize(lineStartPos+1, m_buffer->cursor()));
}
EWOL_DEBUG("ploop : " << m_buffer->getFavoriteUpDownPos());
// get the previous line
appl::Buffer::Iterator prevLineStartPos = m_buffer->countBackwardNLines(lineStartPos, _nbLine);
//APPL_INFO("Move line UP result : prevLineStartPos=" << prevLineStartPos);
// get the display char position
appl::Buffer::Iterator newPos = getPosSize(prevLineStartPos, m_buffer->getFavoriteUpDownPos());
//APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
float posStore = m_buffer->getFavoriteUpDownPos();
moveCursor(newPos);
m_buffer->setFavoriteUpDownPos(posStore);
}
void appl::TextViewer::moveCursorDown(esize_t _nbLine) {
if (m_buffer == NULL) {
return;
}
// check if we are not at the end of Buffer
if (m_buffer->cursor() == m_buffer->end() ) {
return;
}
// find the position of the start of the line.
appl::Buffer::Iterator lineStartPos = m_buffer->getStartLine(m_buffer->cursor());
if (m_buffer->getFavoriteUpDownPos() < 0) {
// TODO : Remove this +1 !!!
m_buffer->setFavoriteUpDownPos(getScreenSize(lineStartPos+1, m_buffer->cursor()));
}
EWOL_DEBUG("ploop : " << m_buffer->getFavoriteUpDownPos());
// get the next line :
appl::Buffer::Iterator nextLineStartPos = m_buffer->countForwardNLines(lineStartPos, _nbLine);
//APPL_INFO("Move line DOWN result : nextLineStartPos=" << nextLineStartPos);
// get the display char position
appl::Buffer::Iterator newPos = getPosSize(nextLineStartPos, m_buffer->getFavoriteUpDownPos());
//APPL_INFO("Move to colomn : column=" << column << " newPos=" << newPos);
float posStore = m_buffer->getFavoriteUpDownPos();
moveCursor(newPos);
m_buffer->setFavoriteUpDownPos(posStore);
}
// TODO : Rename ...
appl::Buffer::Iterator appl::TextViewer::getPosSize(const appl::Buffer::Iterator& _startLinePos, float _distance) {
etk::UChar currentValue;
esize_t countColomn = 0;
etk::UString stringToDisplay;
m_displayText.clear();
m_displayText.forceLineReturn();
for (appl::Buffer::Iterator it = _startLinePos;
it != m_buffer->end();
++it) {
currentValue = *it;
m_buffer->expand(countColomn, currentValue, stringToDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.size(); ++kkk) {
if (stringToDisplay[kkk] == etk::UChar::Return) {
return it;
} else {
m_displayText.print(stringToDisplay[kkk]);
}
}
if (m_displayText.getPos().x() >= _distance) {
return it;
}
countColomn += stringToDisplay.size();
}
return m_buffer->end();
}
// TODO : Rename ...
float appl::TextViewer::getScreenSize(const appl::Buffer::Iterator& _startLinePos, const appl::Buffer::Iterator& _stopPos) {
float ret = 0;
etk::UChar currentValue;
esize_t countColomn = 0;
etk::UString stringToDisplay;
m_displayText.clear();
for (appl::Buffer::Iterator it = _startLinePos;
it != m_buffer->end() || it != _stopPos;
++it) {
currentValue = *it;
//APPL_DEBUG("parse : " << currentValue);
m_buffer->expand(countColomn, currentValue, stringToDisplay);
for (esize_t kkk=0; kkk<stringToDisplay.size(); ++kkk) {
if (stringToDisplay[kkk] == etk::UChar::Return) {
return m_displayText.getPos().x() + 2; // TODO : Add the +2 for the end of line ...
} else {
m_displayText.print(stringToDisplay[kkk]);
}
}
ret = m_displayText.getPos().x();
countColomn += stringToDisplay.size();
}
return ret;
}

View File

@ -18,7 +18,11 @@
#include <ewol/compositing/Drawing.h> #include <ewol/compositing/Drawing.h>
namespace appl { namespace appl {
class TextViewerPlugin;
class TextPluginCopy;
class TextViewer : public widget::WidgetScrooled { class TextViewer : public widget::WidgetScrooled {
friend class appl::TextViewerPlugin;
friend class appl::TextPluginCopy;
public: public:
TextViewer(const etk::UString& _fontName="", int32_t _fontSize=-1); TextViewer(const etk::UString& _fontName="", int32_t _fontSize=-1);
virtual ~TextViewer(void); virtual ~TextViewer(void);
@ -34,7 +38,7 @@ namespace appl {
protected: // derived function protected: // derived function
virtual void onDraw(void); virtual void onDraw(void);
public: // Derived function public: // Derived function
const char * const getObjectType(void) { return "ApplCodeView"; }; const char * const getObjectType(void) { return "appl::TextViewer"; };
virtual bool calculateMinSize(void); virtual bool calculateMinSize(void);
virtual void onRegenerateDisplay(void); virtual void onRegenerateDisplay(void);
virtual void onReceiveMessage(const ewol::EMessage& _msg); virtual void onReceiveMessage(const ewol::EMessage& _msg);
@ -45,6 +49,50 @@ namespace appl {
virtual void onLostFocus(void); virtual void onLostFocus(void);
private: private:
bool m_insertMode; //!< the insert mode is enable bool m_insertMode; //!< the insert mode is enable
public:
public:
// TODO : Doc : write data on buffer
bool moveCursor(const appl::Buffer::Iterator& _pos);
bool write(const etk::UString& _data);
bool write(const etk::UString& _data, const appl::Buffer::Iterator& _pos);
bool replace(const etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd);
bool replace(const etk::UString& _data);
void remove(void);
appl::Buffer::Iterator getMousePosition(const vec2& _relativePos);
void mouseEventDouble(void);
void mouseEventTriple(void);
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, ...
*/
void moveCursorRight(moveMode _mode = moveLetter);
/**
* Move the cursor left in the line (no stop of a new line)
* @param[in] _mode Moving mode char, word, ...
*/
void moveCursorLeft(moveMode _mode = moveLetter);
/**
* @brief Move the cursor at an other position upper.
* @param[in] _nbLine number of up line that might be moved
*/
void moveCursorUp(esize_t _nbLine);
/**
* @brief Move the cursor at an other position under.
* @param[in] _nbLine number of down line that might be moved
*/
void moveCursorDown(esize_t _nbLine);
appl::Buffer::Iterator getPosSize(const appl::Buffer::Iterator& _startLinePos, float _distance);
float getScreenSize(const appl::Buffer::Iterator& _startLinePos, const appl::Buffer::Iterator& _stopPos);
}; };
}; };

View File

@ -29,6 +29,7 @@
#include <ewol/commandLine.h> #include <ewol/commandLine.h>
//#include <ewol/UserConfig.h> //#include <ewol/UserConfig.h>
#include <ewol/renderer/eContext.h> #include <ewol/renderer/eContext.h>
#include <appl/Buffer/TextPluginManager.h>
/** /**
* @brief Main of the program (This can be set in every case, but it is not used in Andoid...). * @brief Main of the program (This can be set in every case, but it is not used in Andoid...).
@ -78,6 +79,8 @@ bool APP_Init(ewol::eContext& _context)
HighlightManager::init(); HighlightManager::init();
HighlightManager::loadLanguages(); HighlightManager::loadLanguages();
cTagsManager::init(); cTagsManager::init();
appl::textPluginManager::init();
appl::textPluginManager::addDefaultPlugin();
// Request load of the user configuration ... // Request load of the user configuration ...
//ewol::userConfig::load(); //ewol::userConfig::load();
@ -137,7 +140,7 @@ void APP_UnInit(ewol::eContext& _context)
delete(tmpWindows); delete(tmpWindows);
tmpWindows = NULL; tmpWindows = NULL;
} }
appl::textPluginManager::unInit();
cTagsManager::unInit(); cTagsManager::unInit();
APPL_INFO("Stop Hightlight"); APPL_INFO("Stop Hightlight");

View File

@ -30,6 +30,9 @@ def Create(target):
# All needed for the buffer management : # All needed for the buffer management :
myModule.AddSrcFile([ myModule.AddSrcFile([
'appl/Buffer/Buffer.cpp', 'appl/Buffer/Buffer.cpp',
'appl/Buffer/TextPlugin.cpp',
'appl/Buffer/TextPluginCopy.cpp',
'appl/Buffer/TextPluginManager.cpp',
'appl/Buffer/BufferManager.cpp']) 'appl/Buffer/BufferManager.cpp'])
# Generic color management for the text editor : # Generic color management for the text editor :