data flow is starting to get more rigorous
On any event we might update the cursor pane's screen top (if it's editable) or the viewport. Updating the cursor pane's screen top will modify the viewport. We then update all pane bounds based on the viewport. Pane bounds include screen top. If that was updated already in the event we skip it for that pane. Still not perfect. Scrolling is jerky in the editable cursor pane.
This commit is contained in:
parent
363d837606
commit
e1d2e90cd9
9
edit.lua
9
edit.lua
|
@ -122,7 +122,14 @@ function edit.draw(State)
|
|||
App.color(Text_color)
|
||||
--? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos)
|
||||
assert(#State.lines == #State.line_cache)
|
||||
assert(Text.le1(State.screen_top1, State.cursor1))
|
||||
if State.show_cursor then
|
||||
if not Text.le1(State.screen_top1, State.cursor1) then
|
||||
print('assertion failure: cursor is above screen top')
|
||||
print('screen top', State.screen_top1.line, State.screen_top1.pos)
|
||||
print('cursor', State.cursor1.line, State.cursor1.pos)
|
||||
assert(false)
|
||||
end
|
||||
end
|
||||
State.cursor_y = -1
|
||||
local y = State.top
|
||||
--? print('== draw')
|
||||
|
|
73
main.lua
73
main.lua
|
@ -46,8 +46,7 @@ function App.initialize_globals()
|
|||
|
||||
Display_settings = {
|
||||
mode=nil,
|
||||
y=0,
|
||||
x=0,
|
||||
x=0, y=0, -- <==== Top-left corner of the viewport into the surface
|
||||
column_width=400,
|
||||
palette='',
|
||||
palette_text=App.newText(love.graphics.getFont(), ''),
|
||||
|
@ -129,6 +128,8 @@ function App.initialize(arg)
|
|||
table.insert(column, initialize_pane_with_placeholder_coordinates('foo'))
|
||||
table.insert(Surface, column)
|
||||
|
||||
update_pane_bounds()
|
||||
|
||||
if rawget(_G, 'jit') then
|
||||
jit.off()
|
||||
jit.flush()
|
||||
|
@ -149,9 +150,9 @@ function initialize_window_geometry()
|
|||
end
|
||||
|
||||
function App.resize(w, h)
|
||||
Surface.dirty = true
|
||||
App.screen.width, App.screen.height = w, h
|
||||
Last_resize_time = App.getTime()
|
||||
update_pane_bounds()
|
||||
end
|
||||
|
||||
function initialize_file(file)
|
||||
|
@ -190,6 +191,38 @@ function initialize_pane_with_placeholder_coordinates(id)
|
|||
return result
|
||||
end
|
||||
|
||||
function update_pane_bounds(options)
|
||||
local sx = Padding_horizontal + Margin_left
|
||||
for column_index, column in ipairs(Surface) do
|
||||
if overlap(sx, sx+Display_settings.column_width, Display_settings.x, Display_settings.x + App.screen.width) then
|
||||
local sy = Margin_top
|
||||
for pane_index, pane in ipairs(column) do
|
||||
if overlap(sy, sy + Margin_above + Cache[pane.id].height + Margin_below, Display_settings.y, Display_settings.y + App.screen.height) then
|
||||
if column_index == Cursor_pane.col and pane_index == Cursor_pane.row then
|
||||
-- update the cursor pane either if it's not editable, or
|
||||
-- if it was explicitly requested
|
||||
if not pane.show_cursor or options == nil or not options.ignore_editable_cursor_pane then
|
||||
if sy < Display_settings.y then
|
||||
pane.screen_top1 = schema1_of_y(pane, Display_settings.y - Margin_top)
|
||||
else
|
||||
pane.screen_top1 = {line=1, pos=1}
|
||||
end
|
||||
end
|
||||
end
|
||||
--? print(('%d,%d: adjusting pane top %d; screen_top is at line %d (max %d)'):format(column_index, pane_index, pane.top, pane.screen_top1.line, #pane.lines))
|
||||
pane.top = sy - Display_settings.y + Margin_above
|
||||
--? print(('pane top is %d'):format(pane.top))
|
||||
pane.left = sx - Display_settings.x
|
||||
pane.right = pane.left + Display_settings.column_width
|
||||
pane.width = pane.right - pane.left
|
||||
end
|
||||
sy = sy + Margin_above + Cache[pane.id].height + Margin_below + Padding_vertical
|
||||
end
|
||||
end
|
||||
sx = sx + Margin_right + Display_settings.column_width + Padding_horizontal + Margin_left
|
||||
end
|
||||
end
|
||||
|
||||
-- Since the editor deals with potentially changing data, it tries to maintain
|
||||
-- just a screen's worth of screen-line data.
|
||||
-- Since the larger note-taking app mostly deals with read-only data, it
|
||||
|
@ -203,27 +236,14 @@ end
|
|||
|
||||
function App.draw()
|
||||
Button_handlers = {}
|
||||
-- top > Margin_top or Screen_top.line > 1
|
||||
local sx = Padding_horizontal + Margin_left
|
||||
--? if Surface.dirty then
|
||||
--? print(('draw from surface y of %d'):format(Display_settings.y))
|
||||
--? end
|
||||
for column_index, column in ipairs(Surface) do
|
||||
if overlap(sx, sx+Display_settings.column_width, Display_settings.x, Display_settings.x + App.screen.width) then
|
||||
--? print('draw column')
|
||||
local sy = Margin_top
|
||||
for pane_index, pane in ipairs(column) do
|
||||
if overlap(sy, sy + Margin_above + Cache[pane.id].height + Margin_below, Display_settings.y, Display_settings.y + App.screen.height) then
|
||||
--? print('draw pane')
|
||||
if Surface.dirty then
|
||||
--? print(('%d,%d: adjusting pane top %d; screen_top is at line %d (max %d)'):format(column_index, pane_index, pane.top, pane.screen_top1.line, #pane.lines))
|
||||
pane.top = sy - Display_settings.y + Margin_above
|
||||
--? print(('pane top is %d'):format(pane.top))
|
||||
pane.left = sx - Display_settings.x
|
||||
pane.right = pane.left + Display_settings.column_width
|
||||
pane.width = pane.right - pane.left
|
||||
end
|
||||
--? print(column_index, pane_index, pane.cursor1.line, pane.cursor1.pos, pane.selection1.line, pane.selection1.pos)
|
||||
--? print('draw pane', column_index, pane_index, pane.cursor1.line, pane.cursor1.pos, pane.selection1.line, pane.selection1.pos)
|
||||
edit.draw(pane)
|
||||
if column_index == Cursor_pane.col and pane_index == Cursor_pane.row then
|
||||
App.color(Cursor_pane_background_color)
|
||||
|
@ -245,7 +265,6 @@ function App.draw()
|
|||
if Display_settings.mode == 'palette' then
|
||||
draw_command_palette()
|
||||
end
|
||||
Surface.dirty = false
|
||||
end
|
||||
|
||||
function overlap(lo1,hi1, lo2,hi2)
|
||||
|
@ -297,7 +316,7 @@ function App.update(dt)
|
|||
edit.update(pane, dt)
|
||||
end
|
||||
if App.mouse_down(1) then
|
||||
Surface.dirty = true
|
||||
update_pane_bounds()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -425,7 +444,6 @@ end
|
|||
|
||||
function App.keychord_pressed(chord, key)
|
||||
Cursor_time = 0 -- ensure cursor is visible immediately after it moves
|
||||
Surface.dirty = true
|
||||
if Display_settings.mode == nil then
|
||||
handle_normal_mode_keychord(chord, key)
|
||||
elseif Display_settings.mode == 'palette' then
|
||||
|
@ -434,6 +452,8 @@ function App.keychord_pressed(chord, key)
|
|||
print(Display_settings.mode)
|
||||
assert(false)
|
||||
end
|
||||
-- editable cursor pane will have already updated its screen_top, so don't clobber it here
|
||||
update_pane_bounds{ignore_editable_cursor_pane=true}
|
||||
end
|
||||
|
||||
function handle_command_palette_keychord(chord, key)
|
||||
|
@ -633,6 +653,19 @@ end
|
|||
-- - let loc, y_offset = schema1_of_y(pane, y)
|
||||
-- y - y_offset == y_of_schema1(pane, loc)
|
||||
function schema1_of_y(pane, y)
|
||||
local y_offset = y
|
||||
local line,pos_index = 1,1
|
||||
Text.populate_screen_line_starting_pos(pane, line)
|
||||
while y_offset >= Line_height do
|
||||
pos_index = pos_index + 1
|
||||
if pos_index > #pane.line_cache[line].screen_line_starting_pos then
|
||||
line = line+1
|
||||
pos_index = 1
|
||||
Text.populate_screen_line_starting_pos(pane, line)
|
||||
end
|
||||
y_offset = y_offset - Line_height
|
||||
end
|
||||
return {line=line, pos=pane.line_cache[line].screen_line_starting_pos[pos_index]}, y_offset
|
||||
end
|
||||
|
||||
function line_height(State, line_index, left, right)
|
||||
|
|
1
text.lua
1
text.lua
|
@ -936,6 +936,7 @@ function Text.populate_screen_line_starting_pos(State, line_index)
|
|||
local frag, frag_text = f.data, f.text
|
||||
-- render fragment
|
||||
local frag_width = App.width(frag_text)
|
||||
--? print('', '', frag, 'comparing', x, frag_width, State.right)
|
||||
if x + frag_width > State.right then
|
||||
x = State.left
|
||||
table.insert(line_cache.screen_line_starting_pos, pos)
|
||||
|
|
Loading…
Reference in New Issue
Block a user