start rendering file picker on the surface as well

This will make things more consistent in the long term, but I realize
one major cost: our button abstraction doesn't work well with luaML and
compute_layout. So we need something to replace it.
This commit is contained in:
Kartik K. Agaram 2023-06-21 22:22:13 -07:00
parent 387dfe4f33
commit c8cd9bb6b6
18 changed files with 140 additions and 101 deletions

View File

@ -1,8 +1,18 @@
on.mouse_press = function(x,y, mouse_button)
if mouse_press_consumed_by_any_button_handler(Global_state, x,y, mouse_button) then
if Cursor_node then
Cursor_node.show_cursor = nil
Cursor_node = nil
end
if mouse_press_consumed_by_any_button_handler(HUD, x,y, mouse_button) then
return
end
if Global_state.root then
mouse_press_on_surface(x,y, mouse_button)
local node = on_text(x,y)
if node then
-- position cursor in node
Cursor_node = node
edit.mouse_press(node.editor, x,y, mouse_button)
return
end
-- pan surface
Pan = {x=Viewport.x+x/Viewport.zoom,y=Viewport.y+y/Viewport.zoom}
end

View File

@ -1 +1 @@
Viewport = {x=-50, y=-50, w=800,h=600, zoom=1.0}
Viewport = {}

View File

@ -1,6 +1,4 @@
on.code_change = function()
print('code changed')
if Global_state.root then
A()
end
A()
end

View File

@ -1,12 +1,8 @@
on.initialize = function()
reset_viewport()
love.graphics.setFont(love.graphics.newFont(20))
local font = love.graphics.getFont()
font:setLineHeight(1.3)
Files = love.filesystem.getDirectoryItems('data')
for i=#Files,1,-1 do
if (not Files[i]:match('%.md$')) or Files[i]:match('%-%d+.md$') then
table.remove(Files, i)
end
end
table.sort(Files)
initialize_file_picker()
A()
end

View File

@ -23,8 +23,8 @@ compute_layout = function(node, x,y, nodes_to_render, preserve_screen_top_of_cur
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local width = love.graphics.getFont():getWidth(s)/Viewport.zoom
for i,line in ipairs(node.data) do
local width = love.graphics.getFont():getWidth(line.data)/Viewport.zoom
if node.w < width then node.w = width end
end
end
@ -101,4 +101,4 @@ compute_layout = function(node, x,y, nodes_to_render, preserve_screen_top_of_cur
end
end
return x+node.w,y+node.h
end
end

View File

@ -1,7 +1,9 @@
on.keychord_press = function(chord, key)
print('key', chord)
-- a little weird that zoom works even in file picker mode
if chord == 'C-=' then
if Global_state.thread and chord == 'C-o' then
Global_state.thread = nil
reset_viewport()
elseif chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
@ -15,7 +17,48 @@ on.keychord_press = function(chord, key)
-- reset zoom
Viewport.zoom = 1.0
B()
elseif Global_state.root then
keychord_press_on_surface(chord, key)
elseif Cursor_node then
local old_top = {line=Cursor_node.editor.screen_top1.line, pos=Cursor_node.editor.screen_top1.pos}
edit.keychord_press(Cursor_node.editor, chord, key)
if not eq(Cursor_node.editor.screen_top1, old_top) then
Viewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)
end
if chord == 'return' then
A(--[[preserve screen_top of cursor node]] true)
else
B(--[[preserve screen_top of cursor node]] true)
end
else
if chord == 'up' then
Viewport.y = Viewport.y - scale(20)
B()
elseif chord == 'down' then
Viewport.y = Viewport.y + scale(20)
B()
elseif chord == 'left' then
Viewport.x = Viewport.x - scale(50)
B()
elseif chord == 'right' then
Viewport.x = Viewport.x + scale(50)
B()
elseif chord == 'pageup' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
B()
elseif chord == 'S-up' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
B()
elseif chord == 'pagedown' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
B()
elseif chord == 'S-down' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
B()
elseif chord == 'S-left' then
Viewport.x = Viewport.x - App.screen.width/Viewport.zoom
B()
elseif chord == 'S-right' then
Viewport.x = Viewport.x + App.screen.width/Viewport.zoom
B()
end
end
end
end

View File

@ -1,9 +1,25 @@
on.draw = function()
Global_state.button_handlers = {}
if Global_state.root == nil then
-- TODO: use surface for file picker as well
draw_file_picker()
else
draw_surface()
for _,obj in ipairs(Surface) do
love.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)
if obj.type == 'rectangle' then
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h), scale(obj.rx or 5), scale(obj.rx or obj.ry or 5))
elseif obj.type == 'line' then
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'circle' then
love.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))
elseif obj.type == 'arc' then
love.graphics.arc(obj.drawmode or 'line', obj.arctype or 'open', vx(obj.x), vy(obj.y), scale(obj.radius), obj.angle1, obj.angle2, obj.segments)
elseif obj.type == 'ellipse' then
love.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))
elseif obj.type == 'bezier' then
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg, not obj.show_cursor)
end
end
end
end
draw_menu_bar()
end

View File

