From: hama Date: Wed, 29 Jul 2015 14:43:46 +0000 (+0200) Subject: Horizontal scrolling works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=7cbb55d92dffaed0b50ab0ee9dc4c66895f79513;p=reqt Horizontal scrolling works --- diff --git a/gui/ReEdit.cpp b/gui/ReEdit.cpp index 55fe958..b7dc779 100644 --- a/gui/ReEdit.cpp +++ b/gui/ReEdit.cpp @@ -36,11 +36,11 @@ inline int heightToFullHeight(int height) { * @param edit the parent */ ReLook::ReLook() : - m_font(NULL), - m_metrics(NULL), - m_foreground(FG_STANDARD), - m_background(BG_STANDARD), - m_edit(NULL) { + m_font(NULL), + m_metrics(NULL), + m_foreground(FG_STANDARD), + m_background(BG_STANDARD), + m_edit(NULL) { } /** @@ -50,8 +50,8 @@ ReLook::ReLook() : * @param look the presentation of the text */ ReEditText::ReEditText(const QString& text, ReLook* look) : - m_text(text), - m_look(look) { + m_text(text), + m_look(look) { } @@ -64,7 +64,7 @@ ReEditText::ReEditText(const QString& text, ReLook* look) : * @param edit the edit field (parent) */ void ReCursortLineBuilder::buildParagraph(ReParagraph& paragraph, int lineNo, - ReEdit* edit) { + ReEdit* edit) { if (lineNo == edit->cursorLineNo()) { for (int ix = 0; ix < paragraph.length(); ix++) { ReEditText* text = paragraph.at(ix); @@ -100,32 +100,32 @@ void ReCursortLineBuilder::buildParagraph(ReParagraph& paragraph, int lineNo, * @param parent NULL or a widget which destroy the instance */ ReEdit::ReEdit(QWidget* parent) : - QWidget(parent), - ReMouseCatcher(), - m_widthEdit(0), - m_heightEdit(0), - m_insertMode(true), - m_breakLines(false), - m_widthLineNumbers(50), - m_widthVScrollBar(16), - m_heightHScrollBar(16), - m_looks(), - m_standardBrush(new QBrush(Qt::SolidPattern)), - m_scrollbarBrush(new QBrush(Qt::SolidPattern)), - m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)), - m_brushColors(), - m_standardPen(new QPen(Qt::SolidLine)), - m_standardFont(NULL), - m_standardMetrics(NULL), - m_fontColors(), - m_keyAlt(), - m_keyAltControl(), - m_keyAltControlShift(), - m_keyAltShift(), - m_keyControl(), - m_keyControlShift(), - m_keyRaw(), - m_keyShift() { + QWidget(parent), + ReMouseCatcher(), + m_widthEdit(0), + m_heightEdit(0), + m_insertMode(true), + m_breakLines(false), + m_widthLineNumbers(50), + m_widthVScrollBar(16), + m_heightHScrollBar(16), + m_looks(), + m_standardBrush(new QBrush(Qt::SolidPattern)), + m_scrollbarBrush(new QBrush(Qt::SolidPattern)), + m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)), + m_brushColors(), + m_standardPen(new QPen(Qt::SolidLine)), + m_standardFont(NULL), + m_standardMetrics(NULL), + m_fontColors(), + m_keyAlt(), + m_keyAltControl(), + m_keyAltControlShift(), + m_keyAltShift(), + m_keyControl(), + m_keyControlShift(), + m_keyRaw(), + m_keyShift() { setFocusPolicy(Qt::WheelFocus); m_standardFont = new QFont("Courier"); m_standardFont->setStyleHint(QFont::TypeWriter); @@ -230,7 +230,7 @@ void ReEdit::assignKeysStandard() { * @param length OUT: the slider length in pixel */ void calcSliderSize(int size, int minSize, double sizeFactor, double posFactor, - int& position, int& length) { + int& position, int& length) { if (sizeFactor > 1.0) sizeFactor = 1.0; if (posFactor > 100) @@ -239,6 +239,9 @@ void calcSliderSize(int size, int minSize, double sizeFactor, double posFactor, if (length < minSize) length = minSize; position = roundInt((size - length) * posFactor); + //ReLogger::globalLogger()->logv(LOG_INFO, 4, + // "calcSize: size: %d / %d sizefac: %.2f posfac: %.2f: pos/len: %d/%d", + // size, minSize, sizeFactor, posFactor, position, length); } /** @@ -274,8 +277,8 @@ int ReEdit::cursorLineNo() const { * @param posHorizontal the position of the scrollbar as factor [0..1] */ void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect, - double sizeVertical, double posVertical, double sizeHorizontal, - double posHorizontal) { + double sizeVertical, double posVertical, double sizeHorizontal, + double posHorizontal) { // We paint the vertical scrollbar: QBrush brush(*m_brushColors[ReLook::BG_SCROLLBAR], Qt::SolidPattern); painter.setBrush(brush); @@ -284,14 +287,14 @@ void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect, static int width = 1; static int width2 = 2 * width; m_vScrollBar->setRect(x + width2, rect.top(), m_widthVScrollBar - width2, - rect.height() - m_heightHScrollBar - width); + rect.height() - m_heightHScrollBar - width); painter.drawRect(*m_vScrollBar); // We paint the horizontal scrollbar: m_hScrollBar->setRect(rect.left() + m_widthLineNumbers, - rect.bottom() - m_heightHScrollBar + width, - rect.width() - m_widthVScrollBar - m_widthLineNumbers, - m_heightHScrollBar - width2); + rect.bottom() - m_heightHScrollBar + width, + rect.width() - m_widthVScrollBar - m_widthLineNumbers, + m_heightHScrollBar - width2); painter.drawRect(*m_hScrollBar); // Slider (vertical) @@ -300,36 +303,36 @@ void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect, int sliderSize = 0; int sliderPos = 0; calcSliderSize(rect.height() - m_heightHScrollBar, m_heightHScrollBar, - sizeVertical, posVertical, sliderPos, sliderSize); + sizeVertical, posVertical, sliderPos, sliderSize); m_vSlider->setRect(x + width2, rect.top() + sliderPos + width, - m_widthVScrollBar - width2, sliderSize - width2); + m_widthVScrollBar - width2, sliderSize - width2); painter.drawRect(*m_vSlider); int middle = m_vSlider->top() + m_vSlider->height() / 2; painter.drawLine(m_vSlider->left() + 2, middle, m_vSlider->right() - 2, - middle); + middle); middle -= m_heightHScrollBar / 2 - 2; painter.drawLine(m_vSlider->left() + 2, middle, m_vSlider->right() - 2, - middle); + middle); middle += m_heightHScrollBar - 4; painter.drawLine(m_vSlider->left() + 2, middle, m_vSlider->right() - 2, - middle); + middle); // Slider (horizontal) calcSliderSize(rect.width() - m_widthLineNumbers - m_widthVScrollBar, - m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos, - sliderSize); + m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos, + sliderSize); m_hSlider->setRect(rect.left() + m_widthLineNumbers + sliderPos, - rect.bottom() - m_heightHScrollBar + width, sliderSize - width, - m_heightHScrollBar - width2); + rect.bottom() - m_heightHScrollBar + width, sliderSize - width, + m_heightHScrollBar - width2); painter.drawRect(*m_hSlider); middle = m_hSlider->left() + m_hSlider->width() / 2; painter.drawLine(middle, m_hSlider->top() + 2, middle, - m_hSlider->bottom() - 2); + m_hSlider->bottom() - 2); middle -= m_heightHScrollBar / 2 - 2; painter.drawLine(middle, m_hSlider->top() + 2, middle, - m_hSlider->bottom() - 2); + m_hSlider->bottom() - 2); middle += m_heightHScrollBar - 4; painter.drawLine(middle, m_hSlider->top() + 2, middle, - m_hSlider->bottom() - 2); + m_hSlider->bottom() - 2); } /** @@ -417,7 +420,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) { m_cursorCol = m_lines->lineAt(m_cursorLineNo - 1).length() - 1; } if (m_lines->removePart(m_cursorLineNo, columnToIndex(currentCol), 1, - true)) + true)) m_cursorLineNo = max(0, m_cursorLineNo - 1); break; @@ -426,7 +429,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) { int lastIx = lastColOfCurrent(); if (m_cursorCol <= lastIx) { m_lines->removePart(m_cursorLineNo, m_cursorCol + 1, - lastIx - m_cursorCol, true); + lastIx - m_cursorCol, true); ensureCursorVisible(); } break; @@ -473,7 +476,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) { */ void ReEdit::ensureCursorVisible() { if (m_cursorLineNo < m_firstLine - || m_cursorLineNo >= m_firstLine + pageSize()) { + || m_cursorLineNo >= m_firstLine + pageSize()) { reposition(m_cursorLineNo, m_cursorCol); } if (m_cursorCol < 0) @@ -515,7 +518,7 @@ void ReEdit::keyPressEvent(QKeyEvent* event) { break; } } else if (shift && !keyText.isEmpty() && key != Qt::Key_Delete - && key != Qt::Key_Backspace) { + && key != Qt::Key_Backspace) { m_lines->insertText(m_cursorLineNo, m_cursorCol + 1, keyText); m_cursorCol++; } else { @@ -561,7 +564,7 @@ ReLines& ReEdit::lines() { * @return */ ReLook* ReEdit::lookOf(ReLook::ForeGround foreground, - ReLook::BackGround background) { + ReLook::BackGround background) { int index = foreground * ReLook::BG_COUNT + background; ReLook* rc = m_looks[index]; if (rc == NULL) { @@ -588,8 +591,8 @@ ReLook* ReEdit::lookOf(ReLook::ForeGround foreground, */ void ReEdit::mouseMoveEvent(QMouseEvent* event) { if (m_lastMousePosition.x() >= 0 - && (handleHScrollBar(event, true, this) - || handleVScrollBar(event, true, this))) { + && (handleHScrollBar(event, true, this) + || handleVScrollBar(event, true, this))) { emit repaint(); } } @@ -607,12 +610,12 @@ void ReEdit::mousePressEvent(QMouseEvent* event) { } else { QPoint position = event->pos(); m_cursorLineNo = position.y() - / heightToFullHeight(m_standardMetrics->height()) + m_firstLine; + / heightToFullHeight(m_standardMetrics->height()) + m_firstLine; int x = position.x(); int charWidth = m_standardMetrics->width('x'); x -= m_widthLineNumbers; if (x >= 0 - && x < m_widthEdit - m_widthLineNumbers - m_widthVScrollBar) { + && x < m_widthEdit - m_widthLineNumbers - m_widthVScrollBar) { if (x <= +charWidth / 2) m_cursorCol = m_firstCol - 1; else @@ -620,8 +623,8 @@ void ReEdit::mousePressEvent(QMouseEvent* event) { } } m_lastMousePosition = event->pos(); - m_lastTopVSlider = m_vSlider->top(); - m_lastLeftHSlider = m_hSlider->left(); + m_lastTopVSlider = m_vSlider->top() - m_vScrollBar->top(); + m_lastLeftHSlider = m_hSlider->left() - m_hScrollBar->left(); emit repaint(); } @@ -636,6 +639,10 @@ void ReEdit::mouseReleaseEvent(QMouseEvent* event) { m_lastMousePosition.setX(-1); m_lastMousePosition.setY(-1); } +inline static double fraction(int a, int b, double exception){ + double rc = b == 0 ? exception : (double) a / b; + return rc; +} /** * Draw the edit field. @@ -651,14 +658,14 @@ void ReEdit::paintEvent(QPaintEvent* event) { int pageSize = (rect.height() - m_heightHScrollBar) / lineHeight; int charWidth = m_standardMetrics->averageCharWidth(); int pageWidth = (rect.width() - m_widthVScrollBar - m_widthLineNumbers) - / charWidth; + / charWidth; int firstLine = m_firstLine; load(firstLine, pageSize, pageWidth, this); QPainter painter(this); ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD); painter.setBrush(*look->m_brush); QRect editArea(rect.left() + m_widthLineNumbers, rect.top(), - rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar); + rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar); // Painting the frame of the edit field: painter.drawRect(editArea); // Painting the edit field area (text...) @@ -673,13 +680,13 @@ void ReEdit::paintEvent(QPaintEvent* event) { for (int ix = 0; ix < maxIx; ix++, lineNo++) { QString number = QString::number(lineNo) + ":"; ReLook* look = - lineNo == m_cursorLineNo + 1 ? - lookOf(ReLook::FG_CURRENT_LINE, ReLook::BG_CURRENT_LINE) : - lookStd; + lineNo == m_cursorLineNo + 1 ? + lookOf(ReLook::FG_CURRENT_LINE, ReLook::BG_CURRENT_LINE) : + lookStd; int width = look->m_metrics->width(number); if (ix == 0) y = rect.top() + look->m_metrics->height() - - look->m_metrics->descent(); + - look->m_metrics->descent(); painter.setFont(*look->m_font); painter.setPen(*look->m_pen); painter.drawText(left + m_widthLineNumbers - width - 5, y, number); @@ -687,29 +694,30 @@ void ReEdit::paintEvent(QPaintEvent* event) { } // We paint the cursor: if (m_cursorVisible && m_cursorLineNo >= firstLine - && m_cursorLineNo < firstLine + pageSize) { + && m_cursorLineNo < firstLine + pageSize) { ReParagraph* cursorPara = cursorParagraph(); int col = min(m_cursorCol, cursorPara->m_columns - 1); if (col != -1) col = indexToColumn(col, m_tabWidth, - m_lines->lineAt(m_cursorLineNo)) - m_firstCol; + m_lines->lineAt(m_cursorLineNo)) - m_firstCol; int x = rect.left() + m_widthLineNumbers + 1 - + (col + 1) * lookStd->m_metrics->width('x'); + + (col + 1) * lookStd->m_metrics->width('x'); int y = rect.top() + (m_cursorLineNo - firstLine) * lineHeight; painter.setPen(*look->m_pen); painter.drawLine(x, y, x, y + lineHeight); } int maxLines = max(1, m_lines->lineCount() - pageSize); - drawScrollbars(painter, rect, double(pageSize) / maxLines, - double(m_firstLine) / maxLines, - m_maxCols == 0 ? 1.0 : (double) m_screenWidth / m_maxCols, - m_maxCols == 0 ? 0.0 : (double) m_firstCol / m_maxCols); + + drawScrollbars(painter, rect, fraction(pageSize, maxLines, 1.0), + fraction(m_firstLine, maxLines, 0.0), + fraction(m_screenWidth, m_maxCols, 1.0), + fraction(m_firstCol, max(0, m_maxCols - m_screenWidth), 0.0)); ReLogger::globalLogger()->logv(LOG_INFO, 3, "draw: %.4f", - double(clock() - start) / CLOCKS_PER_SEC); + double(clock() - start) / CLOCKS_PER_SEC); } /** - * Ensures that a given line is visible. + * Ensures that a given line / column is visible. * * @param firstLine number of the line which should be visible */ @@ -765,16 +773,16 @@ void ReEdit::setTabStrings(int tabWidth) { * Constructor. */ ReParagraphs::ReParagraphs() : - m_builders(), - m_firstLine(0), - m_firstCol(0), - m_cursorLineNo(0), - m_cursorCol(-1), - m_lines(NULL), - m_list(), - m_maxCols(0), - m_screenWidth(0), - m_cursorVisible(true) { + m_builders(), + m_firstLine(0), + m_firstCol(0), + m_cursorLineNo(0), + m_cursorCol(-1), + m_lines(NULL), + m_list(), + m_maxCols(0), + m_screenWidth(0), + m_cursorVisible(true) { } /** @@ -816,7 +824,7 @@ void ReParagraphs::clear() { * expanded tabs */ int ReParagraphs::columnToIndex(int column, int tabWidth, - const QString& string) { + const QString& string) { int rc = 0; if (column < 0) rc = -1; @@ -846,7 +854,7 @@ int ReParagraphs::columnToIndex(int column, int tabWidth, ReParagraph* ReParagraphs::cursorParagraph() { ReParagraph* rc = NULL; if (m_cursorLineNo >= m_firstLine - && m_cursorLineNo < m_firstLine + m_list.length()) { + && m_cursorLineNo < m_firstLine + m_list.length()) { rc = m_list.at(m_cursorLineNo - m_firstLine); } return rc; @@ -860,7 +868,7 @@ ReParagraph* ReParagraphs::cursorParagraph() { */ int ReParagraphs::columnToIndex(int cursorCol) { int rc = columnToIndex(cursorCol, m_tabWidth, - m_lines->lineAt(m_cursorLineNo)); + m_lines->lineAt(m_cursorLineNo)); return rc; } @@ -898,7 +906,7 @@ void ReParagraphs::draw(QPainter& painter, int top, int left) { * @return */ int ReParagraphs::indexToColumn(int index, int tabWidth, - const QString& string) { + const QString& string) { int rc = 0; if (index >= 0) { int length = string.length(); @@ -965,13 +973,13 @@ void ReParagraphs::setLines(ReLines* lines) { * @param edit the parent, the edit field */ void ReParagraphBuilder::buildParagraph(ReParagraph& paragraph, int lineNo, - ReEdit* edit) { + ReEdit* edit) { if (paragraph.length() == 0) { int firstCol = edit->m_firstCol; 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); + ReLook::BG_STANDARD); paragraph.m_columns = 0; int ixTab; ReEditText* part; @@ -1058,14 +1066,14 @@ void ReParagraph::draw(QPainter& painter, int& top, int left) { * 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) { + 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) { } /** @@ -1098,23 +1106,26 @@ void ReMouseCatcher::insertClickObject(ReMouseCatcher::ClickPosition* object) { * @return true: the mouse click is inside the horizontal sb */ bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged, - ReEdit* edit) { + ReEdit* edit) { QPoint pos = event->pos(); - bool rc = rectContains(*m_hScrollBar, pos, "hScrollBar"); + bool rc = rectContains(*m_hScrollBar, pos, "hScrollBar") + || (isDragged && m_hScrollBar->contains(m_lastMousePosition)); if (rc) { if (isDragged) { int distance = pos.x() - m_lastMousePosition.x(); int sliderPos = m_lastLeftHSlider + distance; int moveGap = m_hScrollBar->width() - m_hSlider->width(); double position = moveGap == 0 ? 0.0 : double(sliderPos) / moveGap; - int col = roundInt( - (edit->m_maxCols - edit->m_screenWidth) - * max(0.0, min(position, 1.0))); - edit->reposition(edit->m_cursorLineNo, col); + int col = roundInt((edit->m_maxCols - edit->m_screenWidth) * max(0.0, min(position, 1.0))); + //ReLogger::globalLogger()->logv(LOG_INFO, 4, + // "x: %d dist: %d last: %d slPos: %d pos: %.2f gap: %d col: %d / %d scw: %d", + // pos.x(), distance, m_lastLeftHSlider, sliderPos, position, moveGap, + // col, edit->m_maxCols, edit->m_screenWidth); + edit->reposition(edit->m_firstLine, col); } else { - if (pos.y() < m_hSlider->left()) + if (pos.x() < m_hSlider->left()) edit->editorAction(ReEdit::EA_PAGE_LEFT); - else if (pos.y() > m_hSlider->right()) + else if (pos.x() > m_hSlider->right()) edit->editorAction(ReEdit::EA_PAGE_RIGHT); } } @@ -1130,10 +1141,10 @@ bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged, * @return true: the mouse click is inside the vertical sb */ bool ReMouseCatcher::handleVScrollBar(QMouseEvent* event, bool isDragged, - ReEdit* edit) { + ReEdit* edit) { QPoint pos = event->pos(); bool rc = rectContains(*m_vScrollBar, pos, "vScrollBar") - || (isDragged && m_vScrollBar->contains(m_lastMousePosition)); + || (isDragged && m_vScrollBar->contains(m_lastMousePosition)); if (rc) { if (isDragged) { int distance = pos.y() - m_lastMousePosition.y(); @@ -1141,8 +1152,8 @@ bool ReMouseCatcher::handleVScrollBar(QMouseEvent* event, bool isDragged, int moveGap = m_vScrollBar->height() - m_vSlider->height(); double position = moveGap == 0 ? 0.0 : double(sliderPos) / moveGap; int line = roundInt( - (edit->lines().lineCount() - edit->pageSize()) - * max(0.0, min(position, 1.0))); + (edit->lines().lineCount() - edit->pageSize()) + * max(0.0, min(position, 1.0))); edit->reposition(line, edit->m_cursorCol); } else { if (pos.y() < m_vSlider->top())