diff options
author | David Schulz <[email protected]> | 2025-09-10 14:19:32 +0200 |
---|---|---|
committer | David Schulz <[email protected]> | 2025-09-11 10:43:23 +0000 |
commit | 1e7f76cb5fd036da4fb5fdb7659bcac93a4834fb (patch) | |
tree | c909a621003d2c7d9deb43553fbb1dc7667f5189 | |
parent | 1dc94f1aac8f2e48e231cb4612083986f77ad9f7 (diff) |
Utils: improve page up/down in plain text edit
Just increasing the scrollbar by page step and moving the cursor to the
closest previous vertical offset is way cleaner than the previous
aproach.
Fixes: QTCREATORBUG-33447
Change-Id: I8c6fcfabd263d11ac088f93d34967c2a0682e61b
Reviewed-by: Christian Stenger <[email protected]>
-rw-r--r-- | src/libs/utils/plaintextedit/plaintextedit.cpp | 107 |
1 files changed, 19 insertions, 88 deletions
diff --git a/src/libs/utils/plaintextedit/plaintextedit.cpp b/src/libs/utils/plaintextedit/plaintextedit.cpp index 8cb3a2642f2..48a53ab3c3a 100644 --- a/src/libs/utils/plaintextedit/plaintextedit.cpp +++ b/src/libs/utils/plaintextedit/plaintextedit.cpp @@ -1051,8 +1051,6 @@ void PlainTextEditPrivate::repaintContents(const QRectF &contentsRect) void PlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode, bool moveCursor) { - - QTextCursor cursor = control->textCursor(); if (moveCursor) { ensureCursorVisible(); @@ -1060,100 +1058,33 @@ void PlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor pageUpDownLastCursorY = control->cursorRect(cursor).top() - verticalOffset(); } - qreal lastY = pageUpDownLastCursorY; + int scrollBarValue = vbar()->value(); + const bool atStart = scrollBarValue == 0; + const bool atEnd = scrollBarValue == vbar()->maximum(); - if (op == QTextCursor::Down) { - QRectF visible = QRectF(viewport()->rect()).translated(-q->contentOffset()); - QTextBlock firstVisibleBlock = q->firstVisibleBlock(); - QTextBlock block = firstVisibleBlock; - QRectF br = q->blockBoundingRect(block); - qreal h = 0; - int atEnd = false; - while (h + br.height() <= visible.bottom()) { - if (!block.next().isValid()) { - atEnd = true; - lastY = visible.bottom(); // set cursor to last line - break; - } - h += br.height(); - block = block.next(); - br = q->blockBoundingRect(block); - } + if (op == QTextCursor::Down && !atEnd) + scrollBarValue += vbar()->pageStep(); + else if (op == QTextCursor::Up && !atStart) + scrollBarValue -= vbar()->pageStep(); - if (!atEnd) { - int line = 0; - qreal diff = visible.bottom() - h; - int lineCount = editorLayout->blockLayout(block)->lineCount(); - while (line < lineCount - 1) { - if (editorLayout->blockLayout(block)->lineAt(line).naturalTextRect().bottom() > diff) { - // the first line that did not completely fit the screen - break; - } - ++line; - } - setTopBlock(block.blockNumber(), line); - } + vbar()->setValue(scrollBarValue); - if (moveCursor) { - // move using movePosition to keep the cursor's x - lastY += verticalOffset(); - bool moved = false; - do { - moved = cursor.movePosition(op, moveMode); - } while (moved && control->cursorRect(cursor).top() < lastY); - } - - } else if (op == QTextCursor::Up) { - - QRectF visible = QRectF(viewport()->rect()).translated(-q->contentOffset()); - visible.translate(0, -visible.height()); // previous page - QTextBlock block = q->firstVisibleBlock(); - qreal h = 0; - while (h >= visible.top()) { - if (!block.previous().isValid()) { - if (control->topBlock == 0 && topLine == 0) { - lastY = 0; // set cursor to first line - } - break; - } - block = block.previous(); - QRectF br = q->blockBoundingRect(block); - h -= br.height(); - } - - int line = 0; - if (block.isValid()) { - qreal diff = visible.top() - h; - int lineCount = editorLayout->blockLayout(block)->lineCount(); - while (line < lineCount) { - if (editorLayout->blockLayout(block)->lineAt(line).naturalTextRect().top() >= diff) + if (moveCursor) { + while (cursor.movePosition(op, moveMode)) { + if (op == QTextCursor::Down) { + if (atEnd) + continue; + if (control->cursorRect(cursor).top() >= pageUpDownLastCursorY) + break; + } else if (op == QTextCursor::Up) { + if (atStart) + continue; + if (control->cursorRect(cursor).top() <= pageUpDownLastCursorY) break; - ++line; - } - if (line == lineCount) { - if (block.next().isValid() && block.next() != q->firstVisibleBlock()) { - block = block.next(); - line = 0; - } else { - --line; - } } } - setTopBlock(block.blockNumber(), line); - if (moveCursor) { - cursor.setVisualNavigation(true); - // move using movePosition to keep the cursor's x - lastY += verticalOffset(); - bool moved = false; - do { - moved = cursor.movePosition(op, moveMode); - } while (moved && control->cursorRect(cursor).top() > lastY); - } - } - - if (moveCursor) { control->setTextCursor(cursor, moveMode == QTextCursor::KeepAnchor); pageUpDownLastCursorYIsValid = true; } |