clicking now moves the cursor even on long, wrapped lines
This commit is contained in:
parent
4fb4e0eb25
commit
d4daac442b
4
main.lua
4
main.lua
|
@ -12,6 +12,7 @@ require 'icons'
|
|||
-- a text is a table with:
|
||||
-- mode = 'text'
|
||||
-- string data
|
||||
-- screen_line_starting_pos: optional array of grapheme indices if it wraps over more than one screen line
|
||||
-- a drawing is a table with:
|
||||
-- mode = 'drawing'
|
||||
-- a (y) coord in pixels (updated while painting screen),
|
||||
|
@ -126,7 +127,6 @@ function love.draw()
|
|||
y = y + Drawing.pixels(line.h) + 10 -- padding
|
||||
else
|
||||
line.y = y
|
||||
--? y = Text.draw(line, 100, line_index, Cursor_line, Cursor_pos)
|
||||
y = Text.draw(line, Line_width, line_index, Cursor_line, Cursor_pos)
|
||||
y = y + math.floor(15*Zoom) -- text height
|
||||
end
|
||||
|
@ -145,7 +145,7 @@ function love.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
|
||||
Text.move_cursor(line_index, line, x)
|
||||
Text.move_cursor(line_index, line, x, y)
|
||||
end
|
||||
elseif line.mode == 'drawing' then
|
||||
if Drawing.in_drawing(line, x, y) then
|
||||
|
|
55
text.lua
55
text.lua
|
@ -39,8 +39,6 @@ function Text.compute_fragments(line, line_width)
|
|||
end
|
||||
|
||||
function Text.draw(line, line_width, line_index, cursor_line, cursor_pos)
|
||||
--? love.graphics.setColor(0.75,0.75,0.75)
|
||||
--? love.graphics.line(line_width, 0, line_width, Screen_height)
|
||||
love.graphics.setColor(0,0,0)
|
||||
-- wrap long lines
|
||||
local x = 25
|
||||
|
@ -57,6 +55,11 @@ function Text.draw(line, line_width, line_index, cursor_line, cursor_pos)
|
|||
assert(x > 25) -- no overfull lines
|
||||
y = y + math.floor(15*Zoom)
|
||||
x = 25
|
||||
if line.screen_line_starting_pos == nil then
|
||||
line.screen_line_starting_pos = {1, pos}
|
||||
else
|
||||
table.insert(line.screen_line_starting_pos, pos)
|
||||
end
|
||||
end
|
||||
love.graphics.draw(frag_text, x,y, 0, Zoom)
|
||||
-- render cursor if necessary
|
||||
|
@ -267,13 +270,55 @@ end
|
|||
|
||||
function Text.in_line(line, x,y)
|
||||
if line.y == nil then return false end -- outside current page
|
||||
return x >= 16 and y >= line.y and y < line.y + math.floor(15*Zoom)
|
||||
if x < 16 then return false end
|
||||
if y < line.y then return false end
|
||||
if line.screen_line_starting_pos == nil then return y < line.y + math.floor(15*Zoom) end
|
||||
return y < line.y + #line.screen_line_starting_pos * math.floor(15*Zoom)
|
||||
end
|
||||
|
||||
function Text.move_cursor(line_index, line, mx)
|
||||
function Text.move_cursor(line_index, line, mx, my)
|
||||
Cursor_line = line_index
|
||||
Cursor_pos = Text.nearest_cursor_pos(line.data, mx)
|
||||
if line.screen_line_starting_pos == nil then
|
||||
--? print('single screen line')
|
||||
Cursor_pos = Text.nearest_cursor_pos(line.data, mx)
|
||||
return
|
||||
end
|
||||
assert(line.fragments)
|
||||
assert(my >= line.y)
|
||||
--? print('move_cursor', mx, my)
|
||||
if my < line.y + math.floor(15*Zoom) then
|
||||
--? print('first screen line')
|
||||
Cursor_pos = Text.nearest_cursor_pos(line.data, mx)
|
||||
return
|
||||
end
|
||||
-- duplicate some logic from Text.draw
|
||||
local y = line.y
|
||||
for _,screen_line_starting_pos in ipairs(line.screen_line_starting_pos) do
|
||||
--? print('screen line:', screen_line_starting_pos)
|
||||
local nexty = y + math.floor(15*Zoom)
|
||||
if my < nexty then
|
||||
local s = string.sub(line.data, screen_line_starting_pos)
|
||||
Cursor_pos = screen_line_starting_pos + Text.nearest_cursor_pos(s, mx) - 1
|
||||
return
|
||||
end
|
||||
y = nexty
|
||||
end
|
||||
assert(false)
|
||||
end
|
||||
-- manual test:
|
||||
-- line: abc
|
||||
-- def
|
||||
-- gh
|
||||
-- fragments: abc, def, gh
|
||||
-- click inside e
|
||||
-- line_starting_pos = 1 + 3 = 4
|
||||
-- nearest_cursor_pos('defgh', mx) = 2
|
||||
-- Cursor_pos = 4 + 2 - 1 = 5
|
||||
-- manual test:
|
||||
-- click inside h
|
||||
-- line_starting_pos = 1 + 3 + 3 = 7
|
||||
-- nearest_cursor_pos('gh', mx) = 2
|
||||
-- Cursor_pos = 7 + 2 - 1 = 8
|
||||
|
||||
function Text.nearest_cursor_pos(line, x, hint)
|
||||
if x == 0 then
|
||||
|
|
Loading…
Reference in New Issue