changed inner scroll a bit
This commit is contained in:
@@ -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) << "█";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user