hook up scrolling, kind of works, kind of broke

This commit is contained in:
Mitchell Hashimoto
2022-07-10 17:04:19 -07:00
parent 67d6114202
commit f602d09d5d
3 changed files with 51 additions and 32 deletions

View File

@ -250,6 +250,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
window.setKeyCallback(keyCallback);
window.setFocusCallback(focusCallback);
window.setRefreshCallback(refreshCallback);
window.setScrollCallback(scrollCallback);
return self;
}
@ -505,6 +506,24 @@ fn refreshCallback(window: glfw.Window) void {
win.render_timer.schedule() catch unreachable;
}
fn scrollCallback(window: glfw.Window, xoff: f64, yoff: f64) void {
const win = window.getUserPointer(Window) orelse return;
//log.info("SCROLL: {} {}", .{ xoff, yoff });
_ = xoff;
// Positive is up
const sign: isize = if (yoff < 0) -1 else 1;
const delta: isize = sign * @maximum(@divFloor(win.grid.size.rows, 15), 1);
log.info("scroll: delta={}", .{delta});
win.terminal.scrollViewport(.{ .delta = delta });
// Schedule render since scrolling usually does something.
// TODO(perf): we can only schedule render if we know scrolling
// did something
win.render_timer.schedule() catch unreachable;
}
fn cursorTimerCallback(t: *libuv.Timer) void {
const tracy = trace(@src());
defer tracy.end();

View File

@ -187,12 +187,25 @@ pub fn scroll(self: *Screen, behavior: Scroll) void {
.bottom => self.visible_offset = self.bottom - self.rows,
// TODO: deltas greater than the entire scrollback
.delta => |delta| self.scrollDown(delta, true),
.delta_no_grow => |delta| self.scrollDown(delta, false),
.delta => |delta| self.scrollDelta(delta, true),
.delta_no_grow => |delta| self.scrollDelta(delta, false),
}
}
fn scrollDown(self: *Screen, delta: isize, grow: bool) void {
fn scrollDelta(self: *Screen, delta: isize, grow: bool) void {
log.info("offsets before: top={} bottom={} visible={}", .{
self.top,
self.bottom,
self.visible_offset,
});
defer {
log.info("offsets after: top={} bottom={} visible={}", .{
self.top,
self.bottom,
self.visible_offset,
});
}
// If we're scrolling up, then we just subtract and we're done.
if (delta < 0) {
self.visible_offset -|= @intCast(usize, -delta);
@ -255,22 +268,6 @@ fn scrollDown(self: *Screen, delta: isize, grow: bool) void {
self.visible_offset -= rows_overlapped;
}
/// Scroll the screen up (positive) or down (negative). Scrolling direction
/// is the direction text would move. For example, scrolling down would
/// move existing text downward.
pub fn scrollOld(self: *Screen, count: isize) void {
if (count < 0) {
const amount = @mod(@intCast(usize, -count), self.rows);
if (amount > self.top) {
self.top = self.rows - amount;
} else {
self.top -|= amount;
}
} else {
self.top = @mod(self.top + @intCast(usize, count), self.rows);
}
}
/// Copy row at src to dst.
pub fn copyRow(self: *Screen, dst: usize, src: usize) void {
const src_row = self.getRow(src);
@ -289,7 +286,7 @@ pub fn resize(self: *Screen, alloc: Allocator, rows: usize, cols: usize) !void {
const old = self.*;
// Reallocate the storage
self.storage = try alloc.alloc(Cell, rows * cols);
self.storage = try alloc.alloc(Cell, (rows + self.max_scrollback) * cols);
self.top = 0;
self.bottom = rows - 1;
self.rows = rows;

View File

@ -73,7 +73,8 @@ pub fn init(alloc: Allocator, cols: usize, rows: usize) !Terminal {
return Terminal{
.cols = cols,
.rows = rows,
.screen = try Screen.init(alloc, rows, cols, 0),
// TODO: configurable scrollback
.screen = try Screen.init(alloc, rows, cols, 1000),
.cursor = .{},
.saved_cursor = .{},
.tabstops = try Tabstops.init(alloc, cols, TABSTOP_INTERVAL),
@ -276,7 +277,7 @@ pub fn index(self: *Terminal) void {
if (self.cursor.y < self.scrolling_region.top or
self.cursor.y > self.scrolling_region.bottom) return;
self.scrollUp();
self.screen.scroll(.{ .delta = 1 });
return;
}
@ -673,16 +674,6 @@ pub fn deleteLines(self: *Terminal, count: usize) void {
}
}
/// Scroll the text up by one row.
pub fn scrollUp(self: *Terminal) void {
const tracy = trace(@src());
defer tracy.end();
self.screen.scroll(.{ .delta = 1 });
const last = self.screen.getRow(self.rows - 1);
for (last) |*cell| cell.char = 0;
}
/// Scroll the text down by one row.
/// TODO: test
pub fn scrollDown(self: *Terminal, count: usize) void {
@ -698,6 +689,18 @@ pub fn scrollDown(self: *Terminal, count: usize) void {
self.insertLines(count);
}
/// Options for scrolling the viewport of the terminal grid.
pub const ScrollViewport = union(enum) {
delta: isize,
};
/// Scroll the viewport of the terminal grid.
pub fn scrollViewport(self: *Terminal, behavior: ScrollViewport) void {
self.screen.scroll(switch (behavior) {
.delta => |delta| .{ .delta_no_grow = delta },
});
}
/// Set Top and Bottom Margins If bottom is not specified, 0 or bigger than
/// the number of the bottom-most row, it is adjusted to the number of the
/// bottom most row.