tracking selection from input
This commit is contained in:
186
src/main.odin
186
src/main.odin
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
- DONE implement movement up and down by paragraph
|
- DONE implement movement up and down by paragraph
|
||||||
- DONE implement scrolling/viewport
|
- DONE implement scrolling/viewport
|
||||||
- TODO implement deletion by word
|
- DONE implement deletion by word
|
||||||
- TODO implement selection
|
- TODO implement selection
|
||||||
- TODO implement duplicate selection/line
|
- TODO implement duplicate selection/line
|
||||||
- TODO implement move selection/line up/down
|
- TODO implement move selection/line up/down
|
||||||
@@ -37,6 +37,14 @@ Cursor :: struct {
|
|||||||
char: int,
|
char: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Selection :: struct {
|
||||||
|
active: bool,
|
||||||
|
start_line: int,
|
||||||
|
end_line: int,
|
||||||
|
start_char: int,
|
||||||
|
end_char: int,
|
||||||
|
}
|
||||||
|
|
||||||
window_width := 800
|
window_width := 800
|
||||||
window_height := 600
|
window_height := 600
|
||||||
font_size: f32 = 20.0
|
font_size: f32 = 20.0
|
||||||
@@ -48,6 +56,7 @@ viewport := Viewport {
|
|||||||
start = 0,
|
start = 0,
|
||||||
end = viewport_size,
|
end = viewport_size,
|
||||||
}
|
}
|
||||||
|
selection := Selection{}
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
r.InitWindow(i32(window_width), i32(window_height), "odit")
|
r.InitWindow(i32(window_width), i32(window_height), "odit")
|
||||||
@@ -76,78 +85,7 @@ main :: proc() {
|
|||||||
cursor.char += 1
|
cursor.char += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if repeatable_key_pressed(r.KeyboardKey.RIGHT) {
|
move_cursor()
|
||||||
preferred_position := cursor.char + 1
|
|
||||||
if cursor.char == len(current_line()) && cursor.line != len(lines) - 1 {
|
|
||||||
cursor.char = 0
|
|
||||||
cursor.line += 1
|
|
||||||
}
|
|
||||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && cursor.char + 1 < len(current_line()) {
|
|
||||||
seen_space := false
|
|
||||||
for c, c_index in current_line()[cursor.char + 1:] {
|
|
||||||
if seen_space && !is_whitespace(c) {
|
|
||||||
preferred_position = cursor.char + c_index
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if is_whitespace(c) {
|
|
||||||
seen_space = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !seen_space {
|
|
||||||
preferred_position = len(current_line())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor.char = min(preferred_position, len(current_line()))
|
|
||||||
}
|
|
||||||
|
|
||||||
if repeatable_key_pressed(r.KeyboardKey.LEFT) {
|
|
||||||
preferred_position := cursor.char - 1
|
|
||||||
if cursor.char == 0 && cursor.line != 0 {
|
|
||||||
cursor.line -= 1
|
|
||||||
cursor.char = len(current_line())
|
|
||||||
}
|
|
||||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.char {
|
|
||||||
found := false
|
|
||||||
preferred_position, found = find_previous_space(cursor.char, current_line()[:])
|
|
||||||
}
|
|
||||||
cursor.char = max(preferred_position, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if repeatable_key_pressed(r.KeyboardKey.UP) {
|
|
||||||
preferred_line := cursor.line - 1
|
|
||||||
|
|
||||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.line {
|
|
||||||
#reverse for l, l_index in lines[:cursor.line] {
|
|
||||||
if len(l) == 0 || all_whitespace(l[:]) {
|
|
||||||
preferred_line = l_index
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.line = max(0, preferred_line)
|
|
||||||
if len(current_line()) < cursor.char {
|
|
||||||
cursor.char = len(current_line())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if repeatable_key_pressed(r.KeyboardKey.DOWN) {
|
|
||||||
preferred_line := cursor.line + 1
|
|
||||||
|
|
||||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && cursor.line + 1 < len(lines) {
|
|
||||||
for l, l_index in lines[cursor.line + 1:] {
|
|
||||||
if len(l) == 0 || all_whitespace(l[:]) {
|
|
||||||
preferred_line = cursor.line + l_index + 1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.line = min(preferred_line, len(lines) - 1)
|
|
||||||
if len(current_line()) < cursor.char {
|
|
||||||
cursor.char = len(current_line())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if repeatable_key_pressed(r.KeyboardKey.ENTER) {
|
if repeatable_key_pressed(r.KeyboardKey.ENTER) {
|
||||||
new_line_cap := len(current_line()) - cursor.char
|
new_line_cap := len(current_line()) - cursor.char
|
||||||
@@ -288,3 +226,105 @@ find_previous_space :: proc(current_position: int, line: []u8) -> (result: int,
|
|||||||
|
|
||||||
return result, found
|
return result, found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_selection_start :: proc() {
|
||||||
|
was_active := selection.active
|
||||||
|
if r.IsKeyDown(r.KeyboardKey.LEFT_SHIFT) {
|
||||||
|
selection.active = true
|
||||||
|
} else {
|
||||||
|
selection = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if selection.active && was_active do return
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
move_cursor :: proc() {
|
||||||
|
if repeatable_key_pressed(r.KeyboardKey.RIGHT) {
|
||||||
|
handle_selection_start()
|
||||||
|
defer handle_selection_end()
|
||||||
|
preferred_position := cursor.char + 1
|
||||||
|
if cursor.char == len(current_line()) && cursor.line != len(lines) - 1 {
|
||||||
|
cursor.char = 0
|
||||||
|
cursor.line += 1
|
||||||
|
}
|
||||||
|
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && cursor.char + 1 < len(current_line()) {
|
||||||
|
seen_space := false
|
||||||
|
for c, c_index in current_line()[cursor.char + 1:] {
|
||||||
|
if seen_space && !is_whitespace(c) {
|
||||||
|
preferred_position = cursor.char + c_index
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if is_whitespace(c) {
|
||||||
|
seen_space = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !seen_space {
|
||||||
|
preferred_position = len(current_line())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.char = min(preferred_position, len(current_line()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if repeatable_key_pressed(r.KeyboardKey.LEFT) {
|
||||||
|
handle_selection_start()
|
||||||
|
defer handle_selection_end()
|
||||||
|
preferred_position := cursor.char - 1
|
||||||
|
if cursor.char == 0 && cursor.line != 0 {
|
||||||
|
cursor.line -= 1
|
||||||
|
cursor.char = len(current_line())
|
||||||
|
}
|
||||||
|
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.char {
|
||||||
|
found := false
|
||||||
|
preferred_position, found = find_previous_space(cursor.char, current_line()[:])
|
||||||
|
}
|
||||||
|
cursor.char = max(preferred_position, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if repeatable_key_pressed(r.KeyboardKey.UP) {
|
||||||
|
handle_selection_start()
|
||||||
|
defer handle_selection_end()
|
||||||
|
preferred_line := cursor.line - 1
|
||||||
|
|
||||||
|
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.line {
|
||||||
|
#reverse for l, l_index in lines[:cursor.line] {
|
||||||
|
if len(l) == 0 || all_whitespace(l[:]) {
|
||||||
|
preferred_line = l_index
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.line = max(0, preferred_line)
|
||||||
|
if len(current_line()) < cursor.char {
|
||||||
|
cursor.char = len(current_line())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if repeatable_key_pressed(r.KeyboardKey.DOWN) {
|
||||||
|
handle_selection_start()
|
||||||
|
defer handle_selection_end()
|
||||||
|
preferred_line := cursor.line + 1
|
||||||
|
|
||||||
|
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && cursor.line + 1 < len(lines) {
|
||||||
|
for l, l_index in lines[cursor.line + 1:] {
|
||||||
|
if len(l) == 0 || all_whitespace(l[:]) {
|
||||||
|
preferred_line = cursor.line + l_index + 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.line = min(preferred_line, len(lines) - 1)
|
||||||
|
if len(current_line()) < cursor.char {
|
||||||
|
cursor.char = len(current_line())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user