diff --git a/.gitignore b/.gitignore index e425fab..dfccedf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ bin *.dylib .DS_Store src/src +scratch diff --git a/src/main.odin b/src/main.odin index d48f712..65905e0 100644 --- a/src/main.odin +++ b/src/main.odin @@ -1,5 +1,5 @@ /* -- TODO implement movement up and down by paragraph +- DONE implement movement up and down by paragraph - TODO implement scrolling/viewport - TODO implement deletion by word - TODO implement selection @@ -27,18 +27,27 @@ read_file :: proc(path: string) -> (string, bool) { return string(content), success } +Viewport :: struct { + start: int, + end: int, +} + Cursor :: struct { line: int, char: int, } +window_width := 800 +window_height := 600 font_size: f32 = 20.0 text_height: f32 cursor: Cursor lines: [dynamic][dynamic]u8 +viewport_size := window_height / int(font_size) +viewport := Viewport{start = 0, end = viewport_size} main :: proc() { - r.InitWindow(800, 600, "odit") + r.InitWindow(i32(window_width), i32(window_height), "odit") r.SetTargetFPS(60) font := r.LoadFont("/Users/grant/Library/Fonts/BerkeleyMono-Regular.otf") r.GuiSetFont(font) @@ -139,7 +148,7 @@ main :: proc() { } } - cursor.line = min(preferred_line, len(lines)) + cursor.line = min(preferred_line, len(lines) - 1) if len(current_line()) < cursor.char { cursor.char = len(current_line()) } @@ -186,10 +195,24 @@ main :: proc() { } } + cursor_padding := 3 + // move viewport up + if cursor.line < viewport.start + cursor_padding { + diff := (cursor.line - viewport.start) - cursor_padding + viewport.start = min(max(0, viewport.start + diff), len(lines) - viewport_size) + viewport.end = min(max(viewport_size, viewport.end + diff), len(lines)) + } + // move viewport down + if viewport.end - cursor_padding < cursor.line { + diff := cursor.line - (viewport.end - cursor_padding) + viewport.start = min(max(0, viewport.start + diff), len(lines) - viewport_size) + viewport.end = min(max(viewport_size, viewport.end + diff), len(lines)) + } + r.BeginDrawing() r.ClearBackground(r.BLACK) - for &line, line_index in lines { + for &line, line_index in lines[viewport.start:viewport.end] { if cap(line) == 0 { reserve(&line, 1) } @@ -216,9 +239,9 @@ main :: proc() { render_cursor :: proc(cursor: ^Cursor) { x := cursor.char * int(font_size / 2) - y := i32(font_size) * i32(cursor.line) - r.DrawLine(i32(x), y, i32(x), y + i32(text_height), r.WHITE) - r.DrawLine(i32(x) + 1, y, i32(x) + 1, y + i32(text_height), r.WHITE) + y := i32(font_size) * i32(cursor.line - viewport.start) + r.DrawLine(i32(x), y, i32(x), y + i32(font_size), r.WHITE) + r.DrawLine(i32(x) + 1, y, i32(x) + 1, y + i32(font_size), r.WHITE) } current_line :: proc() -> ^[dynamic]u8 {