diff --git a/NEWS.md b/NEWS.md index 421c419a..0c7249f1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -132,6 +132,7 @@ Red Panda C++ Version 2.26 - Enhancement: New option for compiler set "Don't localize gcc output messages" - Enhancement: Optimization for drawing scrollbars. - Enhancement: Issue #213 Expands macro when finding function tips. + - Enhancement: Vertically scroll by pixel. Red Panda C++ Version 2.25 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 2785b05d..3afb8823 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -5086,7 +5086,7 @@ void Editor::reformat(bool doReparse) #endif if (newContent.isEmpty()) return; - int oldTopLine = topLine(); + int oldTopPos = topPos(); QSynedit::BufferCoord mOldCaret = caretXY(); beginEditing(); @@ -5099,7 +5099,7 @@ void Editor::reformat(bool doReparse) setOptions(newOptions); replaceAll(QString::fromUtf8(newContent)); setCaretXY(mOldCaret); - setTopLine(oldTopLine); + setTopPos(oldTopPos); setOptions(oldOptions); endEditing(); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 16948729..671fa5bc 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -3281,7 +3281,7 @@ bool MainWindow::saveLastOpens() fileObj["focused"] = editor->hasFocus(); fileObj["caretX"] = editor->caretX(); fileObj["caretY"] = editor->caretY(); - fileObj["topLine"] = editor->topLine(); + fileObj["top"] = editor->topPos(); fileObj["left"] = editor->leftPos(); filesArray.append(fileObj); } @@ -3383,8 +3383,8 @@ void MainWindow::loadLastOpens() pos.ch = fileObj["caretX"].toInt(1); pos.line = fileObj["caretY"].toInt(1); editor->setCaretXY(pos); - editor->setTopLine( - fileObj["topLine"].toInt(1) + editor->setTopPos( + fileObj["top"].toInt(1) ); editor->setLeftPos( fileObj["left"].toInt(1) @@ -5482,11 +5482,11 @@ void MainWindow::onFileChanged(const QString &path) QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { try { - int topLine = e->topLine(); + int top = e->topPos(); QSynedit::BufferCoord caretPos = e->caretXY(); e->loadFile(); e->setCaretPositionAndActivate(caretPos.line,1); - e->setTopLine(topLine); + e->setTopPos(top); } catch(FileError e) { QMessageBox::critical(this,tr("Error"),e.reason()); } diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index d49d46e9..7c0f5d9f 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -425,7 +425,7 @@ Editor *Project::openUnit(PProjectUnit &unit, const PProjectEditorLayout &layout //editor->setInProject(true); editor->setCaretY(layout->caretY); editor->setCaretX(layout->caretX); - editor->setTopLine(layout->topLine); + editor->setTopPos(layout->top); editor->setLeftPos(layout->left); editor->activate(); return editor; @@ -662,7 +662,7 @@ void Project::saveLayout() jsonLayout["filename"]=unit->fileName(); jsonLayout["caretX"]=editor->caretX(); jsonLayout["caretY"]=editor->caretY(); - jsonLayout["topLine"]=editor->topLine(); + jsonLayout["top"]=editor->topPos(); jsonLayout["left"]=editor->leftPos(); jsonLayout["isOpen"]=true; jsonLayout["focused"]=(editor==e); @@ -678,7 +678,7 @@ void Project::saveLayout() jsonLayout["filename"]=unit->fileName(); jsonLayout["caretX"]=oldLayout->caretX; jsonLayout["caretY"]=oldLayout->caretY; - jsonLayout["topLine"]=oldLayout->topLine; + jsonLayout["top"]=oldLayout->top; jsonLayout["left"]=oldLayout->left; jsonLayout["isOpen"]=false; jsonLayout["focused"]=false; @@ -1945,7 +1945,7 @@ QHash Project::loadLayout() if (mUnits.contains(unitFilename)) { PProjectEditorLayout editorLayout = std::make_shared(); editorLayout->filename=unitFilename; - editorLayout->topLine=jsonLayout["topLine"].toInt(); + editorLayout->top=jsonLayout["top"].toInt(); editorLayout->left=jsonLayout["left"].toInt(); editorLayout->caretX=jsonLayout["caretX"].toInt(); editorLayout->caretY=jsonLayout["caretY"].toInt(); @@ -2175,7 +2175,7 @@ void Project::loadUnitLayout(Editor *e) if (layout) { e->setCaretY(layout->caretY); e->setCaretX(layout->caretX); - e->setTopLine(layout->topLine); + e->setTopPos(layout->top); e->setLeftPos(layout->left); } } diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h index 049dc2d8..666443b5 100644 --- a/RedPandaIDE/project.h +++ b/RedPandaIDE/project.h @@ -61,7 +61,7 @@ struct ProjectModelNode { struct ProjectEditorLayout { QString filename; - int topLine; + int top; int left; int caretX; int caretY; diff --git a/RedPandaIDE/widgets/searchinfiledialog.cpp b/RedPandaIDE/widgets/searchinfiledialog.cpp index abd5ae65..0ed71610 100644 --- a/RedPandaIDE/widgets/searchinfiledialog.cpp +++ b/RedPandaIDE/widgets/searchinfiledialog.cpp @@ -370,7 +370,7 @@ std::shared_ptr SearchInFileDialog::batchFindInEditor(QSyn QSynedit::BufferCoord caretBackup = e->caretXY(); QSynedit::BufferCoord blockBeginBackup = e->blockBegin(); QSynedit::BufferCoord blockEndBackup = e->blockEnd(); - int toplineBackup = e->topLine(); + int topPosBackup = e->topPos(); int leftPosBackup = e->leftPos(); PSearchResultTreeItem parentItem = std::make_shared(); @@ -393,7 +393,7 @@ std::shared_ptr SearchInFileDialog::batchFindInEditor(QSyn // restore e->setCaretXY(caretBackup); - e->setTopLine(toplineBackup); + e->setTopPos(topPosBackup); e->setLeftPos(leftPosBackup); e->setCaretAndSelection( caretBackup, diff --git a/libs/qsynedit/qsynedit/painter.cpp b/libs/qsynedit/qsynedit/painter.cpp index 911c2191..a2b7f1b1 100644 --- a/libs/qsynedit/qsynedit/painter.cpp +++ b/libs/qsynedit/qsynedit/painter.cpp @@ -74,7 +74,7 @@ void QSynEditPainter::paintEditingArea(const QRect& clip) } // If there is anything visible below the last line, then fill this as well. mRcToken = mClip; - mRcToken.setTop((mLastRow - mEdit->mTopLine + 1) * mEdit->mTextHeight); + mRcToken.setTop((mLastRow - mEdit->yposToRow(0) + 1) * mEdit->mTextHeight); if (mRcToken.top() < mRcToken.bottom()) { mPainter->fillRect(mRcToken,colEditorBG()); // Draw the right edge if necessary. @@ -139,7 +139,7 @@ void QSynEditPainter::paintGutter(const QRect& clip) } else { mPainter->setPen(textColor); } - int lineTop = (row - mEdit->mTopLine) * mEdit->mTextHeight; + int lineTop = (row - 1) * mEdit->mTextHeight - mEdit->mTopPos; // next line rect rcLine.setTop(lineTop); @@ -168,7 +168,7 @@ void QSynEditPainter::paintGutter(const QRect& clip) // Form a rectangle for the square the user can click on rcFold.setLeft(mEdit->mGutterWidth - mEdit->mGutter.rightOffset()); - rcFold.setTop((row - mEdit->mTopLine) * mEdit->mTextHeight); + rcFold.setTop((row - 1) * mEdit->mTextHeight - mEdit->mTopPos); rcFold.setRight(rcFold.left() + mEdit->mGutter.rightOffset() - 4); rcFold.setBottom(rcFold.top() + mEdit->mTextHeight); @@ -231,7 +231,7 @@ void QSynEditPainter::paintGutter(const QRect& clip) int line = mEdit->rowToLine(row); if ((line > mEdit->mDocument->count()) && (mEdit->mDocument->count() != 0)) break; - mEdit->onGutterPaint(*mPainter,line, 0, (row - mEdit->mTopLine) * mEdit->mTextHeight); + mEdit->onGutterPaint(*mPainter,line, 0, (row - mEdit->yposToRow(0)) * mEdit->mTextHeight); } } @@ -818,7 +818,7 @@ void QSynEditPainter::paintFoldAttributes() break; int X; // Set vertical coord - int Y = (row - mEdit->mTopLine) * mEdit->mTextHeight; // limit inside clip rect + int Y = (row - mEdit->yposToRow(0)) * mEdit->mTextHeight; // limit inside clip rect if (mEdit->mTextHeight % 2 == 1 && vLine % 2 == 0) { Y++; } @@ -887,7 +887,7 @@ void QSynEditPainter::paintFoldAttributes() if (range->collapsed && !range->parentCollapsed() && (range->fromLine <= mLastLine) && (range->fromLine >= mFirstLine) ) { // Get starting and end points - int Y = (mEdit->lineToRow(range->fromLine) - mEdit->mTopLine + 1) * mEdit->mTextHeight - 1; + int Y = (mEdit->lineToRow(range->fromLine) - mEdit->yposToRow(0) + 1) * mEdit->mTextHeight - 1; mPainter->drawLine(mClip.left(),Y, mClip.right(),Y); } } @@ -933,7 +933,7 @@ void QSynEditPainter::paintLines() // Initialize rcLine for drawing. Note that Top and Bottom are updated // inside the loop. Get only the starting point for this. mRcLine = mClip; - mRcLine.setBottom((mFirstRow - mEdit->mTopLine) * mEdit->mTextHeight); + mRcLine.setBottom((mFirstRow - 1) * mEdit->mTextHeight - mEdit->mTopPos); mTokenAccu.width = 0; mTokenAccu.left = 0; mTokenAccu.style = FontStyle::fsNone; @@ -1015,7 +1015,7 @@ void QSynEditPainter::paintLines() // Update the rcLine rect to this line. // rcLine.setTop(rcLine.bottom()); // rcLine.setBottom(rcLine.bottom()+edit->mTextHeight); - mRcLine.setTop((row - mEdit->mTopLine) * mEdit->mTextHeight); + mRcLine.setTop((row - 1) * mEdit->mTextHeight - mEdit->mTopPos); mRcLine.setHeight(mEdit->mTextHeight); // if (mIsSpecialLine && colSpBG.isValid()) diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index 629ecfaf..83ca13f9 100644 --- a/libs/qsynedit/qsynedit/qsynedit.cpp +++ b/libs/qsynedit/qsynedit/qsynedit.cpp @@ -132,7 +132,7 @@ QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent), mWantReturns = true; mWantTabs = false; mLeftPos = 0; - mTopLine = 1; + mTopPos = 0; mCaretX = 1; mLastCaretColumn = 1; mCaretY = 1; @@ -432,9 +432,9 @@ void QSynEdit::addCaretToUndo() void QSynEdit::addLeftTopToUndo() { BufferCoord p; - //todo: use buffer coord to save left pos is ugly + //todo: use buffer coord to save left/top pos is ugly p.ch = leftPos(); - p.line = topLine(); + p.line = topPos(); mUndoList->addChange(ChangeReason::LeftTop,p,p,QStringList(), mActiveSelectionMode); } @@ -636,8 +636,7 @@ bool QSynEdit::pointToLine(const QPoint &point, int &line) return false; } line = rowToLine( - std::max(1, mTopLine + (point.y() / mTextHeight)) - ); + yposToRow(point.y() / mTextHeight)); return true; } @@ -681,11 +680,11 @@ void QSynEdit::invalidateGutterLines(int firstLine, int lastLine) else lastLine = INT_MAX; } - firstLine = std::max(firstLine, mTopLine); - lastLine = std::min(lastLine, mTopLine + mLinesInWindow); + firstLine = std::min(firstLine, yposToRow(0) ); + lastLine = std::max(lastLine, yposToRow(clientHeight())); // any line visible? if (lastLine >= firstLine) { - rcInval = {0, mTextHeight * (firstLine - mTopLine), + rcInval = {0, mTextHeight * (firstLine-1) - mTopPos, mGutterWidth, mTextHeight * (lastLine - firstLine + 1)}; if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) { mInvalidateRect = mInvalidateRect.united(rcInval); @@ -745,7 +744,7 @@ QPoint QSynEdit::displayCoordToPixels(const DisplayCoord &coord) const { QPoint result; result.setX(coord.x + textOffset()); - result.setY((coord.row - mTopLine) * mTextHeight); + result.setY((coord.row-1) * mTextHeight - mTopPos); return result; } @@ -980,9 +979,9 @@ void QSynEdit::invalidateLine(int line) // invalidate text area of this line if (useCodeFolding()) line = foldLineToRow(line); - if (line >= mTopLine && line <= mTopLine + mLinesInWindow) { + if (line >= yposToRow(0) && line <= yposToRow(clientHeight())) { rcInval = { mGutterWidth, - mTextHeight * (line - mTopLine), + mTextHeight * (line-1) - mTopPos, clientWidth(), mTextHeight}; if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) @@ -1026,16 +1025,14 @@ void QSynEdit::invalidateLines(int firstLine, int lastLine) lastLine = lineToRow(lastLine + 1) - 1; } - // mTopLine is in display coordinates, so FirstLine and LastLine must be - // converted previously. - firstLine = std::max(firstLine, mTopLine); - lastLine = std::min(lastLine, mTopLine + mLinesInWindow); + firstLine = std::min(firstLine, yposToRow(0)); + lastLine = std::max(lastLine, yposToRow(clientHeight())); // any line visible? if (lastLine >= firstLine) { QRect rcInval = { clientLeft()+mGutterWidth, - mTextHeight * (firstLine - mTopLine), + mTextHeight * (firstLine-1) - mTopPos, clientWidth(), mTextHeight * (lastLine - firstLine + 1) }; if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) @@ -1246,7 +1243,7 @@ void QSynEdit::processGutterClick(QMouseEvent *event) QRect rect; rect.setLeft(mGutterWidth - mGutter.rightOffset()); rect.setRight(rect.left() + mGutter.rightOffset() - 4); - rect.setTop((row - mTopLine) * mTextHeight); + rect.setTop((row - 1) * mTextHeight - mTopPos); rect.setBottom(rect.top() + mTextHeight - 1); if (rect.contains(event->pos())) { if (foldRange->collapsed) @@ -1744,7 +1741,7 @@ void QSynEdit::doToggleBlockComment() } -void QSynEdit::doMouseScroll(bool isDragging) +void QSynEdit::doMouseScroll(bool isDragging, int scrollX, int scrollY) { if (mDropped) { mDropped=false; @@ -1764,23 +1761,23 @@ void QSynEdit::doMouseScroll(bool isDragging) iMousePos = mapFromGlobal(iMousePos); coord = pixelsToNearestGlyphPos(iMousePos.x(), iMousePos.y()); coord.row = minMax(coord.row, 1, displayLineCount()); - if (mScrollDeltaX != 0) { + if (scrollX != 0) { int x; - setLeftPos(leftPos() + mScrollDeltaX * mMouseSelectionScrollSpeed); + setLeftPos(leftPos() + scrollX * mMouseSelectionScrollSpeed); x = leftPos(); - if (mScrollDeltaX > 0) // scrolling right? + if (scrollX > 0) // scrolling right? x+=viewWidth(); coord.x = x; } - if (mScrollDeltaY != 0) { + if (scrollY != 0) { int y; //qDebug()< 0) // scrolling down? + setTopPos(mTopPos + scrollY * mMouseSelectionScrollSpeed * mTextHeight); + y = yposToRow(0); + if (scrollY > 0) // scrolling down? y+=mLinesInWindow - 1; coord.row = minMax(y, 1, displayLineCount()); } @@ -2549,15 +2546,11 @@ void QSynEdit::computeScroll(bool isDragging) { QPoint iMousePos = QCursor::pos(); iMousePos = mapFromGlobal(iMousePos); - int X=iMousePos.x(); - int Y=iMousePos.y(); + int x=iMousePos.x(); + int y=iMousePos.y(); QRect iScrollBounds; // relative to the client area int dispX=2,dispY = 2; -// if (isDragging) { -// dispX = mCharWidth / 2 -1; -// dispY = mTextHeight/ 2 -1; -// } int left = mGutterWidth+frameWidth()+dispX; int top = frameWidth()+dispY; iScrollBounds = QRect(left, @@ -2565,32 +2558,22 @@ void QSynEdit::computeScroll(bool isDragging) clientWidth()-left-dispX, clientHeight()-top-dispY); - if (X < iScrollBounds.left()) - mScrollDeltaX = (X - iScrollBounds.left()) / mCharWidth - 1; - else if (X >= iScrollBounds.right()) - mScrollDeltaX = (X - iScrollBounds.right()) / mCharWidth + 1; + int scrollX,scrollY; + if (x < iScrollBounds.left()) + scrollX = (x - iScrollBounds.left()) / mCharWidth - 1; + else if (x >= iScrollBounds.right()) + scrollX = (x - iScrollBounds.right()) / mCharWidth + 1; else - mScrollDeltaX = 0; + scrollX = 0; -// if (isDragging && (X<0 || X>clientRect().width())) { -// mScrollDeltaX = 0; -// } + if (y < iScrollBounds.top()) + scrollY = (y - iScrollBounds.top()) / mTextHeight - 1; + else if (y >= iScrollBounds.bottom()) { + scrollY = (y - iScrollBounds.bottom()) / mTextHeight + 1; + } else + scrollY = 0; - if (Y < iScrollBounds.top()) - mScrollDeltaY = (Y - iScrollBounds.top()) / mTextHeight - 1; - else if (Y >= iScrollBounds.bottom()) - mScrollDeltaY = (Y - iScrollBounds.bottom()) / mTextHeight + 1; - else - mScrollDeltaY = 0; - -// if (isDragging && (Y<0 || Y>clientRect().height())) { -// mScrollDeltaY = 0; -// } - - -// if (mScrollDeltaX!=0 || mScrollDeltaY!=0) { - doMouseScroll(isDragging); -// } + doMouseScroll(isDragging, scrollX, scrollY); } void QSynEdit::doBlockIndent() @@ -3078,15 +3061,15 @@ void QSynEdit::ensureCursorPosVisibleEx(bool ForceToMiddle) // Make sure Y is visible int vCaretRow = displayY(); if (ForceToMiddle) { - if (vCaretRow < mTopLine || vCaretRow>(mTopLine + (mLinesInWindow - 2))) - setTopLine( vCaretRow - (mLinesInWindow - 1) / 2); + if (vCaretRow < yposToRow(0) || vCaretRow>(yposToRow(0) + (mLinesInWindow - 2))) + setTopPos( (vCaretRow - (mLinesInWindow - 1) / 2-1) * mTextHeight); } else { - if (vCaretRow < mTopLine) - setTopLine(vCaretRow); - else if (vCaretRow > mTopLine + (mLinesInWindow - 2) && mLinesInWindow > 2) { - setTopLine(vCaretRow - (mLinesInWindow - 2) ); + if (vCaretRow < yposToRow(0)) + setTopPos(vCaretRow); + else if (vCaretRow > yposToRow(0) + (mLinesInWindow - 2) && mLinesInWindow > 2) { + setTopPos( (vCaretRow - (mLinesInWindow - 2) -1) * mTextHeight); } else - setTopLine(mTopLine); + setTopPos(mTopPos); } } @@ -3190,7 +3173,7 @@ void QSynEdit::updateVScrollbar() nMin = 1; nMax = std::max(1, nMaxScroll); nPage = mLinesInWindow; - nPos = mTopLine; + nPos = mTopPos; verticalScrollBar()->setMinimum(nMin); verticalScrollBar()->setMaximum(nMax); verticalScrollBar()->setPageStep(nPage); @@ -3824,7 +3807,7 @@ void QSynEdit::onSizeOrFontChanged(bool bFont) //if (!mOptions.testFlag(SynEditorOption::eoScrollPastEol)) setLeftPos(mLeftPos); //if (!mOptions.testFlag(SynEditorOption::eoScrollPastEof)) - setTopLine(mTopLine); + setTopPos(mTopPos); } } @@ -3836,7 +3819,7 @@ void QSynEdit::onChanged() void QSynEdit::onScrolled(int) { mLeftPos = horizontalScrollBar()->value(); - mTopLine = verticalScrollBar()->value(); + mTopPos = verticalScrollBar()->value(); invalidate(); } @@ -4101,7 +4084,7 @@ void QSynEdit::setOptions(const EditorOptions &Value) //if (!mOptions.testFlag(eoScrollPastEol)) setLeftPos(mLeftPos); //if (!mOptions.testFlag(eoScrollPastEof)) - setTopLine(mTopLine); + setTopPos(mTopPos); bool bUpdateAll = !sameEditorOption(Value,mOptions, eoShowLeadingSpaces) @@ -4221,7 +4204,7 @@ void QSynEdit::doUndoItem() case ChangeReason::LeftTop: BufferCoord p; p.ch = leftPos(); - p.line = topLine(); + p.line = topPos(); mRedoList->addRedo( item->changeReason(), p, @@ -4229,7 +4212,7 @@ void QSynEdit::doUndoItem() item->changeSelMode(), item->changeNumber()); setLeftPos(item->changeStartPos().ch); - setTopLine(item->changeStartPos().line); + setTopPos(item->changeStartPos().line); break; case ChangeReason::Selection: mRedoList->addRedo( @@ -4426,7 +4409,7 @@ void QSynEdit::doRedoItem() case ChangeReason::LeftTop: BufferCoord p; p.ch = leftPos(); - p.line = topLine(); + p.line = topPos(); mUndoList->restoreChange( item->changeReason(), p, @@ -4434,7 +4417,7 @@ void QSynEdit::doRedoItem() item->changeSelMode(), item->changeNumber()); setLeftPos(item->changeStartPos().ch); - setTopLine(item->changeStartPos().line); + setTopPos(item->changeStartPos().line); break; case ChangeReason::Selection: mUndoList->restoreChange( @@ -4952,7 +4935,8 @@ void QSynEdit::doGotoBlockStart(bool isSelection) if (document()->blockStarted(line-1)>document()->blockEnded(line-1)) { moveCaretVert(line+1-mCaretY, isSelection); moveCaretToLineStart(isSelection); - setTopLine(line-1); + line = lineToRow(line); + setTopPos((line-1)*mTextHeight); return; } line--; @@ -4974,7 +4958,8 @@ void QSynEdit::doGotoBlockEnd(bool isSelection) if (document()->blockEnded(line-1)>document()->blockStarted(line-1)) { moveCaretVert(line-1-mCaretY, isSelection); moveCaretToLineStart(isSelection); - setTopLine(line-mLinesInWindow+1); + line = lineToRow(line) - mLinesInWindow + 1; + setTopPos((line-1)*mTextHeight); return; } line++; @@ -5669,11 +5654,11 @@ void QSynEdit::executeCommand(EditCommand command, QChar ch, void *pData) } case EditCommand::PageTop: case EditCommand::SelPageTop: - moveCaretVert(mTopLine-mCaretY, command == EditCommand::SelPageTop); + moveCaretVert(yposToRow(0)-mCaretY, command == EditCommand::SelPageTop); break; case EditCommand::PageBottom: case EditCommand::SelPageBottom: - moveCaretVert(mTopLine+mLinesInWindow-1-mCaretY, command == EditCommand::SelPageBottom); + moveCaretVert(yposToRow(0)+mLinesInWindow-1-mCaretY, command == EditCommand::SelPageBottom); break; case EditCommand::EditorStart: case EditCommand::SelEditorStart: @@ -5923,9 +5908,9 @@ void QSynEdit::updateMouseCursor(){ bool QSynEdit::isCaretVisible() { DisplayCoord caret = displayXY(); - if (caret.row < mTopLine) + if (caret.row < yposToRow(0)) return false; - if (caret.row >= mTopLine + mLinesInWindow ) + if (caret.row >= yposToRow(clientHeight()) ) return false; if (caret.x < mLeftPos) return false; @@ -5973,8 +5958,8 @@ void QSynEdit::paintEvent(QPaintEvent *event) nX1 += (rcClip.left() - mGutterWidth - 2 ) ; nX2 = mLeftPos + (rcClip.right() - mGutterWidth - 2); // lines - nL1 = minMax(mTopLine + rcClip.top() / mTextHeight, mTopLine, displayLineCount()); - nL2 = minMax(mTopLine + (rcClip.bottom() + mTextHeight - 1) / mTextHeight, 1, displayLineCount()); + nL1 = minMax(yposToRow(0) + rcClip.top() / mTextHeight, yposToRow(0), displayLineCount()); + nL2 = minMax(yposToRow(0) + (rcClip.bottom() + mTextHeight - 1) / mTextHeight, 1, displayLineCount()); //qDebug()<<"Paint:"<angleDelta().y(); while (mWheelAccumulatedDeltaY>=120) { mWheelAccumulatedDeltaY-=120; - verticalScrollBar()->setValue(verticalScrollBar()->value()+sign*mMouseWheelScrollSpeed); + verticalScrollBar()->setValue(verticalScrollBar()->value()+sign*mMouseWheelScrollSpeed*mTextHeight); } while (mWheelAccumulatedDeltaY<=-120) { mWheelAccumulatedDeltaY+=120; - verticalScrollBar()->setValue(verticalScrollBar()->value()-sign*mMouseWheelScrollSpeed); + verticalScrollBar()->setValue(verticalScrollBar()->value()-sign*mMouseWheelScrollSpeed*mTextHeight); } if ( (mWheelAccumulatedDeltaX>0 &&event->angleDelta().x()<0) @@ -6374,7 +6359,7 @@ void QSynEdit::dropEvent(QDropEvent *event) // } coord = ensureBufferCoordValid(coord); bool lastLineUsed = coord.line == mDocument->count(); - int topLine = mTopLine; + int topPos = mTopPos; int leftPos = mLeftPos; int line=mDocument->count()-1; QString s=mDocument->getLine(line-1); @@ -6429,7 +6414,7 @@ void QSynEdit::dropEvent(QDropEvent *event) coord.ch -= mDragSelEndSave.ch-1; } else { coord.line -= mDragSelEndSave.line-mDragSelBeginSave.line; - topLine -= mDragSelEndSave.line-mDragSelBeginSave.line; + topPos -= (mDragSelEndSave.line-mDragSelBeginSave.line) * mTextHeight; } } } @@ -6437,7 +6422,7 @@ void QSynEdit::dropEvent(QDropEvent *event) endEditing(); event->acceptProposedAction(); mDropped = true; - setTopLine(topLine); + setTopPos(topPos); setLeftPos(leftPos); internalSetCaretXY(coord); } @@ -6476,9 +6461,9 @@ void QSynEdit::dragLeaveEvent(QDragLeaveEvent *) int QSynEdit::maxScrollHeight() const { if (mOptions.testFlag(eoScrollPastEof)) - return std::max(displayLineCount(),1); + return std::max(displayLineCount(),1) * mTextHeight - 1; else - return std::max(displayLineCount()-mLinesInWindow+1, 1); + return std::max((displayLineCount()-mLinesInWindow+1) * mTextHeight - 1 , 1) ; } bool QSynEdit::modified() const @@ -6564,8 +6549,7 @@ void QSynEdit::onLinesChanged() mInvalidateRect = {0,0,0,0}; if (mGutter.showLineNumbers() && (mGutter.autoSize())) mGutter.autoSizeDigitCount(mDocument->count()); - //if (!mOptions.testFlag(SynEditorOption::eoScrollPastEof)) - setTopLine(mTopLine); + setTopPos(mTopPos); } void QSynEdit::onLinesChanging() @@ -6584,7 +6568,7 @@ void QSynEdit::onLinesCleared() // set caret and selected block to start of text setCaretXY({1,1}); // scroll to start of text - setTopLine(1); + setTopPos(0); setLeftPos(0); mStatusChanges.setFlag(StatusChange::scAll); } @@ -6714,15 +6698,19 @@ void QSynEdit::setBlockEnd(BufferCoord value) } if (value.ch != mBlockEnd.ch || value.line != mBlockEnd.line) { if (mActiveSelectionMode == SelectionMode::Column && value.ch != mBlockEnd.ch) { + BufferCoord oldBlockEnd = mBlockEnd; + mBlockEnd = value; invalidateLines( - std::min(mBlockBegin.line, std::min(mBlockEnd.line, value.line)), - std::max(mBlockBegin.line, std::max(mBlockEnd.line, value.line))); - mBlockEnd = value; + std::min(mBlockBegin.line, std::min(mBlockEnd.line, oldBlockEnd.line)), + std::max(mBlockBegin.line, std::max(mBlockEnd.line, oldBlockEnd.line))); } else { - int nLine = mBlockEnd.line; + BufferCoord oldBlockEnd = mBlockEnd; mBlockEnd = value; - if (mActiveSelectionMode != SelectionMode::Column || mBlockBegin.ch != mBlockEnd.ch) - invalidateLines(nLine, mBlockEnd.line); + if (mActiveSelectionMode != SelectionMode::Column || oldBlockEnd.line != mBlockEnd.line) { + invalidateLines( + std::min(mBlockBegin.line, std::min(mBlockEnd.line, oldBlockEnd.line)), + std::max(mBlockBegin.line, std::max(mBlockEnd.line, oldBlockEnd.line))); + } } setStatusChanged(StatusChange::scSelection); } @@ -6863,22 +6851,18 @@ int QSynEdit::linesInWindow() const return mLinesInWindow; } -int QSynEdit::topLine() const +int QSynEdit::topPos() const { - return mTopLine; + return mTopPos; } -void QSynEdit::setTopLine(int Value) +void QSynEdit::setTopPos(int value) { - Value = std::min(Value,maxScrollHeight()); -// if (mOptions.testFlag(SynEditorOption::eoScrollPastEof)) -// Value = std::min(Value, displayLineCount()); -// else -// Value = std::min(Value, displayLineCount() - mLinesInWindow + 1); - Value = std::max(Value, 1); - if (Value != mTopLine) { - verticalScrollBar()->setValue(Value); - setStatusChanged(StatusChange::scTopLine); + value = std::min(value,maxScrollHeight()); + value = std::max(value, 1); + if (value != mTopPos) { + verticalScrollBar()->setValue(value); + setStatusChanged(StatusChange::scTopPos); } } diff --git a/libs/qsynedit/qsynedit/qsynedit.h b/libs/qsynedit/qsynedit/qsynedit.h index 204c3c90..3dcc5743 100644 --- a/libs/qsynedit/qsynedit/qsynedit.h +++ b/libs/qsynedit/qsynedit/qsynedit.h @@ -48,7 +48,7 @@ enum StatusChange { scCaretX = 0x0002, scCaretY = 0x0004, scLeftPos = 0x0008, - scTopLine = 0x0010, + scTopPos = 0x0010, scInsertMode = 0x0020, scModifyChanged = 0x0040, scSelection = 0x0080, @@ -176,7 +176,7 @@ public: void invalidateGutterLines(int FirstLine, int LastLine); int yposToRow(int y) const { - return std::max(1, mTopLine + (y / mTextHeight)); + return std::max(1, ((y + mTopPos) / mTextHeight) + 1 ); } DisplayCoord pixelsToNearestGlyphPos(int aX, int aY) const; @@ -333,8 +333,8 @@ public: bool isCaretVisible(); // setter && getters - int topLine() const; - void setTopLine(int value); + int topPos() const; + void setTopPos(int value); int linesInWindow() const; @@ -651,7 +651,7 @@ private: void doUncomment(); void doToggleComment(); void doToggleBlockComment(); - void doMouseScroll(bool isDragging); + void doMouseScroll(bool isDragging, int scrollX, int scrollY); QString getDisplayStringAtLine(int line) const; @@ -702,7 +702,7 @@ private: QColor mRightEdgeColor; ScrollStyle mScrollBars; int mTextHeight; - int mTopLine; + int mTopPos; PSyntaxer mSyntaxer; QColor mSelectedForeground; QColor mSelectedBackground; @@ -742,8 +742,6 @@ private: // fFocusList: TList; // fPlugins: TList; QTimer* mScrollTimer; - int mScrollDeltaX; - int mScrollDeltaY; PSynEdit fChainedEditor;