]> gitweb.hamatoma.de Git - reqt/commitdiff
reditor: vertical scrollbar works
authorhama <hama@siduction.net>
Sun, 28 Jun 2015 09:52:19 +0000 (11:52 +0200)
committerhama <hama@siduction.net>
Sun, 28 Jun 2015 09:52:19 +0000 (11:52 +0200)
appl/reditor/main.cpp
appl/reditor/reditor.pro
base/ReLogger.cpp
base/ReLogger.hpp
base/rebase.hpp
gui/ReEdit.cpp
gui/ReEdit.hpp
gui/regui.hpp

index 6d719ca8615070f087b37db57ae4533176cc0785..302401e55ed2164c1aabff1faf68f006a39b32d7 100644 (file)
@@ -8,13 +8,17 @@
  * You also can use this license: http://www.wtfpl.net
  * The latest sources: https://github.com/republib
  */
-
+#include "base/rebase.hpp"
 #include "../reditor/mainwindow.hpp"
 #include <QApplication>
 
 int main(int argc, char *argv[]){
    QApplication a(argc, argv);
+   ReLogger logger;
+   ReDebugAppender appender;
+   logger.addAppender(&appender);
    MainWindow w;
+   logger.log(LOG_INFO, 1, "start");
    w.show();
 
    return a.exec();
index 7d966a5892eb2f2a509bafa4dc3367f74b82ac1f..82217985e3c2ce6b332009e4f552194c8d608960 100644 (file)
@@ -16,7 +16,8 @@ INCLUDEPATH += ../..
 SOURCES += main.cpp\
         ../../gui/ReEdit.cpp \
         ../../base/ReFile.cpp \
-       mainwindow.cpp
+       mainwindow.cpp \
+    ../../base/ReLogger.cpp
 
 
 HEADERS  += mainwindow.hpp \
index 16ccbabf3f50f928048a5674c5f875b865eaf8d5..6e932638b1abf92bc064fcc6e6919eb20c8a2407 100644 (file)
@@ -144,14 +144,19 @@ bool ReAppender::isAutoDelete() const{
 
 /**
  * @brief Constructor.
+ *
+ * @param isGlobal  <code>true</code>: the logger becomes the global logger
  */
-ReLogger::ReLogger() :
+ReLogger::ReLogger(bool isGlobal) :
          // m_appenders(),
             m_countAppenders(0),
             m_stdPrefix(),
             m_mutex(),
             m_withLocking(false){
    memset(m_appenders, 0, sizeof m_appenders);
+   if (isGlobal){
+       m_globalLogger = this;
+   }
 }
 
 /**
@@ -633,3 +638,31 @@ const QList <QByteArray>& ReMemoryAppender::getLines() const{
 void ReMemoryAppender::clear(){
    m_lines.clear();
 }
+
+/**
+ * Constructor.
+ *
+ * @param appenderName  a name for the appender
+ */
+ReDebugAppender::ReDebugAppender(const char* appenderName) :
+    ReAppender(appenderName){
+}
+/**
+ * Destructor.
+ */
+ReDebugAppender::~ReDebugAppender(){
+}
+
+/**
+ * @brief Logs (or not) the current location.
+ *
+ * @param level                the level of the location
+ * @param location     an unique identifier of the location
+ * @param message      the logging message
+ * @param logger    the calling logger
+ */
+void ReDebugAppender::log(ReLoggerLevel level, int location,
+   const char* message, ReLogger* logger){
+    QByteArray msg(logger->getStdPrefix(level, location));
+    qDebug("%s%s", msg.constData(), message);
+}
index 293bf2ef4c83cca4da5ab5fe5dfdd1769efbfb45..64bd804b2794963d3bf596011e4ce4ea1327b3d4 100644 (file)
@@ -60,13 +60,7 @@ private:
 
 class ReLogger {
 public:
-   static ReLogger* globalLogger();
-   static void destroyGlobalLogger();
-private:
-   // the standard logger, can be called (with globalLogger()) from each location
-   static ReLogger* m_globalLogger;
-public:
-   ReLogger();
+   ReLogger(bool isGlobal = true);
    virtual ~ReLogger();
 private:
    // No copy constructor: no implementation!
@@ -93,6 +87,12 @@ public:
    bool isActive(ReLoggerLevel level) const;
    void setLevel(ReLoggerLevel level);
    void setWithLocking(bool onNotOff);
+public:
+   static ReLogger* globalLogger();
+   static void destroyGlobalLogger();
+private:
+   // the standard logger, can be called (with globalLogger()) from each location
+   static ReLogger* m_globalLogger;
 private:
    // the assigned appenders:
    ReAppender* m_appenders[16];
@@ -168,4 +168,16 @@ private:
    bool m_addPrefix;
 };
 
+/**
+ * Write the log messages to the QT debug output.
+ */
+class ReDebugAppender: public ReAppender {
+public:
+   ReDebugAppender(const char* appenderName = "DebugAppender");
+   ~ReDebugAppender();
+public:
+   virtual void log(ReLoggerLevel level, int location, const char* message,
+      ReLogger* logger);
+};
+
 #endif // RELOGGER_HPP
index 9e010bb8e0931708d4e6c1b45a54aedb7bb3de81..c2dd64b15849e8e274cfd13b6179f62dc852dd38 100644 (file)
@@ -70,6 +70,21 @@ inline
 int min(int a, int b){
     return a < b ? a : b;
 }
+inline double max(double a, double b){
+    return a > b ? a : b;
+}
+inline double min(double a, double b){
+    return a < b ? a : b;
+}
+
+/**
+ * Rounds a double value to an integer.
+ *
+ * @param value the value to round
+ */
+inline int roundInt(double value){
+    return (int) round(value);
+}
 
 #include "remodules.hpp"
 #include "base/ReByteStorage.hpp"
index 4890ae78f590fb910fd4f5e691282b0082871d6a..32e97d23d27818ea6f3210a7614cb272e25864dc 100644 (file)
@@ -14,8 +14,8 @@
 #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;
 
 /**
@@ -100,6 +100,7 @@ void ReCursortLineBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
  */
 ReEdit::ReEdit(QWidget* parent) :
             QWidget(parent),
+            ReMouseCatcher(),
             m_paragraphs(),
             m_firstLine(0),
             m_firstCol(0),
@@ -111,8 +112,8 @@ ReEdit::ReEdit(QWidget* parent) :
             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)),
