Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

fix: content scrolling so it stops at bottom of viewable area instead… #29

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

s9tpepper
Copy link

… of at the top.

Before fix the content would scroll on the last page to the top of the viewable area, leaving a large blank space on the last page. This fixes the scrolling so the bottom of the last page stops at the bottom of the viewable area. Adjustment is made to the scrollbar thumb so it stops at the bottom of the scroll track.

Copy link
Owner

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add unit tests (similar to the ones below) and doc comments that talk about how this works (and which will show up in the docs.rs page).

If you write the tests first, this should be able to confirm that the simplification is the same as what you had (I'm not 100% sure it is).

Comment on lines 120 to 129
let max_y_offset = self.size.height - area.height;
let next_y_offset = y.min(self.buf.area.height.saturating_sub(1));
let y_offset = if next_y_offset > max_y_offset {
max_y_offset
} else {
next_y_offset
};

x = x.min(self.buf.area.width.saturating_sub(1));
y = y.min(self.buf.area.height.saturating_sub(1));
y = y.min(y_offset);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this can be simplified to:

let min_height = area.height.min(1); // show at least one row
let max_offset = self.size.height.saturating_sub(min_height);
y = y.min(max_offset);

@joshka
Copy link
Owner

joshka commented Apr 25, 2024

#30 changes the implementation a bunch, so I'm going to redo this and credit you for the fix.

@s9tpepper
Copy link
Author

Ok sounds good! I was trying to add a test to try the simplification but I couldn’t figure out how to get the scroll thumb to size correctly, it kept drawing two cells tall instead of one.

@s9tpepper
Copy link
Author

I merged the latest changes to my fork and I added a scroll_to_bottom test to verify the changes that I am proposing.

I also added a fixture that prints the row numbers to make it easier to verify that the scroll position is at the right location.

I simplified the logic around the y position that I updated and I cleaned up some messages that Clippy was complaining about.

Let me know what you think.

@joshka
Copy link
Owner

joshka commented May 6, 2024

Hey there, it might be some time before I respond to this, but I will get back to it as soon as I can.

@TerakomariGandesblood
Copy link

Any updates?

Copy link
Owner

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I just took a look - thanks for reminding me to come back to this.

I merged main into your branch and added some more tests. This now uses the following more convenient test data (which makes it easier to see when there's problems with both rows and columns):

/// a0a1a2a3a4
/// b0b1b2b3b4
/// c0c1c2c3c4
/// d0d1d2d3d4
/// e0e1e2e3e4
/// f0f1f2f3f4
/// g0g1g2g3g4
/// h0h1h2h3h4
/// i0i1i2i3i4
/// j0j1j2j3j4

It works fine when you don't have a horizontal scrollbar:

"f0f1f2f3f4▲",
"g0g1g2g3g4║",
"h0h1h2h3h4█",
"i0i1i2i3i4█",
"j0j1j2j3j4▼",

But fails when you do have a horizontal scrollbar (the last row is never shown):

"f0f1f▲",
"g0g1g║",
"h0h1h█",
"i0i1i█",
"j0j1j▼",
"◄█══► ",

This also should handle scrolling to the right as well.

"2a3a4▲",
"2b3b4█",
"2c3c4█",
"2d3d4║",
"2e3e4▼",
"◄═█═► ",

Note the failing tests likely have the wrong scrollbar positions, but the visible data should likely be correct. Hopefully the tests should guide you towards the right solution here.

x = x.min(self.buf.area.width.saturating_sub(1));
y = y.min(self.buf.area.height.saturating_sub(1));
y = y.min(min(next_y_offset, max_y_offset));
Copy link
Owner

@joshka joshka Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit convoluted y.min(min(a calculation with min from above)). I'd suggest finding a way to make this simple. Don't intersperse x and y here, but instead do x and then y, and perhaps find a way to either simplify the logic into a single expression, or a set of chained assignments (y = ...; y = ...; y = ...;)

// ensure that we don't scroll past the end of the buffer in either direction
// also, ensure that the scrolling stops with the end of the content at the
// bottom of the visible area
let max_y_offset = self.buf.area.height.saturating_sub(area.height);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to a saturating sub as one of the tests was panicking due to underflow here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants