fix a corner case when selecting text

The hard part here is keeping click-drag selection working (without
pressing and holding shift).
This commit is contained in:
Kartik K. Agaram 2022-06-09 15:49:16 -07:00
parent fa5bf1218a
commit 6ba10b4de6
2 changed files with 51 additions and 9 deletions

View File

@ -55,6 +55,7 @@ Cursor1 = {line=1, pos=1} -- position of cursor
Screen_bottom1 = {line=1, pos=1} -- position of start of screen line at bottom of screen
Selection1 = {}
Old_cursor1, Old_selection1, Mousepress_shift = nil -- some extra state to compute selection between mousepress and mouserelease
Recent_mouse = {} -- when selecting text, avoid recomputing some state on every single frame
Cursor_x, Cursor_y = 0, 0 -- in pixels
@ -271,13 +272,19 @@ function App.mousepressed(x,y, mouse_button)
for line_index,line in ipairs(Lines) do
if line.mode == 'text' then
if Text.in_line(line, x,y) then
if App.shift_down() then
Selection1 = {line=Cursor1.line, pos=Cursor1.pos}
end
Cursor1 = {line=line_index, pos=Text.to_pos_on_line(line, x, y)}
if not App.shift_down() then
Selection1 = {line=Cursor1.line, pos=Cursor1.pos}
end
-- delicate dance between cursor, selection and old cursor
-- manual tests:
-- regular press+release: sets cursor, clears selection
-- shift press+release:
-- sets selection to old cursor if not set otherwise leaves it untouched
-- sets cursor
-- press and hold to start a selection: sets selection on press, cursor on release
-- press and hold, then press shift: ignore shift
-- i.e. mousereleased should never look at shift state
Old_cursor1 = Cursor1
Old_selection1 = Selection1
Mousepress_shift = App.shift_down()
Selection1 = {line=line_index, pos=Text.to_pos_on_line(line, x, y)}
end
elseif line.mode == 'drawing' then
if Drawing.in_drawing(line, x, y) then
@ -296,9 +303,14 @@ function App.mousereleased(x,y, button)
if line.mode == 'text' then
if Text.in_line(line, x,y) then
Cursor1 = {line=line_index, pos=Text.to_pos_on_line(line, x, y)}
if Text.eq1(Cursor1, Selection1) and not App.shift_down() then
Selection1 = {}
if Mousepress_shift then
if Old_selection1.line == nil then
Selection1 = Old_cursor1
else
Selection1 = Old_selection1
end
end
Old_cursor1, Old_selection1, Mousepress_shift = nil
end
end
end

View File

@ -224,6 +224,36 @@ function test_select_text_using_mouse_and_shift()
check_eq(Cursor1.pos, 4, 'F - test_select_text_using_mouse_and_shift/cursor:pos')
end
function test_select_text_repeatedly_using_mouse_and_shift()
io.write('\ntest_select_text_repeatedly_using_mouse_and_shift')
App.screen.init{width=50, height=60}
Lines = load_array{'abc', 'def', 'xyz'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=1}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
Selection1 = {}
App.draw() -- populate line.y for each line in Lines
local screen_left_margin = 25 -- pixels
-- click on first location
App.run_after_mousepress(screen_left_margin+8,Margin_top+5, '1')
App.run_after_mouserelease(screen_left_margin+8,Margin_top+5, '1')
-- hold down shift and click on a second location
App.keypress('lshift')
App.run_after_mousepress(screen_left_margin+20,Margin_top+5, '1')
App.run_after_mouserelease(screen_left_margin+20,Margin_top+Line_height+5, '1')
-- hold down shift and click at a third location
App.keypress('lshift')
App.run_after_mousepress(screen_left_margin+20,Margin_top+5, '1')
App.run_after_mouserelease(screen_left_margin+8,Margin_top+Line_height+5, '1')
App.keyrelease('lshift')
-- selection is between first and third location. forget the second location, not the first.
check_eq(Selection1.line, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:line')
check_eq(Selection1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:pos')
check_eq(Cursor1.line, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:line')
check_eq(Cursor1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:pos')
end
function test_pagedown()
io.write('\ntest_pagedown')
App.screen.init{width=120, height=45}