From 921928e96fb674b0026bca920f254b5c99cea83c Mon Sep 17 00:00:00 2001 From: Grant Horner Date: Tue, 9 Dec 2025 18:44:01 -0500 Subject: [PATCH] factored out procedure for rendering selected lines --- src/main.odin | 142 +++++++++++++++++++++++++++++++------------------- 1 file changed, 89 insertions(+), 53 deletions(-) diff --git a/src/main.odin b/src/main.odin index e9bf329..46917cc 100644 --- a/src/main.odin +++ b/src/main.odin @@ -32,17 +32,17 @@ Viewport :: struct { end: int, } -Cursor :: struct { +Position :: struct { line: int, char: int, } +Cursor :: distinct Position + Selection :: struct { - active: bool, - start_line: int, - end_line: int, - start_char: int, - end_char: int, + active: bool, + start: Position, + end: Position, } window_width := 800 @@ -168,48 +168,15 @@ main :: proc() { } raw_data(line)[len(line)] = 0 - if selection.active && - line_index == selection.start_line && - line_index == selection.end_line { - selection_begin := min(selection.start_char, selection.end_char) - selection_end := max(selection.start_char, selection.end_char) - prefix := line[:selection_begin] - suffix := line[selection_end + 1:] if selection_end + 1 < len(line) else []u8{} - // need to copy these into separate buffers for zero value - x: f32 = 0.0 - if len(prefix) != 0 { - cstr := strings.clone_to_cstring(string(prefix), context.temp_allocator) - measurements := r.MeasureTextEx(font, cstr, font_size, 0) - pos := r.Vector2{x, font_size * f32(line_index)} - r.DrawTextEx(font, cstr, pos, font_size, 0, r.WHITE) - x += measurements.x - } - - selected_str := string(line[selection_begin:selection_end + 1]) - cstr := - strings.clone_to_cstring(selected_str, context.temp_allocator) if len(suffix) != 0 else strings.unsafe_string_to_cstring(selected_str) - measurements := r.MeasureTextEx(font, cstr, font_size, 0) - pos := r.Vector2{x, font_size * f32(line_index)} - r.DrawRectangle( - i32(pos.x), - i32(pos.y), - i32(measurements.x), - i32(measurements.y), - r.WHITE, - ) - r.DrawTextEx(font, cstr, pos, font_size, 0, r.BLACK) - x += measurements.x - - if len(suffix) != 0 { - cstr := strings.unsafe_string_to_cstring(string(suffix)) - // cstr := strings.clone_to_cstring(string(suffix), context.temp_allocator) - pos := r.Vector2{x, font_size * f32(line_index)} - r.DrawTextEx(font, cstr, pos, font_size, 0, r.WHITE) - } - } else if selection.active && line_index == selection.start_line { - } else if selection.active && line_index == selection.end_line { - } else if selection.active && selection.start_line < line_index && line_index < selection.end_line { + line_index == selection.start.line && + line_index == selection.end.line { + render_line_with_selection(line[:], line_index, font) + } else if selection.active && line_index == selection.start.line { + } else if selection.active && line_index == selection.end.line { + } else if selection.active && + selection.start.line < line_index && + line_index < selection.end.line { } else { // No selection active cstr := strings.unsafe_string_to_cstring(string(line[:])) @@ -281,14 +248,83 @@ handle_selection_start :: proc() { return } if selection.active && was_active do return - selection.start_line = cursor.line - selection.start_char = cursor.char + selection.start.line = cursor.line + selection.start.char = cursor.char } handle_selection_end :: proc() { if !selection.active do return - selection.end_char = cursor.char - selection.end_line = cursor.line + selection.end.char = cursor.char + selection.end.line = cursor.line +} + +render_line_with_selection :: proc(line: []u8, line_index: int, font: r.Font) { + earliest: Position + latest: Position + if selection.start.line < selection.end.line { + // Started highlighting on a previous line, selecting downwards + earliest = selection.start + latest = selection.end + } else if selection.start.line > selection.end.line { + // Started highlighting on a later line, selecting upwards + earliest = selection.end + latest = selection.start + } else if selection.start.char < selection.end.char { + // Selection on one line, selecting rightwards + earliest = selection.start + latest = selection.end + } else { + // Selection on one line, selecting leftwards + earliest = selection.end + latest = selection.start + } + + selection_begin: int + selection_end: int + if line_index == earliest.line && line_index == latest.line { + selection_begin = min(selection.start.char, selection.end.char) + selection_end = max(selection.start.char, selection.end.char) + } else if line_index == earliest.line { + + } else if line_index == latest.line { + + } else if earliest.line < line_index && line_index < latest.line { + + } else { + + } + + prefix := line[:selection_begin] + suffix := line[selection_end:] if selection_end < len(line) else []u8{} + // need to copy these into separate buffers for zero value + x: f32 = 0.0 + if len(prefix) != 0 { + cstr := strings.clone_to_cstring(string(prefix), context.temp_allocator) + measurements := r.MeasureTextEx(font, cstr, font_size, 0) + pos := r.Vector2{x, font_size * f32(line_index)} + r.DrawTextEx(font, cstr, pos, font_size, 0, r.WHITE) + x += measurements.x + } + + selected_str: string + if selection_end < len(line) { + selected_str = string(line[selection_begin:selection_end]) + } else { + selected_str = string(line[selection_begin:]) + } + cstr := + strings.clone_to_cstring(selected_str, context.temp_allocator) if len(suffix) != 0 else strings.unsafe_string_to_cstring(selected_str) + measurements := r.MeasureTextEx(font, cstr, font_size, 0) + pos := r.Vector2{x, font_size * f32(line_index)} + r.DrawRectangle(i32(pos.x), i32(pos.y), i32(measurements.x), i32(measurements.y), r.WHITE) + r.DrawTextEx(font, cstr, pos, font_size, 0, r.BLACK) + x += measurements.x + + if len(suffix) != 0 { + cstr := strings.unsafe_string_to_cstring(string(suffix)) + pos := r.Vector2{x, font_size * f32(line_index)} + r.DrawTextEx(font, cstr, pos, font_size, 0, r.WHITE) + } } move_cursor :: proc() { @@ -297,7 +333,7 @@ move_cursor :: proc() { defer handle_selection_end() preferred_position := cursor.char + 1 if cursor.char == len(current_line()) && cursor.line != len(lines) - 1 { - cursor.char = 0 + preferred_position = 0 cursor.line += 1 } if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && cursor.char + 1 < len(current_line()) { @@ -324,7 +360,7 @@ move_cursor :: proc() { preferred_position := cursor.char - 1 if cursor.char == 0 && cursor.line != 0 { cursor.line -= 1 - cursor.char = len(current_line()) + preferred_position = len(current_line()) } if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.char { found := false