@ -1,12 +1 @@
Surface = {
-- test data
{type='line', data={0,-1000, 0,1000}},
{type='line', data={-10000,0, 10000,0}},
{type='text', data={'0'}, x=-20,y=-30},
{type='rectangle', x=50,y=50, w=20,h=80, r=1,g=0,b=0},
{type='text', data={'abc', 'def'}, x=150, y=50, w=50,h=50, fg={r=0,g=0.4, b=0.9}},
{type='circle', x=300,y=200, radius=40, r=1,g=0,b=1},
{type='arc', x=0,y=0, radius=50, angle1=0, angle2=math.pi*2/3},
{type='ellipse', x=100,y=100, radiusx=10, radiusy=50},
{type='bezier', data={25,25, 25,125, 75,25, 125,25}},
}
Surface = {}

8
0028-A
View File

@ -1,9 +1,13 @@
A = function(preserve_screen_top_of_cursor_node)
-- print('A')
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font
-- translate Global_state.root to Surface
-- translate some page in Global_state to Surface
Surface = {}
compute_layout(Global_state.root, 0,0, Surface, preserve_screen_top_of_cursor_node)
if Global_state.file_picker then
lay_out_file_picker()
elseif Global_state.thread then
compute_layout(Global_state.thread, 0,0, Surface, preserve_screen_top_of_cursor_node)
end
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice

View File

@ -16,4 +16,4 @@ update_editor_box = function(node, preserve_screen_top_of_cursor_node)
node.editor.left = math.floor(vx(node.x))
node.editor.right = math.ceil(vx(node.x+node.w))
node.editor.width = node.editor.right - node.editor.left
end
end

View File

@ -1,3 +1,4 @@
Global_state = {}
-- button_handlers: for the file picker
-- root: when reading a single thread
-- contains screens to render
-- * file_picker: array of nodes to render on startup
-- * thread: single node containing a single post and its comments

View File

@ -22,4 +22,4 @@ draw_surface = function()
end
end
draw_menu_bar()
end
end

View File

@ -1,6 +1,6 @@
open_thread = function(filename)
Global_state.root = rows()
load_subtree(filename, Global_state.root.data, 0)
Global_state.thread = rows()
load_subtree(filename, Global_state.thread.data, 0)
love.window.setTitle('pothi.love - '..filename)
A()
end

View File

@ -1,52 +0,0 @@
keychord_press_on_surface = function(chord, key)
if chord == 'C-o' then
Global_state = {}
love.graphics.setFont(love.graphics.newFont(20))
local font = love.graphics.getFont()
font:setLineHeight(1.3)
Viewport = {x=-50, y=-50, w=800,h=600, zoom=1.0}
elseif Cursor_node then
local old_top = {line=Cursor_node.editor.screen_top1.line, pos=Cursor_node.editor.screen_top1.pos}
edit.keychord_press(Cursor_node.editor, chord, key)
if not eq(Cursor_node.editor.screen_top1, old_top) then
Viewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)
end
if chord == 'return' then
A(--[[preserve screen_top of cursor node]] true)
else
B(--[[preserve screen_top of cursor node]] true)
end
else
if chord == 'up' then
Viewport.y = Viewport.y - scale(20)
B()
elseif chord == 'down' then
Viewport.y = Viewport.y + scale(20)
B()
elseif chord == 'left' then
Viewport.x = Viewport.x - scale(50)
B()
elseif chord == 'right' then
Viewport.x = Viewport.x + scale(50)
B()
elseif chord == 'pageup' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
B()
elseif chord == 'S-up' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
B()
elseif chord == 'pagedown' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
B()
elseif chord == 'S-down' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
B()
elseif chord == 'S-left' then
Viewport.x = Viewport.x - App.screen.width/Viewport.zoom
B()
elseif chord == 'S-right' then
Viewport.x = Viewport.x + App.screen.width/Viewport.zoom
B()
end
end
end

3
0128-reset_viewport Normal file
View File

@ -0,0 +1,3 @@
reset_viewport = function()
Viewport = {x=-50, y=-50, w=800,h=600, zoom=1.0}
end

View File

@ -0,0 +1,19 @@
initialize_file_picker = function()
Files = love.filesystem.getDirectoryItems('data')
for i=#Files,1,-1 do
if (not Files[i]:match('%.md$')) or Files[i]:match('%-%d+.md$') then
table.remove(Files, i)
end
end
table.sort(Files)
Global_state.file_picker = {}
for _,f in ipairs(Files) do
table.insert(Global_state.file_picker, {
type='text',
data={{data=f}},
rx=5,
bg={r=0.7, g=0.7, b=1.0},
border={r=0.4, g=0.4, b=0.7}
})
end
end

11
0130-lay_out_file_picker Normal file
View File

@ -0,0 +1,11 @@
lay_out_file_picker = function()
local x,y = 0,0
for _,n in ipairs(Global_state.file_picker) do
local x2,y2 = compute_layout(n, x,y, Surface)
if x2 < 1000 then
x = x2 + File_picker_margin
else
x,y = 0,y2+File_picker_margin
end
end
end

1
0131-File_picker_margin Normal file
View File

@ -0,0 +1 @@
File_picker_margin = 20 -- around each file button in all directions