210 lines
5.4 KiB
Plaintext
210 lines
5.4 KiB
Plaintext
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;
|
|
|
|
cursor_x := 0;
|
|
cursor_y := 0;
|
|
|
|
White :: Vector4.{1, 1, 1, 1};
|
|
|
|
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();
|
|
|
|
handle_window_resizes(window);
|
|
|
|
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;
|
|
|
|
case .ARROW_UP; #through;
|
|
case .ARROW_DOWN; #through;
|
|
case .ARROW_LEFT; #through;
|
|
case .ARROW_RIGHT; handle_arrow(event.key_code);
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
for line_buffer: viewable_lines {
|
|
Simp.set_shader_for_text();
|
|
|
|
line := builder_to_line(*line_buffer);
|
|
|
|
Simp.prepare_text(my_font, line);
|
|
top_of_line := window_height - (it_index + 1) * line_height;
|
|
Simp.draw_prepared_text(my_font, 5, top_of_line, White);
|
|
|
|
if it_index == cursor_y {
|
|
Simp.set_shader_for_color();
|
|
Simp.immediate_quad(
|
|
5., cast(float) top_of_line + line_height,
|
|
6., cast(float) top_of_line,
|
|
White);
|
|
}
|
|
}
|
|
}
|
|
|
|
handle_window_resizes :: (window: Window_Type) {
|
|
for Input.get_window_resizes() {
|
|
Simp.update_window(it.window);
|
|
if it.window == window {
|
|
should_reinit := (it.width != window_width) || (it.height != window_height);
|
|
|
|
window_width = it.width;
|
|
window_height = it.height;
|
|
|
|
if should_reinit {
|
|
my_init_fonts();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
handle_arrow :: (key_code: Input.Key_Code) {
|
|
num_lines_in_screen := window_height / line_height - 1;
|
|
viewable_lines := array_view(lines, first_line, num_lines_in_screen);
|
|
|
|
max_chars := 30;
|
|
|
|
if key_code == {
|
|
case .ARROW_UP;
|
|
cursor_y = ifx cursor_y == 0
|
|
then 0
|
|
else cursor_y - 1;
|
|
case .ARROW_DOWN;
|
|
cursor_y = ifx cursor_y == viewable_lines.count
|
|
then viewable_lines.count
|
|
else cursor_y + 1;
|
|
case .ARROW_LEFT;
|
|
cursor_x = ifx cursor_x == 0
|
|
then 0
|
|
else cursor_x - 1;
|
|
case .ARROW_RIGHT;
|
|
cursor_y = ifx cursor_x == max_chars
|
|
then max_chars
|
|
else cursor_x + 1;
|
|
}
|
|
}
|
|
|
|
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());
|
|
|
|
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";
|
|
|