From 3a9784d0c8a50103936580a3cc16f2452b2fb34a Mon Sep 17 00:00:00 2001 From: Grant Horner Date: Tue, 21 Apr 2026 16:01:48 -0400 Subject: [PATCH] initial commit --- .gitignore | 3 ++ edit.jai | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 .gitignore create mode 100644 edit.jai diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80cab65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +edit +*.ttf +.build diff --git a/edit.jai b/edit.jai new file mode 100644 index 0000000..4ee8517 --- /dev/null +++ b/edit.jai @@ -0,0 +1,148 @@ +FPS :: 60; +MS_PER_FRAME :: 1000 / FPS; + +buffer: string; +lines: [..]String_Builder; +line_height: int; + +my_font: *Simp.Dynamic_Font; + +window_width := 800; +window_height := 600; + +first_line := 0; + +main :: () { + args := get_command_line_arguments(); + assert(args.count == 2, "The file name must be passed as a CLI argument"); + + + window_name := ifx args.count == 1 then "edit" else args[1]; + window := create_window(window_width, window_height, window_name); + + my_init_fonts(); + + Simp.set_render_target(window); + + should_quit := false; + prev := get_time(); + + assert(read_file_lines(args[1]), "Must be able to read file!"); + + while !should_quit { + reset_temporary_storage(); + + now := get_time(); + dt := now - prev; + prev = now; + + Input.update_window_events(); + + for event : Input.events_this_frame { + if event.type == .QUIT { + should_quit = true; + break; + } + + if event.type == .KEYBOARD && event.key_pressed { + if event.key_code == { + case .ESCAPE; should_quit = true; + } + } + } + + Simp.clear_render_target(.0, .0, .0, 1); + + render_edit_buffer(); + + Simp.swap_buffers(window); + + now = get_time(); + if now - prev < MS_PER_FRAME { + sleep_milliseconds(xx (now - prev)); + } + } +} + +render_edit_buffer :: () { + num_lines_in_screen := window_height / line_height - 1; + viewable_lines := array_view(lines, first_line, num_lines_in_screen); + Simp.set_shader_for_text(); + color :: Vector4.{1, 1, 1, 1}; + for line_buffer: viewable_lines { + + line := builder_to_line(*line_buffer); + + Simp.prepare_text(my_font, line); + Simp.draw_prepared_text(my_font, 5, window_height - (it_index + 1) * line_height, color); + } +} + +builder_to_line :: (using builder: *String_Builder) -> string { + result_builder: String_Builder; + result_builder.allocator = temporary_allocator; + + builder_str := builder_to_string(builder, do_reset = false,, temp); + + start := 0; + for c: builder_str { + if c == #char "\t" { + s := string.{data=builder_str.data + start, count=(it_index + 1) - start}; + append(*result_builder, s); + start = it_index + 1; + } + } + + s := string.{data=builder_str.data + start, count=builder_str.count - start}; + append(*result_builder, s); + + return builder_to_string(*result_builder,, temp); +} + +get_time :: () -> s64 { + val, ok := to_milliseconds(current_time_monotonic()); + assert(ok, "Must be able to convert from apollo to milliseconds"); + return val; +} + +read_file_lines :: (file_path: string) -> bool { + file_contents, ok := read_entire_file(file_path); + if !ok return ok; + + for lines reset(*it); + free(lines.data); + lines = [..]String_Builder.{}; + + lines_temp := split(file_contents, "\n"); + defer free(lines_temp.data); + + for line: lines_temp { + builder: String_Builder; + init_string_builder(*builder); + append(*builder, line); + array_add(*lines, builder); + } + + return ok; +} + +my_init_fonts :: () { + line_height = 16; + base_path := path_strip_filename(get_path_of_running_executable()); + print("base_path: %\n", base_path); + + my_font = Simp.get_font_at_size("/home/grant/.local/share/fonts/otf/BerkeleyMono/", "BerkeleyMono-Regular.otf", line_height); + // my_font = Simp.get_font_at_size(base_path, "Anonymous Pro.ttf", line_height); + assert(my_font != null); +} + +#import "Basic"; +#import "File"; +#import "Math"; +#import "String"; +#import "System"; +#import "Window_Creation"; + +Input :: #import "Input"; +Simp :: #import "Simp"; +