edn/sources/appl/Gui/TextViewer.cpp

861 lines
26 KiB
C++
Raw Normal View History

2013-09-19 22:23:31 +02:00
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
2013-10-25 20:49:26 +02:00
#include <appl/debug.h>
2013-09-19 22:23:31 +02:00
#include <appl/global.h>
#include <TextViewer.h>
#include <BufferManager.h>
2013-10-25 22:12:34 +02:00
//#include <ColorizeManager.h>
2013-09-19 22:23:31 +02:00
#include <ewol/clipBoard.h>
#include <SearchData.h>
#include <ewol/widget/WidgetManager.h>
#include <ewol/renderer/EObject.h>
#include <appl/TextPluginManager.h>
2013-09-19 22:23:31 +02:00
#undef __class__
2013-10-09 22:00:24 +02:00
#define __class__ "TextViewer"
2013-09-19 22:23:31 +02:00
appl::TextViewer::TextViewer(const etk::UString& _fontName, int32_t _fontSize) :
2013-10-09 22:00:24 +02:00
m_buffer(NULL),
m_displayText(_fontName, _fontSize),
m_insertMode(false) {
2013-10-07 22:04:21 +02:00
setCanHaveFocus(true);
2013-10-09 22:00:24 +02:00
registerMultiCast(ednMsgBufferId);
registerMultiCast(ednMsgGuiRm);
registerMultiCast(ednMsgGuiSelect);
registerMultiCast(ednMsgGuiChangeCharset);
registerMultiCast(ednMsgGuiFind);
registerMultiCast(ednMsgGuiReplace);
registerMultiCast(ednMsgGuiGotoLine);
2013-10-29 21:13:45 +01:00
registerMultiCast(appl::MsgSelectNewFile);
2013-10-07 22:04:21 +02:00
setLimitScrolling(0.2);
2013-09-19 22:23:31 +02:00
2013-10-09 22:00:24 +02:00
shortCutAdd("ctrl+w", ednMsgGuiRm, "Line");
shortCutAdd("ctrl+shift+w", ednMsgGuiRm, "Paragraph");
shortCutAdd("ctrl+a", ednMsgGuiSelect, "ALL");
shortCutAdd("ctrl+shift+a", ednMsgGuiSelect, "NONE");
2013-09-19 22:23:31 +02:00
2013-10-29 21:13:45 +01:00
// load buffer manager:
m_bufferManager = appl::BufferManager::keep();
// load color properties
m_paintingProperties = appl::GlyphPainting::keep("THEME:COLOR:textViewer.json");
// get all id properties ...
m_colorBackground = m_paintingProperties->request("CODE_basicBackgroung");
m_colorSpace = m_paintingProperties->request("CODE_space");
m_colorTabulation = m_paintingProperties->request("CODE_tabulation");
m_colorCursor = m_paintingProperties->request("CODE_cursor");
m_colorLineNumber = m_paintingProperties->request("CODE_lineNumber");
m_colorSelection = m_paintingProperties->request("SelectedText");
m_colorNormal = m_paintingProperties->request("normal");
2013-09-19 22:23:31 +02:00
// by default we load an example object:
/*
2013-09-19 22:23:31 +02:00
m_buffer = new appl::Buffer();
if (m_buffer == NULL) {
APPL_ERROR("can not create buffer ... ");
return;
}
2013-10-07 22:04:21 +02:00
m_buffer->loadFile("./example.txt");
*/
appl::textPluginManager::connect(*this);
2013-11-07 21:08:57 +01:00
// last created has focus ...
setCurrentSelect();
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
appl::TextViewer::~TextViewer(void) {
appl::textPluginManager::disconnect(*this);
2013-10-29 21:13:45 +01:00
if (m_paintingProperties != NULL) {
appl::GlyphPainting::release(m_paintingProperties);
}
if (m_bufferManager != NULL) {
appl::BufferManager::release(m_bufferManager);
}
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
bool appl::TextViewer::calculateMinSize(void) {
2013-09-19 22:23:31 +02:00
m_minSize.setValue(50,50);
return true;
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::onDraw(void) {
2013-10-07 22:04:21 +02:00
m_displayDrawing.draw();
m_displayText.draw();
WidgetScrooled::onDraw();
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::onRegenerateDisplay(void) {
2013-10-07 22:04:21 +02:00
if (false == needRedraw()) {
2013-09-26 22:15:39 +02:00
return;
}
// For the scrooling windows
2013-10-07 22:04:21 +02:00
m_displayDrawing.clear();
m_displayText.clear();
2013-09-26 22:15:39 +02:00
2013-10-07 22:04:21 +02:00
// reset the background :
m_displayDrawing.setPos(vec3(0, 0, 0));
m_displayDrawing.setColor((*m_paintingProperties)[m_colorBackground].getForeground());
2013-10-07 22:04:21 +02:00
m_displayDrawing.rectangleWidth(m_size);
2013-09-26 22:15:39 +02:00
if (m_buffer == NULL) {
m_maxSize.setX(256);
m_maxSize.setY(256);
2013-10-07 22:04:21 +02:00
m_displayText.setTextAlignement(10, m_size.x()-20, ewol::Text::alignLeft);
m_displayText.setRelPos(vec3(10, 0, 0));
2013-09-26 22:15:39 +02:00
etk::UString tmpString("<br/>\n"
"<font color=\"red\">\n"
" <b>\n"
" edn - Editeur De N'ours\n"
" </b>\n"
"</font>\n"
"<br/>\n"
"<br/>\n"
"<font color=\"indigo\">\n"
" <i>\n"
" No Buffer Availlable to display\n"
" </i>\n"
"</font>\n");
2013-10-07 22:04:21 +02:00
m_displayText.setPos(vec3(0.0f, m_size.y(), 0.0f) );
m_displayText.forceLineReturn();
m_displayText.printDecorated(tmpString);
2013-09-26 22:15:39 +02:00
// call the herited class...
2013-10-07 22:04:21 +02:00
WidgetScrooled::onRegenerateDisplay();
2013-09-26 22:15:39 +02:00
return;
}
// normal displa of the buffer :
vec3 tmpCursorPosition(0, 0, -1);
// real display ...
2013-10-07 22:04:21 +02:00
etk::Buffer& buf = m_buffer->getData();
m_displayText.setColor(etk::Color<>(0, 0, 0, 256));
2013-09-26 22:15:39 +02:00
float countNbLine = 1;
esize_t countColomn = 0;
// the siplay string :
etk::UString stringToDisplay;
esize_t bufferElementSize = 0;
bool isSelect = false;
appl::Buffer::Iterator selectPosStart = m_buffer->begin();
appl::Buffer::Iterator selectPosStop = m_buffer->begin();
if (m_buffer->hasTextSelected() == true) {
selectPosStart = m_buffer->selectStart();
selectPosStop = m_buffer->selectStop();
}
m_displayText.setPos(vec3(-m_originScrooled.x(), m_size.y()+m_originScrooled.y(), 0));
m_displayText.forceLineReturn();
appl::Buffer::Iterator startingIt = m_buffer->begin();
int32_t startLineId = 0;
if (m_size.y() < m_displayText.getPos().y()) {
for (startingIt = m_buffer->begin();
(bool)startingIt == true;
++startingIt) {
if (*startingIt == etk::UChar::Return) {
++startLineId;
m_displayText.forceLineReturn();
if (m_size.y() >= m_displayText.getPos().y()) {
++startingIt;
break;
}
}
}
}
// Display line number :
m_lastOffsetDisplay = 0;
2013-10-22 21:34:13 +02:00
vec3 tmpLetterSize = m_displayText.calculateSize((etk::UChar)'A');
{
esize_t nbLine = m_buffer->getNumberOfLines();
float nbLineCalc = nbLine;
int32_t nbChar = 0;
while (nbLineCalc >= 1.0f) {
++nbChar;
nbLineCalc /= 10.0f;
}
m_lastOffsetDisplay = tmpLetterSize.x() * (float)nbChar + 1.0f;
m_displayText.setFontItalic((*m_paintingProperties)[m_colorLineNumber].getItalic());
m_displayText.setFontBold((*m_paintingProperties)[m_colorLineNumber].getBold());
m_displayText.setColorBg((*m_paintingProperties)[m_colorLineNumber].getBackground());
m_displayText.setColor((*m_paintingProperties)[m_colorLineNumber].getForeground());
m_displayText.setClippingMode(false);
vec3 startWriteRealPosition = m_displayText.getPos();
m_displayText.setPos(vec3(0.0f, startWriteRealPosition.y(), 0.0f));
for (int32_t iii=startLineId;
iii<nbLine;
++iii) {
char tmpLineNumber[50];
sprintf(tmpLineNumber, "%*d", nbChar, iii);
m_displayText.print(tmpLineNumber);
m_displayText.forceLineReturn();
if (m_displayText.getPos().y() < -20.0f ) {
break;
}
}
m_displayText.setPos(vec3(-m_originScrooled.x()+m_lastOffsetDisplay, startWriteRealPosition.y(), 0.0f));
m_displayText.setClipping(vec2(m_lastOffsetDisplay, 0), m_size);
}
appl::DisplayHLData displayLocalSyntax;
m_buffer->hightlightGenerateLines(displayLocalSyntax, (esize_t)startingIt, m_size.y());
float maxSizeX = 0;
appl::HighlightInfo * HLColor = NULL;
for (appl::Buffer::Iterator it = startingIt;
(bool)it == true;
++it) {
if (it == m_buffer->cursor()) {
2013-09-26 22:15:39 +02:00
// need to display the cursor :
tmpCursorPosition = m_displayText.getPos();
2013-09-26 22:15:39 +02:00
}
//APPL_DEBUG("display element '" << currentValue << "'at pos : " << m_displayText.getPos() );
2013-09-26 22:15:39 +02:00
//APPL_DEBUG(" element size : " << iii << " : " << bufferElementSize);
if (*it == etk::UChar::Return) {
2013-09-26 22:15:39 +02:00
countNbLine += 1;
countColomn = 0;
maxSizeX = etk_max(m_displayText.getPos().x(), maxSizeX);
// Display the end line position only if we have the focus ...
if (getFocus() == true) {
if (it >= selectPosStart && it < selectPosStop) {
ewol::Drawing& draw = m_displayText.getDrawing();
draw.setColor(etk::Color<>(0xFF0000FF));
draw.setPos(m_displayText.getPos() + tmpLetterSize/4.0f);
draw.rectangle(m_displayText.getPos() + tmpLetterSize*3.0f/4.0f);
}
2013-10-22 21:34:13 +02:00
}
m_displayText.forceLineReturn();
m_displayText.setPos(vec3(-m_originScrooled.x()+m_lastOffsetDisplay, m_displayText.getPos().y(), 0.0f));
if (m_displayText.getPos().y() < -20.0f ) {
break;
}
2013-09-26 22:15:39 +02:00
continue;
2013-09-19 22:23:31 +02:00
}
HLColor = m_buffer->getElementColorAtPosition(displayLocalSyntax, (esize_t)it);
bool haveBackground = false;
if ( HLColor != NULL
&& HLColor->patern != NULL) {
m_displayText.setColor(HLColor->patern->getColorGlyph().getForeground());
m_displayText.setColorBg(HLColor->patern->getColorGlyph().getBackground());
haveBackground = HLColor->patern->getColorGlyph().haveBackground();
m_displayText.setFontItalic(HLColor->patern->getColorGlyph().getItalic());
m_displayText.setFontBold(HLColor->patern->getColorGlyph().getBold());
} else {
m_displayText.setFontItalic((*m_paintingProperties)[m_colorNormal].getItalic());
m_displayText.setFontBold((*m_paintingProperties)[m_colorNormal].getBold());
m_displayText.setColorBg((*m_paintingProperties)[m_colorNormal].getBackground());
m_displayText.setColor((*m_paintingProperties)[m_colorNormal].getForeground());
}
if (haveBackground == false) {
if (*it == etk::UChar::Space) {
m_displayText.setColorBg((*m_paintingProperties)[m_colorSpace].getForeground());
} else if (*it == etk::UChar::Tabulation) {
m_displayText.setColorBg((*m_paintingProperties)[m_colorTabulation].getForeground());
}
2013-10-22 21:34:13 +02:00
}
m_buffer->expand(countColomn, *it, stringToDisplay);
// Display selection only if we have the focus ...
if (getFocus() == true) {
if (it >= selectPosStart && it < selectPosStop) {
m_displayText.setColor((*m_paintingProperties)[m_colorSelection].getForeground());
m_displayText.setColorBg((*m_paintingProperties)[m_colorSelection].getBackground());
}
}
2013-10-07 22:04:21 +02:00
//APPL_DEBUG("display : '" << currentValue << "' == > '" << stringToDisplay << "'");
m_displayText.print(stringToDisplay);
2013-10-07 22:04:21 +02:00
countColomn += stringToDisplay.size();
2013-09-19 22:23:31 +02:00
}
maxSizeX = etk_max(m_displayText.getPos().x(), maxSizeX);
// Display cursor only if we have the focus ...
if ( tmpCursorPosition.z() != -1
&& getFocus() == true) {
2013-09-26 22:15:39 +02:00
// display the cursor:
//APPL_DEBUG("display cursor at position : " << tmpCursorPosition);
2013-10-07 22:04:21 +02:00
m_displayText.setPos(tmpCursorPosition);
m_displayText.setColorBg((*m_paintingProperties)[m_colorCursor].getForeground());
2013-10-07 22:04:21 +02:00
m_displayText.printCursor(m_insertMode);
2013-09-26 22:15:39 +02:00
}
// set maximum size (X&Y) :
{
vec3 tmpLetterSize = m_displayText.calculateSize((etk::UChar)'A');
esize_t nbLines = m_buffer->getNumberOfLines();
m_maxSize.setX(maxSizeX+m_originScrooled.x());
m_maxSize.setY((float)nbLines*tmpLetterSize.y());
}
2013-09-26 22:15:39 +02:00
// call the herited class...
2013-10-07 22:04:21 +02:00
WidgetScrooled::onRegenerateDisplay();
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
bool appl::TextViewer::onEventEntry(const ewol::EventEntry& _event) {
2013-09-26 22:15:39 +02:00
if (m_buffer == NULL) {
return false;
2013-09-19 22:23:31 +02:00
}
// First call plugin
if (appl::textPluginManager::onEventEntry(*this, _event) == true) {
markToRedraw();
return true;
}
2013-10-07 22:04:21 +02:00
// 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 if (localValue == etk::UChar::Suppress ) {
//APPL_INFO("keyEvent : <suppr> pos=" << m_cursorPos);
if (m_buffer->hasTextSelected()) {
2013-10-22 21:34:13 +02:00
remove();
} 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()) {
2013-10-22 21:34:13 +02:00
remove();
} else {
appl::Buffer::Iterator pos = m_buffer->cursor();
appl::Buffer::Iterator posEnd = pos;
--pos;
replace("", pos, posEnd);
}
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);
}
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;
}
2013-09-26 22:15:39 +02:00
return true;
}
return false;
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
bool appl::TextViewer::onEventInput(const ewol::EventInput& _event) {
2013-11-07 21:08:57 +01:00
if (_event.getId() != 0) {
keepFocus();
}
2013-10-16 21:55:45 +02:00
if (m_buffer == NULL) {
return false;
2013-09-19 22:23:31 +02:00
}
// First call the scrolling widget :
if (WidgetScrooled::onEventInput(_event) == true) {
markToRedraw();
return true;
}
// Second call plugin
if (appl::textPluginManager::onEventInput(*this, _event) == true) {
markToRedraw();
return true;
}
2013-10-16 21:55:45 +02:00
vec2 relativePos = relativePosition(_event.getPos());
// offset for the lineNumber:
relativePos -= vec2(m_lastOffsetDisplay, 0);
// offset for the scrolling:
relativePos += vec2(m_originScrooled.x(), -m_originScrooled.y());
2013-10-16 21:55:45 +02:00
// invert for the buffer event ...
relativePos.setY(m_size.y()-relativePos.y());
if (relativePos.x()<0) {
relativePos.setX(0);
}
2013-10-16 21:55:45 +02:00
// 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;
}
2013-10-16 21:55:45 +02:00
}
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();
(bool)it == true;
++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();
2013-09-19 22:23:31 +02:00
}
2013-11-11 20:20:25 +01:00
void appl::TextViewer::onEventClipboard(enum ewol::clipBoard::clipboardListe _clipboardID) {
2013-09-26 22:15:39 +02:00
if (m_buffer != NULL) {
etk::UString data = ewol::clipBoard::get(_clipboardID);
write(data);
2013-09-26 22:15:39 +02:00
}
2013-10-07 22:04:21 +02:00
markToRedraw();
2013-09-26 22:15:39 +02:00
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::onReceiveMessage(const ewol::EMessage& _msg) {
widget::WidgetScrooled::onReceiveMessage(_msg);
2013-10-29 21:13:45 +01:00
//APPL_DEBUG("receive msg: " << _msg);
// First call plugin
if (appl::textPluginManager::onReceiveMessage(*this, _msg) == true) {
markToRedraw();
return;
}
2013-11-07 21:08:57 +01:00
// event needed even if selection of buffer is not done ...
if (_msg.getMessage() == appl::Buffer::eventIsModify) {
markToRedraw();
return;
}
if (_msg.getMessage() == appl::Buffer::eventSelectChange) {
markToRedraw();
return;
}
// If not the last buffer selected, then no event parsing ...
if (isSelectedLast() == false) {
return;
}
2013-10-29 21:13:45 +01:00
if (_msg.getMessage() == appl::MsgSelectNewFile) {
if (m_buffer != NULL) {
m_buffer->unRegisterOnEvent(this);
}
2013-10-29 21:13:45 +01:00
m_buffer = m_bufferManager->get(_msg.getData());
if (m_buffer != NULL) {
m_buffer->registerOnEvent(this, appl::Buffer::eventIsModify);
m_buffer->registerOnEvent(this, appl::Buffer::eventSelectChange);
}
2013-11-07 21:08:57 +01:00
if (m_bufferManager != NULL) {
m_bufferManager->setBufferSelected(m_buffer);
}
markToRedraw();
return;
2013-10-29 21:13:45 +01:00
}
2013-09-19 22:23:31 +02:00
}
2013-10-29 21:13:45 +01:00
void appl::TextViewer::onObjectRemove(ewol::EObject* _removeObject) {
widget::WidgetScrooled::onObjectRemove(_removeObject);
2013-10-29 21:13:45 +01:00
if (m_buffer == _removeObject) {
m_buffer = NULL;
markToRedraw();
}
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::onGetFocus(void) {
showKeyboard();
2013-09-19 22:23:31 +02:00
APPL_INFO("Focus - In");
2013-11-07 21:08:57 +01:00
setCurrentSelect();
markToRedraw();
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::onLostFocus(void) {
hideKeyboard();
2013-09-19 22:23:31 +02:00
APPL_INFO("Focus - out");
2013-11-07 21:08:57 +01:00
markToRedraw();
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::setFontSize(int32_t _size) {
2013-10-07 22:04:21 +02:00
m_displayText.setFontSize(_size);
setScrollingSize(_size*3.0*1.46); // 1.46 is a magic number ...
2013-09-19 22:23:31 +02:00
}
2013-10-09 22:00:24 +02:00
void appl::TextViewer::setFontName(const etk::UString& _fontName) {
2013-10-07 22:04:21 +02:00
m_displayText.setFontName(_fontName);
2013-09-19 22:23:31 +02:00
}
bool appl::TextViewer::moveCursor(const appl::Buffer::Iterator& _pos) {
if (m_buffer == NULL) {
return false;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
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;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
if (appl::textPluginManager::onWrite(*this, _pos, _data) == true) {
2013-10-22 21:34:13 +02:00
// no call of the move cursor, because pluging might call theses function to copy and cut data...
return true;
}
2013-10-22 21:34:13 +02:00
bool 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;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
if (appl::textPluginManager::onReplace(*this, _pos, _data, _posEnd) == true) {
2013-10-22 21:34:13 +02:00
// no call of the move cursor, because pluging might call theses function to copy and cut data...
return true;
}
2013-10-22 21:34:13 +02:00
bool 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;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
if (appl::textPluginManager::onRemove(*this, m_buffer->selectStart(), m_buffer->selectStop()) == true) {
return;
}
2013-10-22 21:34:13 +02:00
m_buffer->removeSelection();
appl::textPluginManager::onCursorMove(*this, m_buffer->cursor());
}
void appl::TextViewer::moveCursorRight(appl::TextViewer::moveMode _mode) {
if (m_buffer == NULL) {
return;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
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;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
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;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
// 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("move_up : " << 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;
}
2013-10-22 21:34:13 +02:00
markToRedraw();
// 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("move down : " << 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;
(bool)it == true;
++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;
(bool)it == true && 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;
}
2013-11-07 21:08:57 +01:00
appl::TextViewer* appl::TextViewer::m_currentBufferSelect = NULL;
void appl::TextViewer::setCurrentSelect(void) {
if (this == m_currentBufferSelect) {
return;
}
m_currentBufferSelect = this;
if (m_bufferManager != NULL) {
m_bufferManager->setBufferSelected(m_buffer);
}
}
bool appl::TextViewer::isSelectedLast(void) {
if (this == m_currentBufferSelect) {
return true;
}
return false;
}