From 9b5a78d3c507a616a59e2933b061603b1e421695 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 9 Jun 2024 20:35:50 -0700 Subject: [PATCH] bugfix in source editor --- source_edit.lua | 13 +++++++------ source_text.lua | 19 +++++++++++++++++++ source_text_tests.lua | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/source_edit.lua b/source_edit.lua index e376537..1e8259c 100644 --- a/source_edit.lua +++ b/source_edit.lua @@ -68,8 +68,10 @@ function edit.initialize_state(top, left, right, font, font_height, line_height) -- -- Make sure these coordinates are never aliased, so that changing one causes -- action at a distance. + -- + -- On lines that are drawings, pos will be nil. screen_top1 = {line=1, pos=1}, -- position of start of screen line at top of screen - cursor1 = {line=1, pos=1}, -- position of cursor + cursor1 = {line=1, pos=1}, -- position of cursor; must be on a text line screen_bottom1 = {line=1, pos=1}, -- position of start of screen line at bottom of screen selection1 = {}, @@ -190,6 +192,7 @@ function edit.draw(State, hide_cursor, show_line_numbers) Drawing.before = snapshot(State, line_index-1, line_index) table.insert(State.lines, line_index, {mode='drawing', y=y, h=256/2, points={}, shapes={}, pending={}}) table.insert(State.line_cache, line_index, {}) + for _,line_cache in ipairs(State.line_cache) do line_cache.starty = nil end if State.cursor1.line >= line_index then State.cursor1.line = State.cursor1.line+1 end @@ -296,10 +299,7 @@ function edit.mouse_press(State, x,y, mouse_button) State.old_cursor1 = State.cursor1 State.old_selection1 = State.selection1 State.mousepress_shift = App.shift_down() - State.selection1 = { - line=State.screen_bottom1.line, - pos=Text.pos_at_end_of_screen_line(State, State.screen_bottom1), - } + State.selection1 = Text.final_text_loc_on_screen(State) end function edit.mouse_release(State, x,y, mouse_button) @@ -337,7 +337,7 @@ function edit.mouse_release(State, x,y, mouse_button) end -- still here? mouse release is below all screen lines - State.cursor1.line, State.cursor1.pos = State.screen_bottom1.line, Text.pos_at_end_of_screen_line(State, State.screen_bottom1) + State.cursor1 = Text.final_text_loc_on_screen(State) edit.clean_up_mouse_press(State) --? print_and_log(('edit.mouse_release: finally selection %s,%s cursor %d,%d'):format(tostring(State.selection1.line), tostring(State.selection1.pos), State.cursor1.line, State.cursor1.pos)) end @@ -600,6 +600,7 @@ end function edit.run_after_mouse_click(State, x,y, mouse_button) App.fake_mouse_press(x,y, mouse_button) edit.mouse_press(State, x,y, mouse_button) + edit.draw(State) App.fake_mouse_release(x,y, mouse_button) edit.mouse_release(State, x,y, mouse_button) App.screen.contents = {} diff --git a/source_text.lua b/source_text.lua index 7c1838c..0fced93 100644 --- a/source_text.lua +++ b/source_text.lua @@ -683,6 +683,7 @@ function Text.pos_at_start_of_screen_line(State, loc1) end function Text.pos_at_end_of_screen_line(State, loc1) + assert(State.lines[loc1.line].mode == 'text') Text.populate_screen_line_starting_pos(State, loc1.line) local line_cache = State.line_cache[loc1.line] local most_recent_final_pos = utf8.len(State.lines[loc1.line].data)+1 @@ -696,6 +697,24 @@ function Text.pos_at_end_of_screen_line(State, loc1) assert(false, ('invalid pos %d'):format(loc1.pos)) end +function Text.final_text_loc_on_screen(State) + if State.lines[State.screen_bottom1.line].mode == 'text' then + return { + line=State.screen_bottom1.line, + pos=Text.pos_at_end_of_screen_line(State, State.screen_bottom1), + } + end + local loc2 = Text.to2(State, State.screen_bottom1) + while true do + if State.lines[loc2.line].mode == 'text' then break end + assert(loc2.line > 1 or loc2.screen_line > 1 and loc2.screen_pos > 1) -- elsewhere we're making sure there's always at least one text line on screen + loc2 = Text.previous_screen_line(State, loc2) + end + local result = Text.to1(State, loc2) + result.pos = Text.pos_at_end_of_screen_line(State, result) + return result +end + function Text.cursor_at_final_screen_line(State) Text.populate_screen_line_starting_pos(State, State.cursor1.line) local screen_lines = State.line_cache[State.cursor1.line].screen_line_starting_pos diff --git a/source_text_tests.lua b/source_text_tests.lua index 6376ec8..b8f29d1 100644 --- a/source_text_tests.lua +++ b/source_text_tests.lua @@ -16,7 +16,7 @@ function test_initial_state() end function test_click_to_create_drawing() - App.screen.init{width=120, height=60} + App.screen.init{width=800, height=600} Editor_state = edit.initialize_test_state() Editor_state.lines = load_array{} Text.redraw_all(Editor_state)