can insert and remove characters
This commit is contained in:
78
edit.jai
78
edit.jai
@@ -2,7 +2,7 @@ FPS :: 60;
|
||||
MS_PER_FRAME :: 1000 / FPS;
|
||||
|
||||
buffer: string;
|
||||
lines: [..]String_Builder;
|
||||
lines: [..][..]u8;
|
||||
line_height: int;
|
||||
|
||||
my_font: *Simp.Dynamic_Font;
|
||||
@@ -55,11 +55,21 @@ main :: () {
|
||||
if event.key_code == {
|
||||
case .ESCAPE; should_quit = true;
|
||||
|
||||
case .BACKSPACE; handle_backspace();
|
||||
|
||||
case .ARROW_UP; #through;
|
||||
case .ARROW_DOWN; #through;
|
||||
case .ARROW_LEFT; #through;
|
||||
case .ARROW_RIGHT; handle_arrow(event.key_code);
|
||||
}
|
||||
|
||||
if #char "A" <= event.key_code && event.key_code <= #char "z" {
|
||||
key := event.key_code;
|
||||
if !event.shift_pressed {
|
||||
key += #char "a" - #char "A";
|
||||
}
|
||||
insert_character_at_cursor(cast(u8) key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +91,7 @@ render_edit_buffer :: () {
|
||||
for line_buffer: visible_lines {
|
||||
Simp.set_shader_for_text();
|
||||
|
||||
line_str := tbuilder_to_string(*line_buffer);
|
||||
line_str := array_view_to_string(line_buffer);
|
||||
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
@@ -116,6 +126,12 @@ render_edit_buffer :: () {
|
||||
}
|
||||
}
|
||||
|
||||
insert_character_at_cursor :: (char: u8) {
|
||||
line := *get_visible_lines()[cursor_y];
|
||||
array_insert_at(line, char, cursor_x);
|
||||
cursor_x += 1;
|
||||
}
|
||||
|
||||
handle_window_resizes :: (window: Window_Type) {
|
||||
for Input.get_window_resizes() {
|
||||
Simp.update_window(it.window);
|
||||
@@ -132,6 +148,26 @@ handle_window_resizes :: (window: Window_Type) {
|
||||
}
|
||||
}
|
||||
|
||||
handle_backspace :: () {
|
||||
if cursor_x == 0 && cursor_y == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor_line_index := cursor_y + first_line;
|
||||
current_line := *lines[cursor_line_index];
|
||||
if cursor_x == 0 {
|
||||
prev_line := *lines[cursor_line_index - 1];
|
||||
prev_count := prev_line.count;
|
||||
array_add(prev_line, current_line.*);
|
||||
array_remove_at(*lines, cursor_line_index);
|
||||
cursor_y -= 1;
|
||||
cursor_x = prev_count;
|
||||
} else {
|
||||
array_remove_at(current_line, cursor_x - 1);
|
||||
cursor_x -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
handle_arrow :: (key_code: Input.Key_Code) {
|
||||
visible_lines := get_visible_lines();
|
||||
|
||||
@@ -148,7 +184,7 @@ handle_arrow :: (key_code: Input.Key_Code) {
|
||||
case .ARROW_LEFT;
|
||||
if cursor_x == 0 && cursor_y != 0 {
|
||||
prev_line := visible_lines[cursor_y - 1];
|
||||
len := builder_string_length(*prev_line);
|
||||
len := prev_line.count;
|
||||
cursor_y = max(0, cursor_y - 1);
|
||||
cursor_x = len;
|
||||
} else if cursor_x != 0 {
|
||||
@@ -156,7 +192,7 @@ handle_arrow :: (key_code: Input.Key_Code) {
|
||||
}
|
||||
case .ARROW_RIGHT;
|
||||
line := visible_lines[cursor_y];
|
||||
len := builder_string_length(*line);
|
||||
len := line.count;
|
||||
if cursor_x == len {
|
||||
cursor_x = 0;
|
||||
cursor_y += 1;
|
||||
@@ -166,7 +202,7 @@ handle_arrow :: (key_code: Input.Key_Code) {
|
||||
}
|
||||
}
|
||||
|
||||
get_visible_lines :: () -> []String_Builder {
|
||||
get_visible_lines :: () -> [][..]u8 {
|
||||
num_lines_in_screen := window_height / line_height - 1;
|
||||
return array_view(lines, first_line, num_lines_in_screen);
|
||||
}
|
||||
@@ -192,11 +228,13 @@ string_to_line :: (str: string, cursor_char_index := -1) -> string, string {
|
||||
c := str.data[char_index];
|
||||
|
||||
if c == #char "\t" {
|
||||
|
||||
// s := string.{data=str.data + start, count=(char_index + 1) - start};
|
||||
// append(current_builder, s);
|
||||
// append(current_builder, " ");
|
||||
// start = char_index + 1;
|
||||
// cursor_index += 4;
|
||||
|
||||
} else {
|
||||
cursor_index += 1;
|
||||
}
|
||||
@@ -229,17 +267,16 @@ read_file_lines :: (file_path: string) -> bool {
|
||||
file_contents, ok := read_entire_file(file_path);
|
||||
if !ok return ok;
|
||||
|
||||
for lines reset(*it);
|
||||
for lines free(*it);
|
||||
free(lines.data);
|
||||
lines = [..]String_Builder.{};
|
||||
lines = [..][..]u8.{};
|
||||
|
||||
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);
|
||||
builder: [..]u8;
|
||||
array_add(*builder, array_view(line));
|
||||
array_add(*lines, builder);
|
||||
}
|
||||
|
||||
@@ -255,9 +292,24 @@ my_init_fonts :: () {
|
||||
assert(my_font != null);
|
||||
}
|
||||
|
||||
tbuilder_to_string :: (builder: *String_Builder) -> string {
|
||||
s := builder_to_string(builder, do_reset = false,, temp);
|
||||
return s;
|
||||
array_add :: (xs: *[..]$T, to_append: []T) {
|
||||
array_reserve(xs, xs.count + to_append.count);
|
||||
|
||||
memcpy(xs.data + xs.count, to_append.data, to_append.count * size_of(T));
|
||||
xs.count += to_append.count;
|
||||
}
|
||||
|
||||
array_view :: (s: string) -> []u8 {
|
||||
return []u8.{count=s.count, data=s.data};
|
||||
}
|
||||
|
||||
array_view_to_string :: (chars: []u8) -> string {
|
||||
return string.{count=chars.count, data=chars.data};
|
||||
}
|
||||
|
||||
array_remove_at :: (xs: *[..]$T, index: int) {
|
||||
xs.count -= 1;
|
||||
memcpy(xs.data + index, xs.data + index + 1, xs.count - index);
|
||||
}
|
||||
|
||||
#import "Basic";
|
||||
|
||||
Reference in New Issue
Block a user