@@ -142,6 +143,15 @@ ReEdit::ReEdit(QWidget* parent) :
    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);
@@ -165,6 +175,8 @@ ReEdit::ReEdit(QWidget* parent) :
    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);
@@ -172,9 +184,17 @@ ReEdit::ReEdit(QWidget* parent) :
    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;
@@ -190,7 +210,7 @@ ReEdit::ReEdit(QWidget* parent) :
    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);
+
 }
 
 /**
@@ -206,6 +226,7 @@ ReLook* ReEdit::lookOf(ReLook::ForeGround foreground,
    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);
@@ -239,6 +260,7 @@ QBrush* ReEdit::createBrush(ReLook::BackGround 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();
@@ -246,7 +268,6 @@ void ReEdit::paintEvent(QPaintEvent* event){
    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);
@@ -290,20 +311,32 @@ void ReEdit::paintEvent(QPaintEvent* event){
    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);
 }
 
 /**
@@ -311,59 +344,95 @@ void calcSliderSize(int size, int minSize, int sizePercent, int posPercent,
  *
  * @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.
  *
@@ -497,8 +566,7 @@ void ReEdit::ensureCursorVisible(int cursorLine){
    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);
    }
 }
@@ -700,6 +768,8 @@ void ReParagraphBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
    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;
@@ -711,7 +781,7 @@ void ReParagraphBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
             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;
       }
 
@@ -748,12 +818,92 @@ void ReParagraph::draw(QPainter& painter, int& top, int left){
    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;
+}
+
index 80ae8e88bb4bb3fbd9fb6b7c3c14b40c06e84459..1051acbe5969286b2cf1f1b10e8c9a6258ce85f9 100644 (file)
@@ -52,6 +52,8 @@ public:
          BG_CURRENT_LINE,
          BG_SELECTED,
          BG_CURRENT_SELECTED,
+         BG_SCROLLBAR,
+         BG_SLIDER,
          BG_SEARCHED,
          BG_SAME_WORD,
          BG_YELLOW,
@@ -96,8 +98,7 @@ public:
    }
 
 public:
-   /**
-    * Returns the look of the instance.
+   /** Returns the look of the instance.
     * @return  the look
     */
    ReLook* look() const{
@@ -227,13 +228,58 @@ protected:
    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 {
@@ -254,36 +300,57 @@ public:
          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)
@@ -325,11 +392,11 @@ protected:
    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;
@@ -338,6 +405,7 @@ protected:
    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;
index 709f6eb5aa4c1f08413358e6f2d4c67b471d5a35..724f9bee89c244ecfa0cbabd8a3073b75721d48b 100644 (file)
 #include "gui/ReStateStorage.hpp"
 #include "gui/ReGuiValidator.hpp"
 #include "gui/ReEdit.hpp"
+/**
+ * Tests whether a point is inside the rectangle (including border).
+ * @param rect  rectangle to test
+ * @param point point to test
+ * @return      <code>true</code>: the point lays inside the rectangle
+ */
+inline bool rectContains(const QRect& rect, const QPoint& point,
+   const char* what = ""){
+#if 1
+   return point.x() >= rect.x() && point.y() >= rect.y()
+      && point.x() < rect.x() + rect.width()
+      && point.y() < rect.y() + rect.height();
+#else
+   bool rc = point.x() >= rect.x();
+   char reason = ' ';
+   if (! rc)
+   reason = 'x';
+   else{
+      rc = point.y() >= rect.y();
+      if (! rc)
+      reason = 'y';
+      else{
+         rc = point.x() < rect.x() + rect.width();
+         if (! rc)
+         reason = 'X';
+         else{
+            rc = point.y() < rect.y() + rect.height();
+            if (! rc)
+            reason = 'Y';
+         }
+      }
+   }
+   if (! rc)
+   ReLogger::globalLogger()->logv(LOG_INFO, 1, "rectContains(%s) %c %d/%d %d-%d/%d-%d",
+            what, reason, point.x(), point.y(), rect.x(), rect.x() + rect.width(),
+            rect.y(), rect.y() + rect.height());
+   return rc;
+#endif
+}
+
 #endif /* GUI_REGUI_HPP_ */