changed inner scroll a bit

This commit is contained in:
2026-06-14 13:34:29 -06:00
parent da7c9ef3db
commit f7f6864666
2 changed files with 33 additions and 22 deletions
+32 -21
View File
@@ -5,53 +5,64 @@
namespace ckitty::terminal { namespace ckitty::terminal {
InnerScroll::InnerScroll(pos p, int w, int h, Content& c) InnerScroll::InnerScroll(pos p, int w, int h, Content& c)
: position(p), width(w), height(h), _content(c) { : position(p), width(w), height(h), rowY(0), scrollY(0), _content(c) {
} }
void InnerScroll::scroll(int delta) { void InnerScroll::scroll(int delta) {
int maxScroll = std::max(0, _content.getTotalHeight() - height); int totalH = _content.getTotalHeight();
scrollY = std::clamp(scrollY + delta, 0, maxScroll); int viewH = height;
if (totalH == 0) return;
// 1. Update and clamp the cursor position within absolute content bounds
rowY = std::clamp(rowY + delta, 0, std::max(0, totalH - 1));
// 2. Adjust scrollY to keep rowY visible
// Case A: Cursor moved above the top of the viewport
if (rowY < scrollY) {
scrollY = rowY;
}
// Case B: Cursor moved below the bottom of the viewport
else if (rowY >= scrollY + viewH) {
scrollY = rowY - viewH + 1;
}
// 3. Final safety clamp for scrollY
int maxScroll = std::max(0, totalH - viewH);
scrollY = std::clamp(scrollY, 0, maxScroll);
} }
void InnerScroll::render(Terminal& t) const { void InnerScroll::render(Terminal& t) const {
int totalH = _content.getTotalHeight(); int totalH = _content.getTotalHeight();
int viewH = height; int viewH = height;
int contentWidth = width - 1; // Last column reserved for scrollbar int contentWidth = width - 1; // Last column reserved for scrollbar
int scrollX = position.x + width - 1;
// 1. Render the Content Viewport // draw content
// We only ask content to draw what fits in our height
int start = scrollY; int start = scrollY;
int end = std::min(totalH, scrollY + viewH); int end = std::min(totalH, scrollY + viewH);
_content.render(t, position, pos(contentWidth, height), { start, end }); _content.render(t, position, pos(contentWidth, height), { start, end });
// 2. Clear empty space if content is shorter than viewport // 3. Render Scrollbar Track First
if (end - start < viewH) { t << style::RESET << trackColor;
for (int y = (end - start); y < viewH; ++y) {
t << pos{ position.x, position.y + y }
<< std::string(std::size_t(contentWidth), ' ');
}
}
// 3. Render Scrollbar Track
int scrollX = position.x + width - 1;
t << trackColor;
for (int y = 0; y < viewH; ++y) { for (int y = 0; y < viewH; ++y) {
t << pos{ scrollX, position.y + y } << ""; t << pos(scrollX, position.y + y) << "";
} }
// 4. Render Scrollbar Thumb // 4. Render Scrollbar Thumb Over the Track
if (totalH > viewH) { if (totalH > viewH) {
// Calculate thumb height (proportional to visibility) // Calculate thumb height (proportional to visibility)
int thumbH = std::max(1, (viewH * viewH) / totalH); int thumbH = std::max(1, (viewH * viewH) / totalH);
// Calculate thumb position // Calculate thumb position safely
float scrollPercent = float(scrollY) / float(totalH - viewH); float scrollPercent = float(scrollY) / float(totalH - viewH);
int thumbPos = int(scrollPercent * float(viewH - thumbH)); int thumbPos = int(scrollPercent * float(viewH - thumbH));
// Clamp thumbPos to ensure it stays within the track bounds
thumbPos = std::clamp(thumbPos, 0, viewH - thumbH);
t << thumbColor; t << thumbColor;
for (int y = 0; y < thumbH; ++y) { for (int y = 0; y < thumbH; ++y) {
t << pos{ scrollX, position.y + thumbPos + y } << ""; t << pos(scrollX, position.y + thumbPos + y) << "";
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@ namespace ckitty::terminal {
pos position; pos position;
int width, height; int width, height;
int scrollY = 0; // The top-most visible row of the content int rowY, scrollY;
// Styling // Styling
color trackColor = color::B_BLACK; color trackColor = color::B_BLACK;