commit
b74f2b917d
4
0019-B
4
0019-B
|
@ -1,4 +1,4 @@
|
|||
B = function(skip_updating_screen_top_for)
|
||||
B = function()
|
||||
-- print('B')
|
||||
-- recompute various aspects based on the current viewport settings
|
||||
for _,obj in ipairs(Surface) do
|
||||
|
@ -17,7 +17,7 @@ B = function(skip_updating_screen_top_for)
|
|||
obj.zdata = love.math.newBezierCurve(zdata):render()
|
||||
elseif obj.type == 'text' then
|
||||
if obj.w then
|
||||
update_editor_box(obj, skip_updating_screen_top_for)
|
||||
update_editor_box(obj)
|
||||
else
|
||||
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
compute_layout = function(node, x,y, nodes_to_render, skip_updating_screen_top_for)
|
||||
compute_layout = function(node, x,y, nodes_to_render)
|
||||
-- append to nodes_to_render flattened instructions to render a hierarchy of nodes
|
||||
-- return x,y rendered until (surface coordinates)
|
||||
if node.type == 'text' then
|
||||
|
@ -31,7 +31,7 @@ compute_layout = function(node, x,y, nodes_to_render, skip_updating_screen_top_f
|
|||
if node.editor == nil then
|
||||
initialize_editor(node)
|
||||
else
|
||||
update_editor_box(node, skip_updating_screen_top_for)
|
||||
update_editor_box(node)
|
||||
end
|
||||
node.h = box_height(node)
|
||||
table.insert(nodes_to_render, node)
|
||||
|
@ -59,7 +59,7 @@ compute_layout = function(node, x,y, nodes_to_render, skip_updating_screen_top_f
|
|||
if not child.width then
|
||||
child.width = node.width -- HACK: should we set child.w or child.width? Neither is quite satisfactory.
|
||||
end
|
||||
subx,suby = compute_layout(child, x,suby, nodes_to_render, skip_updating_screen_top_for)
|
||||
subx,suby = compute_layout(child, x,suby, nodes_to_render)
|
||||
if w < child.w then
|
||||
w = child.w
|
||||
end
|
||||
|
@ -87,7 +87,7 @@ compute_layout = function(node, x,y, nodes_to_render, skip_updating_screen_top_f
|
|||
subx = subx+child.margin
|
||||
w = w+child.margin
|
||||
end
|
||||
subx,suby = compute_layout(child, subx,y, nodes_to_render, skip_updating_screen_top_for)
|
||||
subx,suby = compute_layout(child, subx,y, nodes_to_render)
|
||||
w = w + child.w
|
||||
if h < child.h then
|
||||
h = child.h
|
||||
|
|
|
@ -47,28 +47,12 @@ on.keychord_press = function(chord, key)
|
|||
else
|
||||
local old_top = {line=Cursor_node.editor.screen_top1.line, pos=Cursor_node.editor.screen_top1.pos}
|
||||
local old_definition_name = live.get_definition_name_from_buffer(live.definition_to_string(Cursor_node.editor))
|
||||
print('cursor before', Cursor_node.editor.cursor1.line, Cursor_node.editor.cursor1.pos)
|
||||
edit.keychord_press(Cursor_node.editor, chord, key)
|
||||
--? print('edit', old_top.line, '=>', Cursor_node.editor.screen_top1.line)
|
||||
print('cursor after', Cursor_node.editor.cursor1.line, Cursor_node.editor.cursor1.pos)
|
||||
local definition_name = live.get_definition_name_from_buffer(live.definition_to_string(Cursor_node.editor))
|
||||
maybe_update_key_in_definitions(old_definition_name, definition_name, Cursor_node)
|
||||
if not eq(Cursor_node.editor.screen_top1, old_top) then
|
||||
--? print('modifying Viewport', Viewport.y, 'based on', Cursor_node.y, Cursor_node.editor.screen_top1.line, Cursor_node.editor.line_height)
|
||||
Viewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)/Viewport.zoom
|
||||
--? print('modified Viewport', Viewport.y)
|
||||
-- Most of the time, we update the screen_top of nodes from Viewport.y.
|
||||
-- But here we went the other way.
|
||||
-- It's very important to avoid creating a recurrence, to avoid running
|
||||
-- both sides of this feedback loop in a single frame. These apps are
|
||||
-- not very numerically precise (e.g. we force text lines to start at
|
||||
-- integer pixels regardless of zoom, because that keeps text crisp),
|
||||
-- and the computations of Viewport.y and node.top will almost certainly
|
||||
-- not converge. The resulting bugs are extremely difficult to chase
|
||||
-- down.
|
||||
-- The optional skip_updating_screen_top_for arg ensures we don't run
|
||||
-- the other side of the feedback loop.
|
||||
A(--[[skip updating screen_top for]] Cursor_node)
|
||||
return
|
||||
end
|
||||
pan_viewport_to_contain_cursor(Cursor_node)
|
||||
if chord == 'return' then
|
||||
A()
|
||||
else
|
||||
|
|
4
0028-A
4
0028-A
|
@ -1,4 +1,4 @@
|
|||
A = function(skip_updating_screen_top_for)
|
||||
A = function()
|
||||
-- print('A')
|
||||
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font
|
||||
-- translate Definitions to Surface
|
||||
|
@ -8,6 +8,6 @@ A = function(skip_updating_screen_top_for)
|
|||
compute_layout(node, node.x,node.y, Surface, skip_updating_screen_top_for)
|
||||
end
|
||||
-- continue the pipeline
|
||||
B(skip_updating_screen_top_for)
|
||||
B()
|
||||
-- TODO: ugly that we're manipulating editor objects twice
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
update_editor_box = function(node, skip_updating_screen_top_for)
|
||||
update_editor_box = function(node, skip_updating)
|
||||
if node.editor == nil then return end
|
||||
if node == skip_updating then return end
|
||||
if node.editor.font_height ~= scale(20) then
|
||||
edit.update_font_settings(node.editor, scale(20))
|
||||
end
|
||||
|
@ -7,26 +8,12 @@ update_editor_box = function(node, skip_updating_screen_top_for)
|
|||
node.editor.right = math.ceil(vx(node.x+node.w))
|
||||
node.editor.width = node.editor.right - node.editor.left
|
||||
Text.redraw_all(node.editor)
|
||||
--? print('update', node.y, Viewport.y, 'spx', node.editor.screen_top1.line, node.editor.top, 'vpx')
|
||||
if node.y > Viewport.y then
|
||||
if node ~= skip_updating_screen_top_for then
|
||||
--? print('modifying screen_top to 1')
|
||||
node.editor.screen_top1.line = 1
|
||||
node.editor.screen_top1.pos = 1
|
||||
end
|
||||
node.editor.screen_top1.line = 1
|
||||
node.editor.screen_top1.pos = 1
|
||||
node.editor.top = vy(node.y)
|
||||
else
|
||||
--? print('<=', node, skip_updating_screen_top_for)
|
||||
if node ~= skip_updating_screen_top_for then
|
||||
node.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, scale(Viewport.y-node.y))
|
||||
--? print('modified screen_top to', node.editor.screen_top1.line, 'at', node.editor.top, 'vpx')
|
||||
else
|
||||
-- adjust editor to start rendering near top of viewport
|
||||
--? print(Viewport.y)
|
||||
node.editor.top = Viewport.y%node.editor.line_height
|
||||
if node.editor.top > 0 then node.editor.top = node.editor.top - node.editor.line_height end
|
||||
--? print('top', node.editor.top)
|
||||
end
|
||||
node.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, scale(Viewport.y-node.y))
|
||||
node.editor.top = node.editor.top + Menu_bar_height
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
function pan_viewport_to_contain_cursor(node)
|
||||
print('viewport', Viewport.y)
|
||||
local safety_margin = 2*node.editor.line_height
|
||||
cursor1 = {39, 1}
|
||||
print('safety margin', safety_margin, 'dvpx')
|
||||
print('node', node.y)
|
||||
local cursor_sy = node.y + y_of_schema1(node.editor, node.editor.cursor1)/Viewport.zoom
|
||||
if Text.lt1({line=1, pos=1}, node.editor.screen_top1) then
|
||||
Viewport.y = node.y + y_of_schema1(node.editor, node.editor.screen_top1)/Viewport.zoom
|
||||
end
|
||||
if cursor_sy > Viewport.y + App.screen.height/Viewport.zoom - safety_margin then
|
||||
print('cursor below viewport')
|
||||
local cursor_y = y_of_schema1(node.editor, node.editor.cursor1)
|
||||
if Viewport.y < node.y then
|
||||
-- node starts within Viewport
|
||||
print('node starts within viewport')
|
||||
local max_cursor_y = App.screen.height - scale(node.y - Viewport.y) - safety_margin
|
||||
if cursor_y > max_cursor_y then
|
||||
-- set Viewport.y so cursor_y == max_cursor_y
|
||||
-- equation: cursor_y == App.screen.height - (node.y - Viewport.y)*Viewport.zoom - safety_margin
|
||||
-- solve for Viewport.y
|
||||
Viewport.y = node.y - (App.screen.height - cursor_y - safety_margin)/Viewport.zoom
|
||||
print('adjusting Viewport to', Viewport.y)
|
||||
end
|
||||
else
|
||||
-- node extends above Viewport
|
||||
print('node extends above viewport')
|
||||
local screen_top_y = y_of_schema1(node.editor, node.editor.screen_top1)
|
||||
local min_screen_top_y = cursor_y + safety_margin - App.screen.height
|
||||
if screen_top_y < min_screen_top_y then
|
||||
screen_top_y = min_screen_top_y
|
||||
Viewport.y = node.y + screen_top_y/Viewport.zoom
|
||||
print('adjusting Viewport to', Viewport.y)
|
||||
end
|
||||
end
|
||||
elseif cursor_sy < Viewport.y + safety_margin then
|
||||
print('cursor above viewport')
|
||||
local cursor_y = y_of_schema1(node.editor, node.editor.cursor1)
|
||||
if Viewport.y < node.y then
|
||||
-- node starts within Viewport
|
||||
print('node starts within viewport')
|
||||
local max_cursor_y = App.screen.height - scale(node.y - Viewport.y) - safety_margin
|
||||
if cursor_y > max_cursor_y then
|
||||
-- set Viewport.y so cursor_y == max_cursor_y
|
||||
-- equation: cursor_y == App.screen.height - (node.y - Viewport.y)*Viewport.zoom - safety_margin
|
||||
-- solve for Viewport.y
|
||||
Viewport.y = node.y - (App.screen.height - cursor_y - safety_margin)/Viewport.zoom
|
||||
print('adjusting Viewport to', Viewport.y)
|
||||
end
|
||||
else
|
||||
-- node extends above Viewport
|
||||
print('node extends above viewport')
|
||||
local screen_top_y = y_of_schema1(node.editor, node.editor.screen_top1)
|
||||
local max_screen_top_y = cursor_y - safety_margin
|
||||
if screen_top_y > max_screen_top_y then
|
||||
screen_top_y = max_screen_top_y
|
||||
Viewport.y = node.y + screen_top_y/Viewport.zoom
|
||||
print('adjusting Viewport to', Viewport.y)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -22,23 +22,23 @@ Panning:
|
|||
✓ page-down positions cursor on bottom line
|
||||
✓ mouse panning
|
||||
tall node extending below viewport
|
||||
x repeated down arrow near bottom pans down
|
||||
✓ repeated down arrow near bottom pans down
|
||||
✓ repeated up arrow
|
||||
✓ repeated down arrow
|
||||
✓ repeated pagedown
|
||||
✓ repeated pageup
|
||||
✓ pageup
|
||||
✓ mouse panning
|
||||
tall node extending above viewport
|
||||
✓ repeated up arrow near top pans up
|
||||
✓ repeated down arrow
|
||||
✓ repeated up arrow
|
||||
✓ repeated pagedown
|
||||
✓ pagedown
|
||||
✓ repeated pageup
|
||||
✓ mouse panning
|
||||
tall node extending both below and above viewport
|
||||
✓ repeated up arrow near top pans up
|
||||
✓ repeated down arrow
|
||||
x repeated down arrow near bottom pans down
|
||||
✓ repeated down arrow near bottom pans down
|
||||
✓ repeated up arrow
|
||||
✓ repeated pagedown
|
||||
✓ repeated pageup
|
||||
|
@ -48,20 +48,20 @@ Panning:
|
|||
short node entirely within viewer, cursor in middle of screen
|
||||
✓ arrow keys
|
||||
✓ page-up positions cursor on top line
|
||||
x page-down positions cursor on bottom line
|
||||
✓ page-down positions cursor on bottom line
|
||||
✓ mouse panning
|
||||
tall node extending below viewport
|
||||
x repeated down arrow near bottom pans down
|
||||
✓ repeated down arrow near bottom pans down
|
||||
✓ repeated up arrow
|
||||
✓ repeated down arrow
|
||||
x repeated pagedown
|
||||
✓ repeated pageup
|
||||
✓ repeated pagedown
|
||||
✓ pageup
|
||||
✓ mouse panning
|
||||
tall node extending above viewport
|
||||
✓ repeated up arrow near top pans up
|
||||
✓ repeated down arrow
|
||||
✓ repeated up arrow
|
||||
✓ repeated pagedown
|
||||
✓ pagedown
|
||||
✓ repeated pageup
|
||||
✓ mouse panning
|
||||
tall node extending both below and above viewport
|
||||
|
@ -77,13 +77,13 @@ Panning:
|
|||
short node entirely within viewer, cursor in middle of screen
|
||||
✓ arrow keys
|
||||
✓ page-up positions cursor on top line
|
||||
x page-down positions cursor on bottom line
|
||||
✓ page-down positions cursor on bottom line
|
||||
✓ mouse panning
|
||||
tall node extending below viewport
|
||||
x repeated down arrow near bottom pans down
|
||||
✓ repeated down arrow near bottom pans down
|
||||
✓ repeated up arrow
|
||||
✓ repeated down arrow
|
||||
x repeated pagedown
|
||||
✓ repeated pagedown
|
||||
✓ repeated pageup
|
||||
✓ mouse panning
|
||||
tall node extending above viewport
|
||||
|
|
Loading…
Reference in New Issue