#include <QPaintEvent>
QStringList ReEdit::m_tabStrings;
-// left arrow:
-QChar ReEdit::m_tabChar = QChar(2192);
+// RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+QChar ReEdit::m_tabChar = QChar(0xBB);
int ReEdit::m_tabWidth = 3;
/**
*/
ReEdit::ReEdit(QWidget* parent) :
QWidget(parent),
+ ReMouseCatcher(),
m_paragraphs(),
m_firstLine(0),
m_firstCol(0),
m_insertMode(true),
m_breakLines(false),
m_widthLineNo(50),
- m_widthVScrollBar(20),
- m_heightHScrollBar(20),
+ m_widthVScrollBar(10),
+ m_heightHScrollBar(10),
m_lines(NULL),
m_looks(),
m_standardBrush(new QBrush(Qt::SolidPattern)),
m_sliderBrush->setColor(Qt::lightGray);
memset(m_looks, 0, sizeof m_looks);
memset(m_brushColors, 0, sizeof m_brushColors);
+
+ assignColorsStandard();
+
+ setTabStrings(3);
+ m_paragraphs.appendBuilder(new ReParagraphBuilder());
+ m_paragraphs.appendBuilder(new ReCursortLineBuilder());
+ assignKeysStandard();
+}
+void ReEdit::assignColorsStandard(){
m_fontColors[ReLook::FG_STANDARD] = new QColor(Qt::black);
m_fontColors[ReLook::FG_CURRENT_LINE] = new QColor(Qt::blue);
m_fontColors[ReLook::FG_SELECTED] = new QColor(Qt::blue);
m_brushColors[ReLook::BG_CURRENT_LINE] = new QColor(Qt::lightGray);
m_brushColors[ReLook::BG_SELECTED] = new QColor(Qt::blue);
m_brushColors[ReLook::BG_CURRENT_SELECTED] = new QColor(Qt::blue);
+ m_brushColors[ReLook::BG_SCROLLBAR] = new QColor(216, 214, 212);
+ m_brushColors[ReLook::BG_SLIDER] = new QColor(231, 230, 228);
m_brushColors[ReLook::BG_SEARCHED] = new QColor(Qt::yellow);
m_brushColors[ReLook::BG_SAME_WORD] = new QColor(Qt::yellow);
m_brushColors[ReLook::BG_YELLOW] = new QColor(Qt::yellow);
m_brushColors[ReLook::BG_RED] = new QColor(Qt::red);
m_brushColors[ReLook::BG_GREEN] = new QColor(Qt::green);
m_brushColors[ReLook::BG_BLUE] = new QColor(Qt::blue);
+}
+
+void ReEdit::assignKeysStandard(){
+ m_keyRaw.clear();
+ m_keyControl.clear();
+ m_keyShift.clear();
+ m_keyAlt.clear();
+ m_keyAltControl.clear();
+ m_keyAltControlShift.clear();
+ m_keyControlShift.clear();
- m_paragraphs.appendBuilder(new ReParagraphBuilder());
- m_paragraphs.appendBuilder(new ReCursortLineBuilder());
m_keyRaw[Qt::Key_Left] = EA_CHAR_LEFT;
m_keyRaw[Qt::Key_Right] = EA_CHAR_RIGHT;
m_keyRaw[Qt::Key_Up] = EA_LINE_UP;
m_keyControl[Qt::Key_Delete] = EA_DEL_END_OF_LINE;
m_keyShift[Qt::Key_Delete] = EA_DEL_BEGIN_OF_LINE;
m_keyAlt[Qt::Key_Delete] = EA_DEL_LINE;
- setTabStrings(3);
+
}
/**
ReLook* rc = m_looks[index];
if (rc == NULL){
rc = m_looks[index] = new ReLook();
+ rc->m_edit = this;
rc->m_foreground = foreground;
rc->m_background = background;
rc->m_brush = createBrush(background);
* @param event the trigger event
*/
void ReEdit::paintEvent(QPaintEvent* event){
+ clock_t start = clock();
QRect rect = event->rect();
m_widthEdit = rect.width();
m_heightEdit = rect.height();
int pageSize = (rect.height() - m_heightHScrollBar) / lineHeight;
int firstLine = m_paragraphs.firstLine();
m_paragraphs.load(firstLine, pageSize, this);
-
QPainter painter(this);
ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
painter.setBrush(*look->m_brush);
int width = (rect.width() - m_widthLineNo - m_widthVScrollBar)
/ m_standardMetrics->width('x');
int maxLines = max(1, m_lines->lineCount() - pageSize);
- drawScrollbars(painter, rect, pageSize * 100 / maxLines,
- m_paragraphs.firstLine() * 100 / maxLines, width * 100 / maxWidth, 0);
+ drawScrollbars(painter, rect, double(pageSize) / maxLines,
+ double(m_paragraphs.firstLine()) / maxLines, double(width) / maxWidth,
+ 0.0);
+ ReLogger::globalLogger()->logv(LOG_INFO, 3, "draw: %.4f",
+ double(clock() - start) / CLOCKS_PER_SEC);
}
-void calcSliderSize(int size, int minSize, int sizePercent, int posPercent,
+/**
+ * Calculates the size/position of a slider from a relative value [0..1].
+ * @param size the size of the scrollbar (width/height for horiz/vert bar)
+ * @param minSize the minimum size of the slider
+ * @param sizeFactor the factor of the slider size: [0..1]
+ * @param posFactor the factor of the slider position [0..1]
+ * @param position OUT: the slider position in pixel from the start
+ * @param length OUT: the slider length in pixel
+ */
+void calcSliderSize(int size, int minSize, double sizeFactor, double posFactor,
int& position, int& length){
- if (sizePercent > 100)
- sizePercent = 100;
- if (posPercent > 100)
- posPercent = 100;
- length = size * sizePercent / 100;
+ if (sizeFactor > 1.0)
+ sizeFactor = 1.0;
+ if (posFactor > 100)
+ posFactor = 100;
+ length = roundInt(size * sizeFactor);
if (length < minSize)
length = minSize;
- position = (size - length) * posPercent / 100;
+ position = roundInt((size - length) * posFactor);
}
/**
*
* @param painter the paint unit
* @param rect the full area of the edit field
- * @param sizeVertical the size of the scrollbar (in %)
- * @param posVertical the position of the scrollbar (in %)
- * @param sizeHorizontal the size of the scrollbar (in %)
- * @param posHorizontal the position of the scrollbar (in %)
+ * @param sizeVertical the size of the scrollbar as factor [0..1]
+ * @param posVertical the position of the scrollbar as factor [0..1]
+ * @param sizeHorizontal the size of the scrollbar as factor [0..1]
+ * @param posHorizontal the position of the scrollbar as factor [0..1]
*/
void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect,
- int sizeVertical, int posVertical, int sizeHorizontal, int posHorizontal){
+ double sizeVertical, double posVertical, double sizeHorizontal,
+ double posHorizontal){
// We paint the vertical scrollbar:
- painter.setBrush(*m_scrollbarBrush);
+ QBrush brush(*m_brushColors[ReLook::BG_SCROLLBAR], Qt::SolidPattern);
+ painter.setBrush(brush);
int x = rect.right() - m_widthVScrollBar;
- painter.drawRect(x, rect.top(), m_widthVScrollBar,
+ m_vScrollBar->setRect(x, rect.top(), m_widthVScrollBar,
rect.height() - m_heightHScrollBar);
+ painter.drawRect(*m_vScrollBar);
// We paint the horizontal scrollbar:
- painter.drawRect(rect.left() + m_widthLineNo,
+ m_hScrollBar->setRect(rect.left() + m_widthLineNo,
rect.bottom() - m_heightHScrollBar,
rect.width() - m_widthVScrollBar - m_widthLineNo, m_heightHScrollBar);
+ painter.drawRect(*m_hScrollBar);
// Slider (vertical)
- painter.setBrush(*m_sliderBrush);
+ QBrush brush2(*m_brushColors[ReLook::BG_SLIDER], Qt::SolidPattern);
+ painter.setBrush(brush2);
int sliderSize = 0;
int sliderPos = 0;
calcSliderSize(rect.height() - m_heightHScrollBar, m_heightHScrollBar,
sizeVertical, posVertical, sliderPos, sliderSize);
- painter.drawRect(x + 1, rect.top() + sliderPos, m_widthVScrollBar - 2,
- sliderSize);
+ m_vSlider->setRect(x, rect.top() + sliderPos, m_widthVScrollBar, sliderSize);
+ painter.drawRect(*m_vSlider);
// Slider (horizontal)
calcSliderSize(rect.width() - m_widthLineNo - m_widthVScrollBar,
m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos, sliderSize);
- painter.drawRect(rect.left() + m_widthLineNo + sliderPos,
- rect.bottom() - m_heightHScrollBar + 1, sliderSize,
- m_heightHScrollBar - 2);
+ m_hSlider->setRect(rect.left() + m_widthLineNo + sliderPos,
+ rect.bottom() - m_heightHScrollBar, sliderSize, m_heightHScrollBar);
+ painter.drawRect(*m_hSlider);
+}
+/**
+ * Handles the event when a drag action is done
+ * @param event
+ */
+void ReEdit::mouseMoveEvent(QMouseEvent* event){
+ if (m_lastMousePosition.x() >= 0
+ && (handleHScrollBar(event, true, this)
+ || handleVScrollBar(event, true, this))){
+ emit repaint();
+ }
}
+
/**
* Handles the mouse click event.
*
* @param event the description of the mouse click
*/
void ReEdit::mousePressEvent(QMouseEvent* event){
- QPoint position = event->pos();
- m_cursorLine = position.y() / heightToFullHeight(m_standardMetrics->height())
- + m_paragraphs.firstLine();
- int x = position.x();
- int charWidth = m_standardMetrics->width('x');
- if (x >= m_widthLineNo && x < m_widthEdit - m_widthVScrollBar){
- if (x <= m_widthLineNo + charWidth / 2)
- m_cursorCol = -1;
- else
- m_cursorCol = (x - m_widthLineNo) / charWidth;
+ if (handleVScrollBar(event, false, this)){
+
+ }else if (handleHScrollBar(event, false, this)){
+
+ }else{
+ QPoint position = event->pos();
+ m_cursorLine = position.y()
+ / heightToFullHeight(m_standardMetrics->height())
+ + m_paragraphs.firstLine();
+ int x = position.x();
+ int charWidth = m_standardMetrics->width('x');
+ if (x >= m_widthLineNo && x < m_widthEdit - m_widthVScrollBar){
+ if (x <= m_widthLineNo + charWidth / 2)
+ m_cursorCol = -1;
+ else
+ m_cursorCol = (x - m_widthLineNo) / charWidth;
+ }
}
+ m_lastMousePosition = event->pos();
+ m_lastTopVSlider = m_vSlider->top();
+ m_lastLeftHSlider = m_hSlider->left();
emit repaint();
}
+/**
+ * Handles the mouse click event.
+ *
+ * @param event the description of the mouse click
+ */
+void ReEdit::mouseReleaseEvent(QMouseEvent* event){
+ m_lastMousePosition.setX(-1);
+}
+
/**
* Calculates the index of the line string from the cursor column.
*
if (cursorLine >= 0)
m_cursorLine = cursorLine;
int firstLine = m_paragraphs.firstLine();
- int pageSize = m_paragraphs.list().length();
- if (m_cursorLine < firstLine || m_cursorLine >= firstLine + pageSize){
+ if (m_cursorLine < firstLine || m_cursorLine >= firstLine + pageSize()){
reposition(m_cursorLine);
}
}
if (paragraph.length() == 0){
const QString& text = edit->lines().lineAt(lineNo);
ReLook* look = edit->lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
+ ReLook* lookTab = edit->lookOf(ReLook::FG_GREY_LIGHT,
+ ReLook::BG_STANDARD);
paragraph.m_columns = 0;
int ixTab;
ReEditText* part;
paragraph.m_columns += ixTab - start;
}
paragraph.append(
- new ReEditText(ReEdit::tabString(paragraph.m_columns), look));
+ new ReEditText(ReEdit::tabString(paragraph.m_columns), lookTab));
start = ixTab + 1;
}
top += heightToFullHeight(height);
for (int ix = 0; ix < length(); ix++){
ReEditText* current = at(ix);
- QFont& font = *current->look()->m_font;
- painter.setFont(font);
- QPen& pen = *current->look()->m_pen;
+ ReLook* look = current->look();
+ painter.setFont(*look->m_font);
+ const ReLook::ForeGround fg = look->m_foreground;
+ QPen pen(*look->m_edit->foregroundColors()[fg]);
painter.setPen(pen);
painter.drawText(x, y, current->text());
x += metrics->width(current->text());
}
}
+/**
+ * Constructor.
+ */
+ReMouseCatcher::ReMouseCatcher() :
+ m_clickObjects(),
+ m_vScrollBar(new ClickPosition(CO_VSCROLLBAR)),
+ m_hScrollBar(new ClickPosition(CO_HSCROLLBAR)),
+ m_hSlider(new ClickPosition(CO_HSLIDER)),
+ m_vSlider(new ClickPosition(CO_VSLIDER)),
+ m_lastMousePosition(),
+ m_lastTopVSlider(0),
+ m_lastLeftHSlider(0){
+
+}
+/**
+ * Destructor.
+ */
+ReMouseCatcher::~ReMouseCatcher(){
+ delete m_vScrollBar;
+ delete m_hScrollBar;
+ delete m_vSlider;
+ delete m_vSlider;
+ m_vScrollBar = m_hScrollBar = m_vSlider = m_hSlider = NULL;
+}
+
+/**
+ * Inserts an object which can be clicked into the list.
+ *
+ * @param object the object to insert.
+ */
+void ReMouseCatcher::insertClickObject(ReMouseCatcher::ClickPosition* object){
+ if (!m_clickObjects.contains(object))
+ m_clickObjects.append(object);
+}
+
+/**
+ * Does some things if the mouse position is inside the vertical scrollbar.
+ *
+ * @param event the mouse click event
+ * @param isDragged <code>true</code>: called from <code>mouseMoveEvent</code>
+ * @param edit the edit field
+ * @return <code>true</code>: the mouse click is inside the vertical sb
+ */
+bool ReMouseCatcher::handleVScrollBar(QMouseEvent* event, bool isDragged,
+ ReEdit* edit){
+ QPoint pos = event->pos();
+ bool rc = rectContains(*m_vScrollBar, pos, "vScrollBar")
+ || (isDragged && m_vScrollBar->contains(m_lastMousePosition));
+ if (rc){
+ int distance = pos.y() - m_lastMousePosition.y();
+ int sliderPos = m_lastTopVSlider + distance;
+ double position = double(sliderPos)
+ / (m_vScrollBar->height() - m_vSlider->height());
+ int line = roundInt(
+ (edit->lines().lineCount() - edit->pageSize())
+ * max(0.0, min(position, 1.0)));
+ edit->reposition(line);
+ }
+ return rc;
+}
+
+/**
+ * Does some things if the mouse position is inside the horizontal scrollbar.
+ *
+ * @param event the mouse click event
+ * @param isDragged <code>true</code>: called from <code>mouseMoveEvent</code>
+ * @param edit the edit field
+ * @return <code>true</code>: the mouse click is inside the horizontal sb
+ */
+bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged,
+ ReEdit* edit){
+ QPoint pos = event->pos();
+ bool rc = rectContains(*m_hScrollBar, pos, "hScrollBar");
+ if (rc){
+
+ }
+ return rc;
+}
+
BG_CURRENT_LINE,
BG_SELECTED,
BG_CURRENT_SELECTED,
+ BG_SCROLLBAR,
+ BG_SLIDER,
BG_SEARCHED,
BG_SAME_WORD,
BG_YELLOW,
}
public:
- /**
- * Returns the look of the instance.
+ /** Returns the look of the instance.
* @return the look
*/
ReLook* look() const{
int m_maxLineLength;
};
+/**
+ * Handles the mouse clicks inside of the edit field.
+ */
+class ReMouseCatcher {
+public:
+ enum ClickObjType {
+ CO_UNDEF,
+ CO_HSCROLLBAR,
+ CO_HSLIDER,
+ CO_VSCROLLBAR,
+ CO_VSLIDER,
+ CO_BOOKMARK
+ };
+ class ClickPosition: public QRect {
+ public:
+ ClickPosition(ClickObjType type) :
+ QRect(0, 0, 0, 0), m_type(type), m_title(), m_object(NULL){
+ }
+ public:
+ bool operator <(const ClickPosition& op){
+ return y() < op.y() || (y() == op.y() && x() < op.x());
+ }
+ public:
+ ClickObjType m_type;
+ QString m_title;
+ void* m_object;
+ };
+public:
+ ReMouseCatcher();
+ ~ReMouseCatcher();
+public:
+ void insertClickObject(ClickPosition* object);
+ bool handleVScrollBar(QMouseEvent* event, bool isDragged, ReEdit* edit);
+ bool handleHScrollBar(QMouseEvent* event, bool isDragged, ReEdit* edit);
+public:
+ QList <ClickPosition*> m_clickObjects;
+ ClickPosition* m_vScrollBar;
+ ClickPosition* m_hScrollBar;
+ ClickPosition* m_hSlider;
+ ClickPosition* m_vSlider;
+ QPoint m_lastMousePosition;
+ int m_lastTopVSlider;
+ int m_lastLeftHSlider;
+};
+
/**
* An text display and edit unit.
*
* It displays a set of paragraphs with line number, vertical and horizontal
* scroll bars and handle the key and mouse events to implement an editor.
*/
-class ReEdit: public QWidget {
+class ReEdit: public QWidget, protected ReMouseCatcher {
Q_OBJECT
public:
enum EditorAction {
EA_DEL_BEGIN_OF_LINE,
EA_DEL_LINE,
};
-
public:
explicit ReEdit(QWidget *parent = 0);
public:
+ void assignColorsStandard();
+ void assignKeysStandard();
int cursorLine() const;
void editorAction(EditorAction action);
ReLines& lines();
ReLook* lookOf(ReLook::ForeGround foreground, ReLook::BackGround background);
-
+ /** Returns the current page size.
+ * return number of visible lines in the edit field
+ */
+ inline
+ int pageSize(){
+ return m_paragraphs.list().length();
+ }
+ void reposition(int firstLine);
void setCursorLine(int cursorLine);
void setLines(ReLines* lines);
/** Returns the paragraph list
* @return the paragraph list
*/
- ReParagraphs& paragraphs(){
+ inline ReParagraphs& paragraphs(){
return m_paragraphs;
}
-
+ /** Returns the array of the foreground colors.
+ * @return the array of the foreground colors
+ */
+ inline const QColor* const * foregroundColors() const{
+ return m_fontColors;
+ }
+ /** Returns the array of the background colors.
+ * @return the array of the background colors
+ */
+ inline const QColor* const * backgroundColors() const{
+ return m_brushColors;
+ }
protected:
int columnToTextIndex(int cursorCol);
QBrush* createBrush(ReLook::BackGround background);
- void drawScrollbars(QPainter& painter, const QRect& rect, int sizeVertical,
- int posVertical, int sizeHorizontal, int posHorizontal);
+ void drawScrollbars(QPainter& painter, const QRect& rect,
+ double sizeVertical, double posVertical, double sizeHorizontal,
+ double posHorizontal);
void ensureCursorVisible(int cursorLine = -1);
- void reposition(int firstLine);
int textIndexToColumn(int index);
protected slots:
+ void keyPressEvent(QKeyEvent* event);
void paintEvent(QPaintEvent *);
+ void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
- void keyPressEvent(QKeyEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
public:
/** Returns the tabulator expanding string.
* @param position the position of the tabulator (0..N-1)
QBrush* m_standardBrush;
QBrush* m_scrollbarBrush;
QBrush* m_sliderBrush;
- QColor* m_brushColors[ReLook::BG_COUNT];
+ const QColor* m_brushColors[ReLook::BG_COUNT];
QPen* m_standardPen;
QFont* m_standardFont;
QFontMetrics* m_standardMetrics;
- QColor* m_fontColors[ReLook::FG_COUNT];
+ const QColor* m_fontColors[ReLook::FG_COUNT];
QMap <int, EditorAction> m_keyAlt;
QMap <int, EditorAction> m_keyAltControl;
QMap <int, EditorAction> m_keyAltControlShift;
QMap <int, EditorAction> m_keyControlShift;
QMap <int, EditorAction> m_keyRaw;
QMap <int, EditorAction> m_keyShift;
+ ReMouseCatcher m_mouseCatcher;
protected:
static QStringList m_tabStrings;
static QChar m_tabChar;