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 {
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) {
int maxScroll = std::max(0, _content.getTotalHeight() - height);
scrollY = std::clamp(scrollY + delta, 0, maxScroll);
int totalH = _content.getTotalHeight();
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 {
int totalH = _content.getTotalHeight();
int viewH = height;
int contentWidth = width - 1; // Last column reserved for scrollbar
int scrollX = position.x + width - 1;
// 1. Render the Content Viewport
// We only ask content to draw what fits in our height
// draw content
int start = scrollY;
int end = std::min(totalH, scrollY + viewH);
_content.render(t, position, pos(contentWidth, height), { start, end });
// 2. Clear empty space if content is shorter than viewport
if (end - start < viewH) {
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;
// 3. Render Scrollbar Track First
t << style::RESET << trackColor;
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) {
// Calculate thumb height (proportional to visibility)
int thumbH = std::max(1, (viewH * viewH) / totalH);
// Calculate thumb position
// Calculate thumb position safely
float scrollPercent = float(scrollY) / float(totalH - viewH);
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;
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;
int width, height;
int scrollY = 0; // The top-most visible row of the content
int rowY, scrollY;
// Styling
color trackColor = color::B_BLACK;