aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2025-06-01 08:38:14 +1000
committerNeil <nyamatongwe@gmail.com>2025-06-01 08:38:14 +1000
commita180e477ec3efd9d35a4cf32b63ab7354a03371f (patch)
tree17ed696a646a5acf4305a0795ae56690a04e08b5 /src
parent922a70ac051ac097632bc26e56c23fffb65aa43d (diff)
downloadscintilla-mirror-a180e477ec3efd9d35a4cf32b63ab7354a03371f.tar.gz
Add SCI_SCROLLVERTICAL API.
Diffstat (limited to 'src')
-rw-r--r--src/ContractionState.cxx7
-rw-r--r--src/ContractionState.h1
-rw-r--r--src/Editor.cxx34
-rw-r--r--src/Editor.h8
4 files changed, 46 insertions, 4 deletions
diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx
index b36e1ebd8..8f0f795e2 100644
--- a/src/ContractionState.cxx
+++ b/src/ContractionState.cxx
@@ -65,6 +65,7 @@ public:
Sci::Line LinesInDoc() const noexcept override;
Sci::Line LinesDisplayed() const noexcept override;
Sci::Line DisplayFromDoc(Sci::Line lineDoc) const noexcept override;
+ Sci::Line DisplayFromDocSub(Sci::Line lineDoc, Sci::Line lineSub) const noexcept override;
Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const noexcept override;
Sci::Line DocFromDisplay(Sci::Line lineDisplay) const noexcept override;
@@ -184,6 +185,12 @@ Sci::Line ContractionState<LINE>::DisplayFromDoc(Sci::Line lineDoc) const noexce
}
template <typename LINE>
+Sci::Line ContractionState<LINE>::DisplayFromDocSub(Sci::Line lineDoc, Sci::Line lineSub) const noexcept {
+ return DisplayFromDoc(lineDoc) +
+ std::min(lineSub, static_cast<Sci::Line>(GetHeight(lineDoc) - 1));
+}
+
+template <typename LINE>
Sci::Line ContractionState<LINE>::DisplayLastFromDoc(Sci::Line lineDoc) const noexcept {
return DisplayFromDoc(lineDoc) + GetHeight(lineDoc) - 1;
}
diff --git a/src/ContractionState.h b/src/ContractionState.h
index ae753f8d1..a144364d0 100644
--- a/src/ContractionState.h
+++ b/src/ContractionState.h
@@ -21,6 +21,7 @@ public:
virtual Sci::Line LinesInDoc() const noexcept=0;
virtual Sci::Line LinesDisplayed() const noexcept=0;
virtual Sci::Line DisplayFromDoc(Sci::Line lineDoc) const noexcept=0;
+ virtual Sci::Line DisplayFromDocSub(Sci::Line lineDoc, Sci::Line lineSub) const noexcept=0;
virtual Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const noexcept=0;
virtual Sci::Line DocFromDisplay(Sci::Line lineDisplay) const noexcept=0;
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 4c35093db..8bc5d036a 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -202,6 +202,8 @@ Editor::Editor() : durationWrapOneByte(0.000001, 0.00000001, 0.00001) {
recordingMacro = false;
foldAutomatic = AutomaticFold::None;
+ insideWrapScroll = false;
+
convertPastes = true;
SetRepresentations();
@@ -1679,8 +1681,15 @@ bool Editor::WrapLines(WrapScope ws) {
// Decide where to start wrapping
Sci::Line lineToWrap = wrapPending.start;
Sci::Line lineToWrapEnd = std::min(wrapPending.end, pdoc->LinesTotal());
+
const Sci::Line lineDocTop = pcs->DocFromDisplay(topLine);
- const Sci::Line subLineTop = topLine - pcs->DisplayFromDoc(lineDocTop);
+ LineDocSub lineScrollTo;
+ if (scrollToAfterWrap) {
+ lineScrollTo = scrollToAfterWrap.value();
+ } else {
+ const Sci::Line subLineTop = topLine - pcs->DisplayFromDoc(lineDocTop);
+ lineScrollTo = { lineDocTop, subLineTop };
+ }
if (ws == WrapScope::wsVisible) {
lineToWrap = std::clamp(lineDocTop-5, wrapPending.start, pdoc->LinesTotal());
// Priority wrap to just after visible area.
@@ -1731,21 +1740,23 @@ bool Editor::WrapLines(WrapScope ws) {
wrapOccurred = WrapBlock(surface, lineToWrap, lineToWrapEnd);
- goodTopLine = pcs->DisplayFromDoc(lineDocTop) + std::min(
- subLineTop, static_cast<Sci::Line>(pcs->GetHeight(lineDocTop)-1));
+ goodTopLine = pcs->DisplayFromDocSub(lineScrollTo.lineDoc, lineScrollTo.subLine);
}
}
// If wrapping is done, bring it to resting position
if (wrapPending.start >= lineEndNeedWrap) {
wrapPending.Reset();
+ scrollToAfterWrap.reset();
}
}
if (wrapOccurred) {
+ insideWrapScroll = true;
SetScrollBars();
SetTopLine(std::clamp<Sci::Line>(goodTopLine, 0, MaxScrollPos()));
SetVerticalScrollPos();
+ insideWrapScroll = false;
}
return wrapOccurred;
@@ -1985,6 +1996,12 @@ long Editor::TextWidth(uptr_t style, const char *text) {
return 1;
}
+void Editor::SetVerticalScrollPos() {
+ if (!insideWrapScroll) {
+ scrollToAfterWrap.reset();
+ }
+}
+
// Empty method is overridden on GTK+ to show / hide scrollbars
void Editor::ReconfigureScrollBars() {}
@@ -5540,6 +5557,8 @@ void Editor::SetDocPointer(Document *document) {
SetRepresentations();
+ scrollToAfterWrap.reset();
+
// Reset the contraction state to fully shown.
pcs->Clear();
pcs->InsertLines(0, pdoc->LinesTotal() - 1);
@@ -6549,6 +6568,15 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
HorizontalScrollTo(xOffset + static_cast<int>(static_cast<int>(wParam) * vs.spaceWidth));
return 1;
+ case Message::ScrollVertical:
+ if (Wrapping()) {
+ scrollToAfterWrap = { LineFromUPtr(wParam), lParam };
+ } else {
+ scrollToAfterWrap.reset();
+ }
+ ScrollTo(pcs->DisplayFromDocSub(LineFromUPtr(wParam), lParam));
+ break;
+
case Message::SetXOffset:
xOffset = static_cast<int>(wParam);
ContainerNeedsUpdate(Update::HScroll);
diff --git a/src/Editor.h b/src/Editor.h
index 46879cdc4..f8bc18970 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -283,6 +283,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
// Wrapping support
WrapPending wrapPending;
ActionDuration durationWrapOneByte;
+ bool insideWrapScroll;
+ struct LineDocSub {
+ Scintilla::Line lineDoc = 0;
+ Scintilla::Line subLine = 0;
+ };
+ std::optional<LineDocSub> scrollToAfterWrap;
bool convertPastes;
@@ -417,7 +423,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
Sci::Position FormatRange(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
long TextWidth(Scintilla::uptr_t style, const char *text);
- virtual void SetVerticalScrollPos() = 0;
+ virtual void SetVerticalScrollPos();
virtual void SetHorizontalScrollPos() = 0;
virtual bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) = 0;
virtual void ReconfigureScrollBars();