[DEV] add scrolling and multiline indent module

This commit is contained in:
2013-10-21 21:47:28 +02:00
parent 4704eca027
commit e6480b8cac
9 changed files with 399 additions and 82 deletions

View File

@@ -82,7 +82,8 @@ appl::Buffer::Iterator appl::Buffer::selectStop(void) {
appl::Buffer::Buffer(void) :
m_cursorPos(0),
m_cursorSelectPos(-1),
m_cursorPreferredCol(-1) {
m_cursorPreferredCol(-1),
m_nbLines(0) {
}
@@ -93,7 +94,9 @@ bool appl::Buffer::loadFile(const etk::UString& _name) {
if (file.exist() == false) {
return false;
}
m_nbLines = 0;
if (true == m_data.dumpFrom(file) ) {
countNumberofLine();
return true;
}
return false;
@@ -104,6 +107,21 @@ void appl::Buffer::setFileName(const etk::UString& _name) {
}
void appl::Buffer::countNumberofLine(void) {
m_nbLines = 0;
for (Iterator it = begin();
it != end();
++it) {
if (*it == etk::UChar::Return) {
++m_nbLines;
}
}
if (*end() == etk::UChar::Return) {
++m_nbLines;
}
}
appl::Buffer::Iterator appl::Buffer::getStartLine(const appl::Buffer::Iterator& _pos) {
appl::Buffer::Iterator startPos;
if (false == searchBack(_pos, etk::UChar::Return, startPos)) {
@@ -124,7 +142,7 @@ appl::Buffer::Iterator appl::Buffer::getEndLine(const appl::Buffer::Iterator& _p
bool appl::Buffer::search(const appl::Buffer::Iterator& _pos, const etk::UChar& _search, appl::Buffer::Iterator& _result) {
// move in the string
etk::UChar value;
for (Iterator it = position(m_cursorPos);
for (Iterator it = _pos;
it != end();
++it) {
if (*it == _search) {
@@ -139,7 +157,7 @@ bool appl::Buffer::search(const appl::Buffer::Iterator& _pos, const etk::UChar&
bool appl::Buffer::searchBack(const appl::Buffer::Iterator& _pos, const etk::UChar& _search, appl::Buffer::Iterator& _result) {
// move in the string
etk::UChar value;
for (Iterator it = --position(m_cursorPos);
for (Iterator it = _pos - 1;
it != begin();
--it) {
//APPL_DEBUG("compare : " << *it << " ?= " << _search);
@@ -376,11 +394,24 @@ bool appl::Buffer::copy(etk::UString& _data) {
return false;
}
void appl::Buffer::copy(etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd) {
_data.clear();
esize_t startPos = getStartSelectionPos();
esize_t endPos = getStopSelectionPos();
for (Iterator it = _pos;
it != _posEnd &&
it != end();
++it) {
_data += *it;
}
}
bool appl::Buffer::write(const etk::UString& _data, const appl::Buffer::Iterator& _pos) {
etk::Char output = _data.c_str();
m_data.insert(_pos, (int8_t*)((void*)output), output.size());
m_selectMode = false;
moveCursor((esize_t)_pos+output.size());
countNumberofLine(); // TODO : use more intelligent counter
return true;
}
@@ -389,6 +420,7 @@ bool appl::Buffer::replace(const etk::UString& _data, const appl::Buffer::Iterat
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());
countNumberofLine(); // TODO : use more intelligent counter
return true;
}
@@ -399,6 +431,7 @@ void appl::Buffer::removeSelection(void) {
m_data.remove(startPos, endPos-startPos);
m_selectMode = false;
moveCursor(startPos);
countNumberofLine(); // TODO : use more intelligent counter
}
}

View File

@@ -131,6 +131,58 @@ namespace appl {
}
return false;
}
/**
* @brief <= iterator
* @return true if the iterator is identical pos
*/
bool operator<= (const Iterator& _obj) const {
if (m_data != _obj.m_data) {
return false;
}
if (m_current <= _obj.m_current) {
return true;
}
return false;
}
/**
* @brief >= iterator
* @return true if the iterator is identical pos
*/
bool operator>= (const Iterator& _obj) const {
if (m_data != _obj.m_data) {
return false;
}
if (m_current >= _obj.m_current) {
return true;
}
return false;
}
/**
* @brief < iterator
* @return true if the iterator is identical pos
*/
bool operator< (const Iterator& _obj) const {
if (m_data != _obj.m_data) {
return false;
}
if (m_current < _obj.m_current) {
return true;
}
return false;
}
/**
* @brief > iterator
* @return true if the iterator is identical pos
*/
bool operator> (const Iterator& _obj) const {
if (m_data != _obj.m_data) {
return false;
}
if (m_current > _obj.m_current) {
return true;
}
return false;
}
/**
* @brief Get the value on the current element
* @return The request element value
@@ -193,34 +245,26 @@ namespace appl {
etk::Buffer& getData(void) {
return m_data;
};
public:
protected:
esize_t m_cursorPos; //!< cursor position.
public:
void moveCursor(esize_t _pos);
protected:
int32_t m_cursorSelectPos; //!< cursor position.
public:
/**
* @brief Set the selection position in the buffer.
* @param[in] _pos Position of the selection.
*/
void setSelectionPos(const Iterator& _pos);
/**
* @brief Un select request.
*/
void unSelect(void);
protected:
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
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.
bool onEventEntry(const ewol::EventEntry& _event, ewol::Text& _textDrawer);
//bool onEventInput(const ewol::EventInput& _event, ewol::Text& _textDrawer, const vec2& _relativePos);
void moveCursor(esize_t _pos);
/**
* @brief Remove the selection of the buffer. (do nothing if no secection)
*/
void removeSelection(void);
/**
* @brief Get the status of selection.
* @return true if we have a curent selection, false otherwise.
@@ -242,6 +286,48 @@ namespace appl {
esize_t getStopSelectionPos(void) {
return etk_max(m_cursorPos, m_cursorSelectPos);
}
protected:
float m_cursorPreferredCol; //!< position of the cursor when up and down is done.
public:
/**
* @brief Set the favorite up and down position (distance from the left of the screen.
* @param[in] _val New distance (in pixels).
*/
void setFavoriteUpDownPos(float _val) {
m_cursorPreferredCol = _val;
}
/**
* @brief Get the favorite distance from the left screen (For up and down moving).
* @return The distance in pixels.
*/
float getFavoriteUpDownPos(void) {
return m_cursorPreferredCol;
}
protected:
bool m_selectMode; //!< when true, the select mode keep the moving selecting
public:
/**
* @brief Set the selection mode (if true, the move event creata a selection)
* @param[in] _status New status of the section.
*/
void setSelectMode(bool _status) {
m_selectMode = _status;
}
/**
* @brief Get the selection mode (if true, the move event creata a selection)
* @return The selecting mode.
*/
bool getSelectMode(void) {
return m_selectMode;
}
public:
/**
* @brief Get the position of selection around (select word).
* @param[in] _startPos Position to start the selection.
* @param[out] _beginPos Position where the element start.
* @param[out] _endPos Position where the element stop.
* @return true if we find a selection around.
*/
bool getPosAround(const Iterator& _startPos, Iterator &_beginPos, Iterator &_endPos);
/**
* @brief Expand the specify char to have a user frendly display for special char and tabs
@@ -250,7 +336,6 @@ namespace appl {
* @param[out] _out String that represent the curent value to display
*/
void expand(esize_t& _indent, const etk::UChar& _value, etk::UString& _out) const;
public:
/**
* @brief get the start of a line with the position in the buffer.
* @param[in] _pos position in the buffer.
@@ -281,15 +366,15 @@ namespace appl {
bool searchBack(const Iterator& _pos, const etk::UChar& _search, Iterator& _result);
/**
* @brief find the first character of the line "nLines" forward
* @param[in,out] _startPos Start position.
* @param[in,out] _nLines Number of line to count.
* @param[in] _startPos Start position.
* @param[in] _nLines Number of line to count.
* @return position of the starting the line.
*/
Iterator countForwardNLines(const Iterator& _startPos, int32_t _nLines);
/**
* @brief find the first character of the line "nLines" backwards
* @param[in,out] _startPos Start position to count (this caracter is not counted)
* @param[in,out] _nLines Number of line to count (if == 0 means find the beginning of the line)
* @param[in] _startPos Start position to count (this caracter is not counted)
* @param[in] _nLines Number of line to count (if == 0 means find the beginning of the line)
* @return position of the starting the line
*/
Iterator countBackwardNLines(const Iterator& _startPos, int32_t _nLines);
@@ -301,12 +386,26 @@ namespace appl {
*/
bool copy(etk::UString& _data);
/**
* @brief Remove the selection of the buffer. (do nothing if no secection)
* @brief copy data in the _data ref value.
* @param[out] _data Output stream to copy.
* @param[in] _pos Position to add the data.
* @param[in] _posEnd End position to end replace the data.
*/
void copy(etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd);
/**
* @brief Write data at a specific position
* @param[in] _data Data to insert in the buffer
* @param[in] _pos Position to add the data.
* @return true if the write is done corectly
*/
void removeSelection(void);
bool write(const etk::UString& _data, const appl::Buffer::Iterator& _pos);
/**
* @brief Write data at a specific position
* @param[in] _data Data to insert in the buffer
* @param[in] _pos Position to add the data.
* @param[in] _posEnd End position to end replace the data.
* @return true if the write is done corectly
*/
bool replace(const etk::UString& _data, const appl::Buffer::Iterator& _pos, const appl::Buffer::Iterator& _posEnd);
public: // iterator section :
/**
@@ -340,6 +439,21 @@ namespace appl {
* @return The Iterator
*/
Iterator selectStop(void);
protected:
esize_t m_nbLines; //!< number of line in the buffer
public:
/**
* @brief Get the number of line in the buffer.
* @return number of line in the Buffer.
*/
esize_t getNumberOfLines(void) {
return m_nbLines;
}
protected:
/**
* @brief Count the number of line in the buffer
*/
void countNumberofLine(void);
};
};

View File

@@ -9,6 +9,7 @@
#include <appl/Buffer/TextPluginManager.h>
#include <appl/Debug.h>
#include <appl/Buffer/TextPluginCopy.h>
#include <appl/Buffer/TextPluginMultiLineTab.h>
static etk::Vector<appl::TextViewerPlugin *>& getList(void) {
static etk::Vector<appl::TextViewerPlugin *> s_list;
@@ -69,6 +70,7 @@ void appl::textPluginManager::unInit(void) {
void appl::textPluginManager::addDefaultPlugin(void) {
appl::textPluginManager::addPlugin(new appl::TextPluginCopy());
appl::textPluginManager::addPlugin(new appl::TextPluginMultiLineTab());
}
void appl::textPluginManager::addPlugin(appl::TextViewerPlugin* _plugin) {

View File

@@ -1,22 +1,90 @@
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();
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#include <appl/Buffer/TextPluginMultiLineTab.h>
#include <ewol/clipBoard.h>
#include <appl/Gui/TextViewer.h>
appl::TextPluginMultiLineTab::TextPluginMultiLineTab(void) {
m_activateOnEventEntry = true;
}
bool appl::TextPluginMultiLineTab::onEventEntry(appl::TextViewer& _textDrawer,
const ewol::EventEntry& _event) {
if (_event.getType() != ewol::keyEvent::keyboardChar) {
return false;
}
//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) {
return false;
}
if (_textDrawer.m_buffer->hasTextSelected() == false) {
return false;
}
appl::Buffer::Iterator itStart = _textDrawer.m_buffer->selectStart();
appl::Buffer::Iterator itStop = _textDrawer.m_buffer->selectStop();
// get the compleate section of the buffer :
itStart = _textDrawer.m_buffer->getStartLine(itStart);
itStop = _textDrawer.m_buffer->getEndLine(itStop);
// copy the curent data in a classicle string:
etk::UString data;
_textDrawer.m_buffer->copy(data, itStart, itStop);
// TODO : Change this ...
bool m_useTabs = true;
int32_t m_tabDist = 4;
if (true == _event.getSpecialKey().isSetShift() ) {
// un-indent
data.add(0, etk::UChar::Return);
for (esize_t iii=1; iii<data.size(); ++iii) {
if (data[iii-1] == etk::UChar::Return) {
if(data[iii] == etk::UChar::Tabulation) {
data.remove(iii);
} else if(data[iii] == etk::UChar::Space) {
for (esize_t jjj=0; jjj<m_tabDist && jjj+iii<data.size() ; jjj++) {
if(data[iii] == etk::UChar::Space) {
data.remove(iii);
} else if(data[iii] == etk::UChar::Tabulation) {
data.remove(iii);
break;
} else {
break;
}
}
}
*/
markToRedraw();
return true;
}
}
}
data.remove(0);
} else {
// indent
data.add(0, etk::UChar::Return);
for (esize_t iii=1; iii<data.size(); iii++) {
if (data[iii-1] == etk::UChar::Return) {
if (true == m_useTabs) {
data.add(iii, etk::UChar::Tabulation);
} else {
for (int32_t jjj=0; jjj<m_tabDist; jjj++) {
data.add(iii, etk::UChar::Space);
}
}
}
}
data.remove(0);
}
// Real replace of DATA :
_textDrawer.replace(data, itStart, itStop);
//_textDrawer.moveCursor(itStart);
_textDrawer.m_buffer->setSelectionPos(itStart+1);
return true;
}

View File

@@ -0,0 +1,32 @@
/**
* @author Edouard DUPIN
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
#ifndef __APPL_TEXT_PLUGIN_MULTI_LINE_TAB_H__
#define __APPL_TEXT_PLUGIN_MULTI_LINE_TAB_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 TextPluginMultiLineTab : public appl::TextViewerPlugin {
public:
TextPluginMultiLineTab(void);
~TextPluginMultiLineTab(void) {
// nothing to do ...
};
public:
virtual bool onEventEntry(appl::TextViewer& _textDrawer,
const ewol::EventEntry& _event);
};
};
#endif