NTYP3TWGASXUIEJOGZL5XL5CGZVJ6RCAVO3ZFGCCDIAHQ6FE6TKAC
DXFOMHQIWZ6EAUIDZQLY3ZRRDWJRB2VQHJXHBBNXQYCYCABIMJ5QC
J4UN4JK4DGKXKNB65JNAHYZDYP4TKRNFFDZLUAVK7SLFIQYHIFEQC
VPSAM3ZZVVGUSP5VEEMPOTQSY3XSY2H4D6RQW7RLDFVB6RS7ORRAC
MISEW25VIMXQ6ID37VQ365KAMPQ5O4COYWEIK6M4JXKIG7L5DVSQC
6L225AP7UON4CQ7NPGLMK2JXQNPZOS4FL5SSIJINNQRCRVJKLSWQC
CCPQONNNZGI6OOZTUR4FE4OAWEF7DH6UUCCS647WU2SYYFBWQ65QC
EZHO4TSWIYYUE73S6XQWIEF3HA3H7MKCNJOT27NTWTVSPVS2SL5QC
R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC
QJAYOFWY7V4BWVLJMEDCCBC2HX4BDAZI6PQVLWCLYRHWGMOBFTVAC
PPVABNGQTQMPYILHDNSNXBI5IOCBSIYO45NIHUR4LYPABQZE6PAQC
VHT5NALKBXY6CZ2AJPLIJ33OSP5X2TF6GTDMIYXVKNIXPZXPAMAAC
UO6BAQV7RDN2O6SHZ2WNLQPGRVIYK2IRERWEI4TDRU7HBCPYS64AC
TBPJ5WSRM5IKQH7FTAVYTWWUBWW7G2CLT5M6FN7CMPLD6Y77YIWQC
4TL2FLYP36JS4K6QBXZBCFCTIBMIT7OAF7KMAAFGPAF5OWSP4QFAC
X7HYGAL2QVKG7M5EMZ2VSH37UYWGE3EPUXYQBJOVL6IGJFZ2I5AAC
TTMMK6S6ILBQ6YN6H2DR5I5PH4ZUITWAGG72AJWLKLKGO5AATT2AC
BF7TW3EKRIDYC6J2Q2J4YOBAVQF55Y3H6KGZIHNXMH4N72MR6GXQC
KV64IWA3DKR4FL6E4BIG5SFCRQJ3DZFEJOUELCD5TC7DDVJQ6SWAC
ZQMQVMFWZIGWBRCB455IKHPTAOUYPLYCSC44NBPPET557RGVRX3AC
JIBCE66ZTWM5WEHEHNKKTRWBJQSQWBDDWPMOJIJR5Q676OSHYCNAC
FAZW23IDQ6JTXYSJXB5XEALXTWXSDRTDDBBIOWIOKPQ2R3S3WUMQC
PHJEOJAWCHNI4CGTSAJQTWM3UFP6N6J3ZF2TRSSIR4S42OF2PZUQC
63XNR7IQGIKE43QMIYG23DZRHXOOP6NYTH5O3WWFJF7CVYWMPACQC
4WW67KAXORLJFOJVWV3CP4VNHTEIJY5WQMSDMXMFKRWSI5EEHTRAC
Q2C4QGRCXKMCWMEQJT2OJMC5A3OIYKWPQBU4U3QWICEJHFXO6LPQC
FBDRJ53NJ5BWDQGU2GWZ6NEYHKCCRD7RODMIG7QQZBRFUB4HR7OAC
OLCKKDVSDTIBX5U3IRCLRL6KQMG2RDWKGDN4OTPI3WMN4FSX6ROQC
PWV23PO6MZBZ33JSURWRUADIHI6O2E3N7EWGQ5VWIL67PYWOKA2QC
LRDM35CEK3OHXOTB7TEFJRL7P6PQWO5ZG3F2BVA7DIDFHBPJQ7KAC
GDBDGLRHJSMN527PHXGZVSGF55EYT4X3GFNF4LF6363JE2FGBQXQC
FS2ITYYHBLFT66YUC3ENPFYI2HOYHOVEPQIN7NQR6KF5MEK4NKZAC
2DVVKKVA6PJ7VKYLGPQ22AXUB6ZWFMPWB445PRDZJDNLURUFDNDQC
{"on.text_input":388,"font":353,"scale":7,"Cursor_node":172,"on.draw":418,"A":426,"vx":5,"add_thick_line":400,"Viewport":303,"Surface":422,"update_editor_box":430,"vy":8,"line_height":365,"to_text":180,"copy_shape":396,"fw_parent":429,"on.mouse_press":179,"Page2":429,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"y_of_schema1":364,"on.code_change":306,"Page":381,"on":1,"schema1_of_y":366,"B":379}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"on.text_input":388,"vy":8,"scale":7,"y_of_schema1":364,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"on":1,"Page":381,"Page2":429,"vx":5,"font":353,"fw_parent":428,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"A":426,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"on.text_input":388,"vy":8,"scale":7,"y_of_schema1":364,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"on":1,"Page":381,"Page2":428,"vx":5,"font":353,"fw_parent":427,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"A":426,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"on.text_input":388,"vy":8,"scale":7,"y_of_schema1":364,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"on":1,"Page":381,"Page2":427,"vx":5,"font":353,"fw_parent":426,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"A":426,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"on.text_input":388,"vy":8,"scale":7,"y_of_schema1":364,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"on":1,"Page":381,"Page2":425,"vx":5,"font":353,"fw_parent":425,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"A":426,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"on.text_input":388,"vy":8,"scale":7,"y_of_schema1":364,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"on":1,"Page":381,"Page2":425,"vx":5,"font":353,"fw_parent":424,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"A":421,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"on.text_input":388,"vy":8,"scale":7,"y_of_schema1":364,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"on":1,"Page":381,"Page2":424,"vx":5,"font":353,"fw_parent":422,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"A":421,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"B":379,"vy":8,"scale":7,"A":421,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"Page2":423,"vx":5,"font":353,"fw_parent":422,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"y_of_schema1":364,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":421,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":421,"to_text":180,"line_height":365,"Surface":422,"add_thick_line":400,"y_of_schema1":364,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":421,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":420,"to_text":180,"line_height":365,"Surface":420,"add_thick_line":400,"y_of_schema1":364,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":417,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":419,"to_text":180,"line_height":365,"Surface":420,"add_thick_line":400,"y_of_schema1":364,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":417,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":418,"to_text":180,"line_height":365,"Surface":419,"add_thick_line":400,"y_of_schema1":364,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":417,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":417,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":418,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":417,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":416,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":416,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":415,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":415,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":414,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":414,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":413,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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
A(--[[preserve screen_top of cursor node]] true)
end
end
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":413,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":412,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":412,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":411,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":411,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":410,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":410,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":409,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":409,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":408,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":408,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":407,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":407,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":406,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":406,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":405,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":405,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":404,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":404,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":403,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
on.update = function(dt)
if Pan then
end
if App.mouse_down(1) then
B()
end
end
Viewport.x = Pan.x - App.mouse_x()
Viewport.y = Pan.y - App.mouse_y()
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":403,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":402,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"scale":7,"A":402,"on.text_input":388,"schema1_of_y":366,"on.mouse_press":179,"on.initialize":350,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"on":1,"on.code_change":306,"B":379,"vx":5,"font":353,"fw_parent":400,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"y_of_schema1":364,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":401,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":400,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"on.text_input":388,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":399,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":399,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":400,"on.text_input":388,"on.draw":346,"Cursor_node":172}
B = function()
-- recompute various aspects based on the current viewport settings
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update it
for _,obj in ipairs(Surface) do
if obj.type == 'line' then
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
elseif obj.type == 'bezier' then
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
if obj.w then
initialize_editor(obj)
else
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
end
end
end
end
B = function()
-- recompute various aspects based on the current viewport settings
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update it
for _,obj in ipairs(Surface) do
if obj.type == 'line' then
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
elseif obj.type == 'bezier' then
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
if obj.w then
update_editor_box(obj)
else
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
end
end
end
end
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":399,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":398,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":397,"on.text_input":388,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":398,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":397,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":397,"on.text_input":388,"on.draw":346,"Cursor_node":172}
box_height = function(node)
-- return the height of a node. The result is scaled.
print('computing box height based on font size', node.scaled_fontsize, node.editor.font_height, node.editor.line_height)
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
table.insert(Box_heights, y)
end
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":394,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":396,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":397,"on.text_input":388,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"copy_shape":396,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":394,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":395,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":395,"on.text_input":388,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"Viewport":303,"vy":8,"on.code_change":306,"scale":7,"A":394,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":394,"to_text":180,"line_height":365,"Surface":196,"add_thick_line":395,"on.text_input":388,"on.draw":346,"Cursor_node":172}
on.update = function(dt)
if Pan then
end
if App.mouse_down(1) then
B()
clip_all()
end
end
Viewport.x = Pan.x - App.mouse_x()
Viewport.y = Pan.y - App.mouse_y()
{"update_editor_box":377,"Viewport":303,"vy":8,"scale":7,"A":394,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":393,"to_text":180,"line_height":365,"Surface":196,"on.code_change":306,"on.text_input":388,"on.draw":346,"Cursor_node":172}
{"update_editor_box":377,"Viewport":303,"vy":8,"scale":7,"A":393,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":392,"to_text":180,"line_height":365,"Surface":196,"on.code_change":306,"on.text_input":388,"on.draw":346,"Cursor_node":172}
update_editor_box = function(obj)
if obj.editor == nil then return end
obj.editor.top = vy(obj.y)
obj.editor.left = math.floor(vx(obj.x))
obj.editor.right = math.ceil(vx(obj.x+obj.w))
edit.update_font_settings(obj.editor, scale(20))
Text.redraw_all(obj.editor)
end
{"update_editor_box":377,"Viewport":303,"vy":8,"scale":7,"A":392,"schema1_of_y":366,"on.mouse_press":179,"y_of_schema1":364,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":350,"on":1,"Page":381,"B":379,"vx":5,"font":353,"fw_parent":391,"to_text":180,"line_height":365,"Surface":196,"on.code_change":306,"on.text_input":388,"on.draw":346,"Cursor_node":172}
{"on.mouse_press":179,"B":379,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"Page":381,"line_height":365,"update_editor_box":377,"font":353,"on.code_change":306,"on.text_input":388,"Surface":196,"vy":8,"Cursor_node":172,"on.draw":346,"fw_parent":390,"schema1_of_y":366,"vx":5,"Viewport":303,"on":1,"to_text":180,"on.initialize":350,"y_of_schema1":364,"A":387,"scale":7}
{"on.mouse_press":179,"B":379,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"box_height":345,"on.keychord_press":390,"compute_layout":385,"Page":381,"line_height":365,"update_editor_box":377,"font":353,"on.code_change":306,"on.text_input":388,"Surface":196,"vy":8,"Cursor_node":172,"on.draw":346,"fw_parent":389,"schema1_of_y":366,"vx":5,"Viewport":303,"on":1,"to_text":180,"on.initialize":350,"y_of_schema1":364,"A":387,"scale":7}
{"Cursor_node":172,"scale":7,"on.update":368,"to_text":180,"font":353,"on.text_input":388,"on":1,"schema1_of_y":366,"A":387,"initialize_editor":338,"on.initialize":350,"y_of_schema1":364,"Page":381,"B":379,"on.draw":346,"box_height":345,"vx":5,"on.keychord_press":389,"Viewport":303,"compute_layout":385,"on.mouse_release":367,"vy":8,"on.code_change":306,"update_editor_box":377,"Surface":196,"fw_parent":388,"on.mouse_press":179,"line_height":365}
{"Cursor_node":172,"scale":7,"on.update":368,"to_text":180,"font":353,"on.text_input":388,"on":1,"schema1_of_y":366,"A":387,"initialize_editor":338,"on.initialize":350,"y_of_schema1":364,"Page":381,"B":379,"on.draw":346,"box_height":345,"vx":5,"on.keychord_press":383,"Viewport":303,"compute_layout":385,"on.mouse_release":367,"vy":8,"on.code_change":306,"update_editor_box":377,"Surface":196,"fw_parent":387,"on.mouse_press":179,"line_height":365}
{"Cursor_node":172,"scale":7,"on.update":368,"to_text":180,"font":353,"on.text_input":382,"on":1,"schema1_of_y":366,"A":387,"initialize_editor":338,"on.initialize":350,"y_of_schema1":364,"Page":381,"B":379,"on.draw":346,"box_height":345,"vx":5,"on.keychord_press":383,"Viewport":303,"compute_layout":385,"on.mouse_release":367,"vy":8,"on.code_change":306,"update_editor_box":377,"Surface":196,"fw_parent":386,"on.mouse_press":179,"line_height":365}
{"Cursor_node":172,"scale":7,"on.update":368,"to_text":180,"font":353,"on.text_input":382,"on":1,"schema1_of_y":366,"A":386,"initialize_editor":338,"on.initialize":350,"y_of_schema1":364,"Page":381,"B":379,"on.draw":346,"box_height":345,"vx":5,"on.keychord_press":383,"Viewport":303,"compute_layout":385,"on.mouse_release":367,"vy":8,"on.code_change":306,"update_editor_box":377,"Surface":196,"fw_parent":385,"on.mouse_press":179,"line_height":365}
{"on.code_change":306,"fw_parent":384,"Surface":196,"schema1_of_y":366,"on.draw":346,"font":353,"Cursor_node":172,"Viewport":303,"y_of_schema1":364,"update_editor_box":377,"vx":5,"vy":8,"on.text_input":382,"to_text":180,"line_height":365,"scale":7,"on.mouse_press":179,"A":309,"on":1,"on.mouse_release":367,"on.update":368,"B":379,"on.keychord_press":383,"box_height":345,"initialize_editor":338,"compute_layout":385,"Page":381,"on.initialize":350}
{"on.code_change":306,"fw_parent":383,"Surface":196,"schema1_of_y":366,"on.draw":346,"font":353,"Cursor_node":172,"Viewport":303,"y_of_schema1":364,"update_editor_box":377,"vx":5,"vy":8,"on.text_input":382,"to_text":180,"line_height":365,"scale":7,"on.mouse_press":179,"A":309,"on":1,"on.mouse_release":367,"on.update":368,"B":379,"on.keychord_press":383,"box_height":345,"initialize_editor":338,"compute_layout":384,"Page":381,"on.initialize":350}
{"on.code_change":306,"fw_parent":382,"Surface":196,"schema1_of_y":366,"on.draw":346,"font":353,"Cursor_node":172,"Viewport":303,"y_of_schema1":364,"update_editor_box":377,"vx":5,"vy":8,"on.text_input":382,"to_text":180,"line_height":365,"scale":7,"on.mouse_press":179,"A":309,"on":1,"on.mouse_release":367,"on.update":368,"B":379,"on.keychord_press":383,"box_height":345,"initialize_editor":338,"compute_layout":354,"Page":381,"on.initialize":350}
{"on.code_change":306,"fw_parent":381,"Surface":196,"schema1_of_y":366,"on.draw":346,"font":353,"Cursor_node":172,"Viewport":303,"y_of_schema1":364,"update_editor_box":377,"vx":5,"vy":8,"on.text_input":382,"to_text":180,"line_height":365,"scale":7,"on.mouse_press":179,"A":309,"on":1,"on.mouse_release":367,"on.update":368,"B":379,"on.keychord_press":376,"box_height":345,"initialize_editor":338,"compute_layout":354,"Page":381,"on.initialize":350}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
----[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), math.floor(vx(obj.x)), math.ceil(vx(obj.x+obj.w)), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"vy":8,"schema1_of_y":366,"on.keychord_press":376,"to_text":180,"initialize_editor":338,"on.update":368,"on.initialize":350,"y_of_schema1":364,"A":309,"box_height":345,"compute_layout":354,"Page":381,"B":379,"on.mouse_release":367,"on":1,"scale":7,"on.mouse_press":179,"on.text_input":177,"Surface":196,"on.code_change":306,"fw_parent":380,"line_height":365,"Cursor_node":172,"vx":5,"update_editor_box":377,"Viewport":303,"on.draw":346,"font":353}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
{"compute_layout":354,"Page":380,"schema1_of_y":366,"fw_parent":379,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":379,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":377,"on.update":368,"box_height":345,"on.keychord_press":376}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":378,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":379,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":377,"on.update":368,"box_height":345,"on.keychord_press":376}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":377,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":378,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":377,"on.update":368,"box_height":345,"on.keychord_press":376}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":376,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":377,"on.update":368,"box_height":345,"on.keychord_press":376}
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":375,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":372,"on.update":368,"box_height":345,"on.keychord_press":376}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":374,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":372,"on.update":368,"box_height":345,"on.keychord_press":375}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":373,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":372,"on.update":368,"box_height":345,"on.keychord_press":374}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":372,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":372,"on.update":368,"box_height":345,"on.keychord_press":373}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":371,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":372,"on.update":368,"box_height":345,"on.keychord_press":311}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":370,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":371,"on.update":368,"box_height":345,"on.keychord_press":311}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":369,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":370,"on.update":368,"box_height":345,"on.keychord_press":311}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":368,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":369,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":358,"on.update":368,"box_height":345,"on.keychord_press":311}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":367,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":352,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":358,"on.update":368,"box_height":345,"on.keychord_press":311}
{"compute_layout":354,"Page":344,"schema1_of_y":366,"fw_parent":366,"Cursor_node":172,"on":1,"on.initialize":350,"y_of_schema1":364,"A":309,"on.draw":346,"font":353,"vx":5,"B":352,"Viewport":303,"initialize_editor":338,"line_height":365,"vy":8,"on.code_change":306,"Surface":196,"on.text_input":177,"to_text":180,"on.mouse_press":179,"scale":7,"on.mouse_release":367,"update_editor_box":358,"on.update":355,"box_height":345,"on.keychord_press":311}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":366,"y_of_schema1":364,"to_text":180,"Page":344,"line_height":365,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":365,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":363,"y_of_schema1":364,"to_text":180,"Page":344,"line_height":365,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":364,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":363,"y_of_schema1":364,"to_text":180,"Page":344,"line_height":362,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":363,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":363,"to_text":180,"Page":344,"line_height":362,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":362,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":360,"to_text":180,"Page":344,"line_height":362,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":361,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":360,"to_text":180,"Page":344,"line_height":361,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":360,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":360,"to_text":180,"Page":344,"on.draw":346,"on":1,"A":309,"on.initialize":350,"Viewport":303,"fw_parent":358,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"Surface":196,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"schema1_of_y":359,"Surface":196,"to_text":180,"on.draw":346,"on.initialize":350,"A":309,"on":1,"Viewport":303,"Page":344,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"fw_parent":358,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(font(20), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
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)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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 == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
elseif obj.type == 'bezier' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
end
end
end
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(font(20), node.data)
local width = text:getWidth()
print(node.data[i], 'has width', width)
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
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)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"box_height":345,"on.keychord_press":311,"compute_layout":354,"on.code_change":306,"Cursor_node":172,"font":353,"Surface":196,"to_text":180,"on.draw":346,"on.initialize":350,"A":309,"on":1,"Viewport":303,"Page":344,"B":352,"vy":8,"scale":7,"on.text_input":177,"update_editor_box":358,"vx":5,"on.mouse_press":179,"fw_parent":357,"on.mouse_release":178,"initialize_editor":338,"on.update":355}
{"box_height":345,"on.mouse_release":178,"compute_layout":354,"on.update":355,"on.text_input":177,"A":309,"B":352,"Surface":196,"font":353,"on.code_change":306,"fw_parent":356,"on.initialize":350,"on.draw":346,"Cursor_node":172,"vx":5,"on.keychord_press":311,"Viewport":303,"scale":7,"Page":344,"vy":8,"on.mouse_press":179,"update_editor_box":351,"on":1,"initialize_editor":338,"to_text":180}
{"box_height":345,"on.mouse_release":178,"compute_layout":354,"on.update":355,"on.text_input":177,"A":309,"B":352,"Surface":196,"font":353,"on.code_change":306,"fw_parent":355,"clip":236,"on.initialize":350,"on.draw":346,"Cursor_node":172,"vx":5,"on.keychord_press":311,"Viewport":303,"scale":7,"Page":344,"vy":8,"on.mouse_press":179,"update_editor_box":351,"on":1,"initialize_editor":338,"to_text":180}
{"box_height":345,"on.mouse_release":178,"compute_layout":354,"on.update":355,"on.text_input":177,"A":309,"B":352,"Surface":196,"font":353,"clip_all":265,"on.code_change":306,"fw_parent":354,"clip":236,"on.initialize":350,"on.draw":346,"Cursor_node":172,"vx":5,"on.keychord_press":311,"Viewport":303,"scale":7,"Page":344,"vy":8,"on.mouse_press":179,"update_editor_box":351,"on":1,"initialize_editor":338,"to_text":180}
B = function()
-- editor objects implicitly depend on current font so update it
love.graphics.setFont(love.graphics.newFont(scale(20)))
for _,obj in ipairs(Surface) do
if obj.type == 'line' then
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
elseif obj.type == 'bezier' then
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
if obj.w then
initialize_editor(obj)
else
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
end
end
end
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
----[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), math.ceil(vx(obj.x+obj.w)), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"on.text_input":177,"vx":5,"to_text":180,"vy":8,"A":309,"fw_parent":353,"on.mouse_press":179,"B":352,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":354,"Viewport":303,"on":1,"Page":344,"on.initialize":350,"font":353,"scale":7,"update_editor_box":351,"Cursor_node":172,"Surface":196,"clip":236,"on.code_change":306,"clip_all":265,"on.draw":346}
{"on.text_input":177,"vx":5,"to_text":180,"vy":8,"A":309,"fw_parent":352,"on.mouse_press":179,"B":352,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":349,"Viewport":303,"on":1,"Page":344,"on.initialize":350,"font":353,"scale":7,"update_editor_box":351,"Cursor_node":172,"Surface":196,"clip":236,"on.code_change":306,"clip_all":265,"on.draw":346}
{"Cursor_node":172,"vy":8,"on.mouse_press":179,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":349,"to_text":180,"Page":344,"on.code_change":306,"clip":236,"font":228,"on.text_input":177,"scale":7,"on":1,"clip_all":265,"Surface":196,"update_editor_box":351,"B":352,"on.draw":346,"on.initialize":350,"vx":5,"A":309,"Viewport":303,"fw_parent":351}
{"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":349,"on.code_change":306,"update_editor_box":351,"on.text_input":177,"on.initialize":350,"scale":7,"Surface":196,"A":309,"vy":8,"on.draw":346,"B":316,"vx":5,"initialize_editor":338,"Viewport":303,"on":1,"fw_parent":350,"Cursor_node":172,"font":228,"clip":236,"Page":344,"clip_all":265}
{"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":349,"on.code_change":306,"on.text_input":177,"on.initialize":350,"scale":7,"Surface":196,"A":309,"vy":8,"on.draw":346,"B":316,"vx":5,"initialize_editor":338,"Viewport":303,"on":1,"fw_parent":349,"Cursor_node":172,"font":228,"clip":236,"Page":344,"clip_all":265}
{"on.mouse_press":179,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":349,"Cursor_node":172,"to_text":180,"Page":344,"on.text_input":177,"Surface":196,"clip":236,"on.code_change":306,"on.draw":346,"on":1,"vx":5,"fw_parent":348,"Viewport":303,"on.initialize":304,"clip_all":265,"vy":8,"A":309,"scale":7,"B":316}
{"on.mouse_press":179,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":348,"Cursor_node":172,"to_text":180,"Page":344,"on.text_input":177,"Surface":196,"clip":236,"on.code_change":306,"on.draw":346,"on":1,"vx":5,"fw_parent":347,"Viewport":303,"on.initialize":304,"clip_all":265,"vy":8,"A":309,"scale":7,"B":316}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
{"on.mouse_press":179,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":335,"Cursor_node":172,"to_text":180,"Page":344,"on.text_input":177,"Surface":196,"clip":236,"on.code_change":306,"on.draw":346,"on":1,"vx":5,"fw_parent":346,"Viewport":303,"on.initialize":304,"clip_all":265,"vy":8,"A":309,"scale":7,"B":316}
{"on.mouse_press":179,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":335,"Cursor_node":172,"to_text":180,"Page":344,"on.text_input":177,"Surface":196,"clip":236,"on.code_change":306,"on.draw":346,"on":1,"vx":5,"fw_parent":345,"Viewport":303,"on.initialize":304,"clip_all":265,"vy":8,"A":309,"Box_heights":277,"scale":7,"B":316}
{"on.mouse_press":179,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":345,"on.keychord_press":311,"compute_layout":335,"Cursor_node":172,"to_text":180,"Page":344,"on.text_input":177,"Surface":196,"clip":236,"on.code_change":306,"on.draw":310,"on":1,"vx":5,"fw_parent":344,"Viewport":303,"on.initialize":304,"clip_all":265,"vy":8,"A":309,"Box_heights":277,"scale":7,"B":316}
{"Page":344,"on.text_input":177,"Surface":196,"A":309,"on.draw":310,"vx":5,"to_text":180,"on.initialize":304,"compute_layout":335,"Viewport":303,"B":316,"on.code_change":306,"vy":8,"scale":7,"Cursor_node":172,"clip":236,"on.mouse_press":179,"clip_all":265,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":317,"on.keychord_press":311,"on":1,"fw_parent":343,"Box_heights":277}
Page2 = {
x=500, y=300,
-- page
type='text',
data={
"Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me."
},
width=400, bg={r=0.8,g=0,b=0.8}
}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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
A(--[[preserve screen_top of cursor node]] true)
else
if chord == 'up' then
Viewport.y = Viewport.y - scale(20)
elseif chord == 'down' then
Viewport.y = Viewport.y + scale(20)
elseif chord == 'left' then
Viewport.x = Viewport.x - scale(50)
elseif chord == 'right' then
Viewport.x = Viewport.x + scale(50)
elseif chord == 'pageup' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
elseif chord == 'S-up' then
Viewport.y = Viewport.y - App.screen.height/Viewport.zoom
elseif chord == 'pagedown' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
elseif chord == 'S-down' then
Viewport.y = Viewport.y + App.screen.height/Viewport.zoom
elseif chord == 'S-left' then
Viewport.x = Viewport.x - App.screen.width/Viewport.zoom
elseif chord == 'S-right' then
Viewport.x = Viewport.x + App.screen.width/Viewport.zoom
end
end
end
{"Page":343,"on.text_input":177,"Surface":196,"A":309,"on.draw":310,"vx":5,"to_text":180,"on.initialize":304,"compute_layout":335,"Viewport":303,"B":316,"on.code_change":306,"vy":8,"scale":7,"Cursor_node":172,"clip":236,"on.mouse_press":179,"clip_all":265,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":317,"on.keychord_press":311,"on":1,"fw_parent":342,"Box_heights":277}
{"Page":342,"on.text_input":177,"Surface":196,"A":309,"on.draw":310,"vx":5,"to_text":180,"on.initialize":304,"compute_layout":335,"Viewport":303,"B":316,"on.code_change":306,"vy":8,"scale":7,"Cursor_node":172,"clip":236,"on.mouse_press":179,"clip_all":265,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":317,"on.keychord_press":311,"on":1,"fw_parent":341,"Box_heights":277}
{"Page":341,"on.text_input":177,"Surface":196,"A":309,"on.draw":310,"vx":5,"to_text":180,"on.initialize":304,"compute_layout":335,"Viewport":303,"B":316,"on.code_change":306,"vy":8,"scale":7,"Cursor_node":172,"clip":236,"on.mouse_press":179,"clip_all":265,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":317,"on.keychord_press":311,"on":1,"fw_parent":340,"Box_heights":277}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B()
end
{"Page":340,"on.text_input":177,"Surface":196,"A":309,"on.draw":310,"vx":5,"to_text":180,"on.initialize":304,"compute_layout":335,"Viewport":303,"B":316,"on.code_change":306,"vy":8,"scale":7,"Cursor_node":172,"clip":236,"on.mouse_press":179,"clip_all":265,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":317,"on.keychord_press":311,"on":1,"fw_parent":339,"Box_heights":277}
{"Page":339,"on.text_input":177,"Surface":196,"A":309,"on.draw":310,"vx":5,"to_text":180,"on.initialize":304,"compute_layout":335,"Viewport":303,"B":316,"on.code_change":306,"vy":8,"scale":7,"Cursor_node":172,"clip":236,"on.mouse_press":179,"clip_all":265,"font":228,"on.mouse_release":178,"initialize_editor":338,"on.update":315,"box_height":317,"on.keychord_press":311,"on":1,"fw_parent":338,"Box_heights":277}
{"on.mouse_release":178,"Box_heights":277,"on":1,"on.keychord_press":311,"Page":324,"A":309,"on.update":315,"on.text_input":177,"clip_all":265,"fw_parent":337,"Surface":196,"scale":7,"on.code_change":306,"on.draw":310,"font":228,"vx":5,"Cursor_node":172,"Viewport":303,"clip":236,"on.mouse_press":179,"vy":8,"initialize_editor":338,"box_height":317,"B":316,"compute_layout":335,"on.initialize":304,"to_text":180}
{"on.initialize":304,"Surface":196,"B":316,"on.draw":310,"on":1,"vx":5,"on.mouse_release":178,"Viewport":303,"initialize_editor":337,"box_height":317,"vy":8,"compute_layout":335,"to_text":180,"Page":324,"on.keychord_press":311,"Box_heights":277,"on.mouse_press":179,"on.code_change":306,"Cursor_node":172,"font":228,"clip":236,"fw_parent":336,"clip_all":265,"scale":7,"on.text_input":177,"on.update":315,"A":309}
{"on.mouse_release":178,"initialize_editor":336,"on.update":315,"to_text":180,"compute_layout":335,"A":309,"box_height":317,"Box_heights":277,"Page":324,"clip":236,"on.code_change":306,"on.text_input":177,"Surface":196,"on":1,"on.draw":310,"vx":5,"clip_all":265,"Viewport":303,"B":316,"vy":8,"scale":7,"fw_parent":335,"Cursor_node":172,"font":228,"on.initialize":304,"on.mouse_press":179,"on.keychord_press":311}
{"fw_parent":334,"font":228,"on.mouse_release":178,"on.update":315,"box_height":317,"on.keychord_press":311,"compute_layout":335,"to_text":180,"Page":324,"clip":236,"on.code_change":306,"scale":7,"on.initialize":304,"Surface":196,"A":309,"on.draw":310,"Box_heights":277,"initialize_editor":333,"vx":5,"on.mouse_press":179,"Viewport":303,"on":1,"Cursor_node":172,"vy":8,"B":316,"clip_all":265,"on.text_input":177}
{"fw_parent":333,"font":228,"on.mouse_release":178,"on.update":315,"box_height":317,"on.keychord_press":311,"compute_layout":334,"to_text":180,"Page":324,"clip":236,"on.code_change":306,"scale":7,"on.initialize":304,"Surface":196,"A":309,"on.draw":310,"Box_heights":277,"initialize_editor":333,"vx":5,"on.mouse_press":179,"Viewport":303,"on":1,"Cursor_node":172,"vy":8,"B":316,"clip_all":265,"on.text_input":177}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print('init', obj.data[1], obj.w)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"fw_parent":332,"font":228,"on.mouse_release":178,"on.update":315,"box_height":317,"on.keychord_press":311,"compute_layout":301,"to_text":180,"Page":324,"clip":236,"on.code_change":306,"scale":7,"on.initialize":304,"Surface":196,"A":309,"on.draw":310,"Box_heights":277,"initialize_editor":333,"vx":5,"on.mouse_press":179,"Viewport":303,"on":1,"Cursor_node":172,"vy":8,"B":316,"clip_all":265,"on.text_input":177}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":331,"box_height":317,"on.mouse_press":179,"initialize_editor":332,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":330,"box_height":317,"on.mouse_press":179,"initialize_editor":331,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":329,"box_height":317,"on.mouse_press":179,"initialize_editor":330,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
Page = {
-- page
type='rows', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":328,"box_height":317,"on.mouse_press":179,"initialize_editor":329,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":327,"box_height":317,"on.mouse_press":179,"initialize_editor":328,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
schema1_of_y = function(editor, y)
-- return line/pos of screen line starting near a given y offset,
-- and the (negative) offset remaining after the calculation
-- invariants:
-- - 0 >= y_offset >= -Line_height
-- - let loc, y_offset = schema1_of_y(pane, y)
-- y + y_offset == y_of_schema1(pane, loc)
assert(y >= 0)
local y_offset = y
for i=1,#editor.lines do
Text.populate_screen_line_starting_pos(editor, i)
local height = line_height(editor, i)
if y_offset < height then
local line = editor.lines[i]
local nlines = math.floor(y_offset/editor.line_height)
assert(nlines >= 0 and nlines < #editor.line_cache[i].screen_line_starting_pos)
local pos = editor.line_cache[i].screen_line_starting_pos[nlines+1] -- switch to 1-indexing
y_offset = y_offset - nlines*editor.line_height
return {line=i, pos=pos}, -y_offset
end
y_offset = y_offset - height
end
-- y is below the pane
return {line=#pane.lines+1, pos=1}, y_offset -- positive value
end
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":326,"box_height":317,"on.mouse_press":179,"initialize_editor":327,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":325,"box_height":317,"on.mouse_press":179,"initialize_editor":326,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":324,"box_height":317,"on.mouse_press":179,"initialize_editor":325,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":324,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":323,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":323,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":322,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":322,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":321,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":321,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":320,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":320,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":319,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":319,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":318,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":318,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":317,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"on.keychord_press":311,"scale":7,"Page":312,"on.code_change":306,"clip":236,"clip_all":265,"on.text_input":177,"Surface":196,"on.initialize":304,"font":228,"A":309,"vx":5,"Box_heights":277,"Viewport":303,"B":316,"compute_layout":301,"vy":8,"Cursor_node":172,"on":1,"fw_parent":316,"box_height":317,"on.mouse_press":179,"initialize_editor":313,"on.mouse_release":178,"to_text":180,"on.update":315,"on.draw":310}
{"clip":236,"on.mouse_release":178,"clip_all":265,"on.update":315,"box_height":297,"on.keychord_press":311,"compute_layout":301,"scale":7,"Page":312,"Box_heights":277,"to_text":180,"B":316,"Surface":196,"Cursor_node":172,"on.draw":310,"font":228,"vx":5,"on.code_change":306,"Viewport":303,"on.text_input":177,"A":309,"vy":8,"fw_parent":315,"on.initialize":304,"on":1,"initialize_editor":313,"on.mouse_press":179}
box_height = function(node)
-- return the height of a node. The result is scaled.
print('computing box height based on font size', node.scaled_fontsize, node.editor.font_height, node.editor.line_height)
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
table.insert(Box_heights, y)
end
end
return y
end
{"Box_heights":277,"on.text_input":177,"B":314,"on.mouse_press":179,"on":1,"Surface":196,"clip_all":265,"clip":236,"on.draw":310,"Viewport":303,"scale":7,"on.update":315,"on.keychord_press":311,"Page":312,"on.mouse_release":178,"vy":8,"initialize_editor":313,"box_height":297,"to_text":180,"compute_layout":301,"vx":5,"fw_parent":314,"Cursor_node":172,"on.initialize":304,"font":228,"A":309,"on.code_change":306}
{"Box_heights":277,"on.text_input":177,"B":314,"on.mouse_press":179,"on":1,"Surface":196,"clip_all":265,"clip":236,"on.draw":310,"Viewport":303,"scale":7,"on.update":239,"on.keychord_press":311,"Page":312,"on.mouse_release":178,"vy":8,"initialize_editor":313,"box_height":297,"to_text":180,"compute_layout":301,"vx":5,"fw_parent":313,"Cursor_node":172,"on.initialize":304,"font":228,"A":309,"on.code_change":306}
{"Viewport":303,"Box_heights":277,"vy":8,"A":309,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"B":308,"on.update":239,"fw_parent":312,"on.keychord_press":311,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":313,"Page":312,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":310,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"A":309,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"B":308,"on.update":239,"fw_parent":311,"on.keychord_press":311,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":312,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":310,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"A":309,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"B":308,"on.update":239,"fw_parent":310,"on.keychord_press":311,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":310,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"A":309,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"B":308,"on.update":239,"fw_parent":309,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":310,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"A":309,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"B":308,"on.update":239,"fw_parent":308,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":307,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"A":305,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"B":308,"on.update":239,"fw_parent":307,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":307,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"A":305,"on.update":239,"fw_parent":306,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":307,"clip":236,"vx":5}
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"Viewport":303,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"A":305,"on.update":239,"fw_parent":305,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":306,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":293,"clip":236,"vx":5}
on.draw = function()
for _,obj in ipairs(Surface) do
love.graphics.setColor(obj.r or 1, obj.g or 1, obj.b or 1)
if obj.type == 'rectangle' then
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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 == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
elseif obj.type == 'bezier' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
end
end
end
{"Viewport":303,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"A":305,"on.update":239,"fw_parent":304,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":293,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":239,"fw_parent":303,"on.keychord_press":200,"compute_layout":301,"clip_all":265,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"on.initialize":304,"on.draw":293,"clip":236,"vx":5}
{"Viewport":303,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":239,"fw_parent":302,"on.keychord_press":200,"compute_layout":301,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"clip_all":265,"on.draw":293,"clip":236,"vx":5}
{"Viewport":302,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":239,"fw_parent":301,"on.keychord_press":200,"compute_layout":301,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"clip_all":265,"on.draw":293,"clip":236,"vx":5}
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"Viewport":298,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":239,"fw_parent":300,"on.keychord_press":200,"compute_layout":301,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"clip_all":265,"on.draw":293,"clip":236,"vx":5}
Page2 = {
x=400, y=400,
-- page
type='text',
data={
"Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me."
},
width=400, bg={r=0.8,g=0,b=0.8}
}
{"Viewport":298,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":239,"fw_parent":299,"on.keychord_press":200,"compute_layout":235,"box_height":297,"Cursor_node":172,"initialize_editor":300,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"clip_all":265,"on.draw":293,"clip":236,"vx":5}
{"Viewport":298,"Box_heights":277,"vy":8,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"on.update":239,"fw_parent":298,"on.keychord_press":200,"compute_layout":235,"box_height":297,"Cursor_node":172,"initialize_editor":290,"Page":296,"font":228,"on.code_change":299,"scale":7,"on.text_input":177,"Surface":196,"on":1,"clip_all":265,"on.draw":293,"clip":236,"vx":5}
{"Page":296,"Cursor_node":172,"on.code_change":289,"to_text":180,"on.draw":293,"on.mouse_press":179,"vx":5,"clip":236,"Viewport":298,"clip_all":265,"on":1,"vy":8,"scale":7,"Surface":196,"fw_parent":297,"Box_heights":277,"font":228,"on.update":239,"on.mouse_release":178,"on.text_input":177,"initialize_editor":290,"box_height":297,"on.keychord_press":200,"compute_layout":235}
{"box_height":297,"on.keychord_press":200,"compute_layout":235,"Cursor_node":172,"on.code_change":289,"on.text_input":177,"Surface":196,"to_text":180,"on.draw":293,"vx":5,"scale":7,"Viewport":233,"clip":236,"initialize_editor":290,"clip_all":265,"Page":296,"vy":8,"font":228,"on.update":239,"on.mouse_press":179,"fw_parent":296,"on.mouse_release":178,"on":1,"Box_heights":277}
B = function(preserve_screen_top_of_cursor_node)
-- recompute various aspects based on the current viewport settings
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update it
for _,obj in ipairs(Surface) do
if obj.type == 'line' then
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
elseif obj.type == 'bezier' then
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
if obj.w then
update_editor_box(obj, preserve_screen_top_of_cursor_node)
else
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
end
end
end
end
{"box_height":295,"on.keychord_press":200,"compute_layout":235,"Cursor_node":172,"on.code_change":289,"on.text_input":177,"Surface":196,"to_text":180,"on.draw":293,"vx":5,"scale":7,"Viewport":233,"clip":236,"initialize_editor":290,"clip_all":265,"Page":296,"vy":8,"font":228,"on.update":239,"on.mouse_press":179,"fw_parent":295,"on.mouse_release":178,"on":1,"Box_heights":277}
{"box_height":295,"on.keychord_press":200,"compute_layout":235,"Cursor_node":172,"on.code_change":289,"on.text_input":177,"Surface":196,"to_text":180,"on.draw":293,"vx":5,"scale":7,"Viewport":233,"clip":236,"initialize_editor":290,"clip_all":265,"Page":263,"vy":8,"font":228,"on.update":239,"on.mouse_press":179,"fw_parent":294,"on.mouse_release":178,"on":1,"Box_heights":277}
{"box_height":294,"on.keychord_press":200,"compute_layout":235,"Cursor_node":172,"on.code_change":289,"on.text_input":177,"Surface":196,"to_text":180,"on.draw":293,"vx":5,"scale":7,"Viewport":233,"clip":236,"initialize_editor":290,"clip_all":265,"Page":263,"vy":8,"font":228,"on.update":239,"on.mouse_press":179,"fw_parent":293,"on.mouse_release":178,"on":1,"Box_heights":277}
{"Surface":196,"on.draw":293,"vx":5,"Viewport":233,"fw_parent":292,"on":1,"clip":236,"clip_all":265,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"font":228,"on.update":239,"on.keychord_press":200,"Cursor_node":172,"Box_heights":277,"vy":8,"Page":263,"on.code_change":289,"initialize_editor":290,"on.text_input":177,"box_height":291,"compute_layout":235,"scale":7}
{"fw_parent":291,"on.text_input":177,"to_text":180,"on.mouse_press":179,"on.mouse_release":178,"font":228,"on.update":239,"Page":263,"initialize_editor":290,"box_height":291,"on.keychord_press":200,"compute_layout":235,"clip":236,"clip_all":265,"Surface":196,"Box_heights":277,"on":1,"on.draw":292,"on.code_change":289,"Cursor_node":172,"vy":8,"Viewport":233,"vx":5,"scale":7}
{"fw_parent":290,"on.text_input":177,"to_text":180,"on.mouse_press":179,"on.mouse_release":178,"font":228,"on.update":239,"Page":263,"initialize_editor":290,"box_height":291,"on.keychord_press":200,"compute_layout":235,"clip":236,"clip_all":265,"Surface":196,"Box_heights":277,"on":1,"on.draw":286,"on.code_change":289,"Cursor_node":172,"vy":8,"Viewport":233,"vx":5,"scale":7}
{"on.code_change":289,"font":228,"Surface":196,"to_text":180,"clip_all":265,"on.draw":286,"on.text_input":177,"vx":5,"on":1,"Viewport":233,"fw_parent":289,"vy":8,"scale":7,"on.mouse_press":179,"Cursor_node":172,"on.mouse_release":178,"Box_heights":277,"on.update":239,"box_height":285,"on.keychord_press":200,"compute_layout":235,"clip":236,"initialize_editor":290,"Page":263}
{"Surface":196,"on.draw":286,"vx":5,"Viewport":233,"vy":8,"to_text":180,"on":1,"on.mouse_press":179,"scale":7,"on.mouse_release":178,"fw_parent":288,"clip_all":265,"box_height":285,"on.keychord_press":200,"compute_layout":235,"on.update":239,"initialize_editor":254,"Page":263,"clip":236,"on.text_input":177,"Box_heights":277,"on.code_change":289,"font":228,"Cursor_node":172}
{"Surface":196,"on.draw":286,"vx":5,"Viewport":233,"vy":8,"to_text":180,"on":1,"on.mouse_press":179,"scale":7,"on.mouse_release":178,"fw_parent":287,"clip_all":265,"box_height":285,"on.keychord_press":200,"compute_layout":235,"on.update":239,"initialize_editor":254,"Page":263,"clip":236,"on.text_input":177,"Box_heights":277,"on.code_change":288,"font":228,"Cursor_node":172}
{"on.code_change":287,"Surface":196,"clip_all":265,"on.draw":286,"on.text_input":177,"vx":5,"Viewport":233,"vy":8,"fw_parent":286,"on.mouse_press":179,"Box_heights":277,"on.mouse_release":178,"scale":7,"on.update":239,"initialize_editor":254,"box_height":285,"clip":236,"compute_layout":235,"on.keychord_press":200,"Page":263,"Cursor_node":172,"font":228,"on":1,"to_text":180}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":286,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":285,"box_height":285,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":280,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":284,"box_height":285,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(font(20), node.data)
local width = text:getWidth()
print(node.data[i], 'has width', width)
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
if node.width and 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)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(font(20), node.data)
local width = text:getWidth()
print(node.data[i], 'has width', width)
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"on.code_change":212,"font":228,"Surface":196,"on.draw":280,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":283,"box_height":284,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":280,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":282,"box_height":283,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
box_height = function(node)
-- return the height of a node. The result is scaled.
print('computing box height based on font size', node.scaled_fontsize, node.editor.font_height, node.editor.line_height)
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
table.insert(Box_heights, y)
end
end
return y
end
{"on.code_change":212,"font":228,"Surface":196,"on.draw":280,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":281,"box_height":282,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":280,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":280,"box_height":281,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":280,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":279,"box_height":278,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":279,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":278,"box_height":278,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":277,"box_height":278,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on":1,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":276,"box_height":276,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"Box_heights":277}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":275,"box_height":276,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":274,"box_height":275,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":273,"box_height":274,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":272,"box_height":273,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":272,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":271,"box_height":270,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,2000,300 do
for y=-10000,10000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
compute_layout(Page2, Page2.x,Page2.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
{"on.code_change":212,"font":228,"Surface":196,"on.draw":271,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":270,"box_height":270,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":266,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":269,"box_height":270,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":266,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":268,"box_height":269,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":266,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":267,"box_height":268,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":266,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":266,"box_height":267,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":266,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":265,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":264,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":265,"on.mouse_release":178,"Cursor_node":172,"fw_parent":264,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":264,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":241,"on.mouse_release":178,"Cursor_node":172,"fw_parent":263,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":262,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":241,"on.mouse_release":178,"Cursor_node":172,"fw_parent":262,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":263,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"font":228,"Surface":196,"on.draw":262,"vx":5,"Viewport":233,"to_text":180,"vy":8,"initialize_editor":254,"on.mouse_press":179,"clip_all":241,"on.mouse_release":178,"Cursor_node":172,"fw_parent":261,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on.update":239,"Page":243,"clip":236,"scale":7,"on":1}
{"on.code_change":212,"scale":7,"on.text_input":177,"Surface":196,"clip":236,"on.draw":261,"vx":5,"font":228,"Viewport":233,"on":1,"vy":8,"to_text":180,"on.mouse_press":179,"fw_parent":260,"on.mouse_release":178,"initialize_editor":254,"box_height":255,"on.keychord_press":200,"compute_layout":235,"Page":243,"on.update":239,"Cursor_node":172,"clip_all":241}
{"on.code_change":212,"scale":7,"on.text_input":177,"Surface":196,"clip":236,"on.draw":260,"vx":5,"font":228,"Viewport":233,"on":1,"vy":8,"to_text":180,"on.mouse_press":179,"fw_parent":259,"on.mouse_release":178,"initialize_editor":254,"box_height":255,"on.keychord_press":200,"compute_layout":235,"Page":243,"on.update":239,"Cursor_node":172,"clip_all":241}
{"Page":243,"on.code_change":212,"Surface":196,"to_text":180,"vx":5,"Viewport":233,"font":228,"initialize_editor":254,"vy":8,"Cursor_node":172,"on.mouse_press":179,"clip":236,"scale":7,"clip_all":241,"on.draw":259,"on.mouse_release":178,"fw_parent":258,"on.update":239,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on":1}
{"Page":243,"on.code_change":212,"Surface":196,"to_text":180,"vx":5,"Viewport":233,"font":228,"initialize_editor":254,"vy":8,"Cursor_node":172,"on.mouse_press":179,"clip":236,"scale":7,"clip_all":241,"on.draw":258,"on.mouse_release":178,"fw_parent":257,"on.update":239,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on":1}
schema1_of_y = function(editor, y)
-- return line/pos of screen line starting near a given y offset,
-- and the (negative) offset remaining after the calculation
-- invariants:
-- - 0 >= y_offset >= -Line_height
-- - let loc, y_offset = schema1_of_y(pane, y)
-- y + y_offset == y_of_schema1(pane, loc)
assert(y >= 0)
local y_offset = y
for i=1,#editor.lines do
Text.populate_screen_line_starting_pos(editor, i)
local height = line_height(editor, i, editor.left, editor.right)
if y_offset < height then
local line = editor.lines[i]
local nlines = math.floor(y_offset/editor.line_height)
assert(nlines >= 0 and nlines < #editor.line_cache[i].screen_line_starting_pos)
local pos = editor.line_cache[i].screen_line_starting_pos[nlines+1] -- switch to 1-indexing
y_offset = y_offset - nlines*editor.line_height
return {line=i, pos=pos}, -y_offset
end
y_offset = y_offset - height
end
-- y is below the pane
return {line=#pane.lines+1, pos=1}, y_offset -- positive value
end
{"Page":243,"on.code_change":212,"Surface":196,"to_text":180,"vx":5,"Viewport":233,"font":228,"initialize_editor":254,"vy":8,"Cursor_node":172,"on.mouse_press":179,"clip":236,"scale":7,"clip_all":241,"on.draw":257,"on.mouse_release":178,"fw_parent":256,"on.update":239,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on":1}
{"Page":243,"on.code_change":212,"Surface":196,"to_text":180,"vx":5,"Viewport":233,"font":228,"initialize_editor":254,"vy":8,"Cursor_node":172,"on.mouse_press":179,"clip":236,"scale":7,"clip_all":241,"on.draw":256,"on.mouse_release":178,"fw_parent":255,"on.update":239,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on":1}
{"Page":243,"on.code_change":212,"Surface":196,"to_text":180,"vx":5,"Viewport":233,"font":228,"initialize_editor":254,"vy":8,"Cursor_node":172,"on.mouse_press":179,"clip":236,"scale":7,"clip_all":241,"on.draw":234,"on.mouse_release":178,"fw_parent":254,"on.update":239,"box_height":255,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"on":1}
{"on.code_change":212,"on.text_input":177,"Surface":196,"to_text":180,"scale":7,"vx":5,"Viewport":233,"vy":8,"on":1,"Page":243,"fw_parent":253,"on.draw":234,"on.mouse_press":179,"clip":236,"on.mouse_release":178,"clip_all":241,"on.update":239,"box_height":250,"on.keychord_press":200,"compute_layout":235,"font":228,"initialize_editor":254,"Cursor_node":172}
{"font":228,"initialize_editor":253,"Surface":196,"Cursor_node":172,"on.draw":234,"fw_parent":252,"vx":5,"on":1,"on.text_input":177,"to_text":180,"on.mouse_release":178,"vy":8,"on.update":239,"box_height":250,"on.keychord_press":200,"compute_layout":235,"on.mouse_press":179,"clip_all":241,"Page":243,"Viewport":233,"clip":236,"on.code_change":212,"scale":7}
on.draw = function()
for _,obj in ipairs(Surface) do
color(obj.r or 1, obj.g or 1, obj.b or 1)
if obj.type == 'rectangle' then
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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 == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
elseif obj.type == 'bezier' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
end
end
end
{"initialize_editor":252,"on.mouse_press":179,"on.mouse_release":178,"Cursor_node":172,"on.update":239,"box_height":250,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"Page":243,"to_text":180,"on.code_change":212,"scale":7,"Surface":196,"on.draw":234,"vx":5,"font":228,"clip":236,"Viewport":233,"clip_all":241,"on":1,"vy":8,"fw_parent":251}
{"initialize_editor":251,"on.mouse_press":179,"on.mouse_release":178,"Cursor_node":172,"on.update":239,"box_height":250,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"Page":243,"to_text":180,"on.code_change":212,"scale":7,"Surface":196,"on.draw":234,"vx":5,"font":228,"clip":236,"Viewport":233,"clip_all":241,"on":1,"vy":8,"fw_parent":250}
{"initialize_editor":74,"on.mouse_press":179,"on.mouse_release":178,"Cursor_node":172,"on.update":239,"box_height":250,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"Page":243,"to_text":180,"on.code_change":212,"scale":7,"Surface":196,"on.draw":234,"vx":5,"font":228,"clip":236,"Viewport":233,"clip_all":241,"on":1,"vy":8,"fw_parent":249}
{"initialize_editor":74,"on.mouse_press":179,"on.mouse_release":178,"Cursor_node":172,"on.update":239,"box_height":249,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"Page":243,"to_text":180,"on.code_change":212,"scale":7,"Surface":196,"on.draw":234,"vx":5,"font":228,"clip":236,"Viewport":233,"clip_all":241,"on":1,"vy":8,"fw_parent":248}
{"initialize_editor":74,"on.mouse_press":179,"on.mouse_release":178,"Cursor_node":172,"on.update":239,"box_height":248,"on.keychord_press":200,"compute_layout":235,"on.text_input":177,"Page":243,"to_text":180,"on.code_change":212,"scale":7,"Surface":196,"on.draw":234,"vx":5,"font":228,"clip":236,"Viewport":233,"clip_all":241,"on":1,"vy":8,"fw_parent":247}
{"on.mouse_release":178,"on.update":239,"box_height":247,"on.keychord_press":200,"compute_layout":235,"fw_parent":246,"Page":243,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":239,"box_height":246,"on.keychord_press":200,"compute_layout":235,"fw_parent":245,"Page":243,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
to_text = function(x,y)
for _,node in ipairs(Surface) do
if node.type == 'text' then
print(x, y, node.data[1], node.x, node.y, node.w, node.h)
if x >= vx(node.x) and node.w and x < vx(node.x + node.w) then
if y >= vy(node.y) and node.h and y < vy(node.y + node.h) then
return node
end
end
end
end
end
update_editor_box = function(node, preserve_screen_top_of_cursor_node)
if node.editor == nil then return end
if node.y > Viewport.y then
if not preserve_screen_top_of_cursor_node or node ~= Cursor_node then
node.editor.screen_top1.line = 1
node.editor.screen_top1.pos = 1
end
node.editor.top = vy(node.y)
else
node.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, Viewport.y - node.y)
end
print('top', node.editor.top)
print('screen_top1', node.editor.screen_top1.line, node.editor.screen_top1.pos)
node.editor.left = math.floor(vx(node.x))
node.editor.right = math.ceil(vx(node.x+node.w))
edit.update_font_settings(node.editor, scale(20))
Text.redraw_all(node.editor)
end
{"on.mouse_release":178,"on.update":239,"box_height":245,"on.keychord_press":200,"compute_layout":235,"fw_parent":244,"Page":243,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":239,"box_height":244,"on.keychord_press":200,"compute_layout":235,"fw_parent":243,"Page":243,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":239,"box_height":44,"on.keychord_press":200,"compute_layout":235,"fw_parent":242,"Page":243,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
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))
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 or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"on.mouse_release":178,"on.update":239,"box_height":44,"on.keychord_press":200,"compute_layout":235,"fw_parent":241,"Page":242,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":239,"box_height":44,"on.keychord_press":200,"compute_layout":235,"fw_parent":240,"Page":202,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":241,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":239,"box_height":44,"on.keychord_press":200,"compute_layout":235,"fw_parent":239,"Page":202,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":240,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":239,"box_height":44,"on.keychord_press":200,"compute_layout":235,"fw_parent":238,"Page":202,"on.text_input":177,"on.code_change":212,"Surface":196,"on":1,"font":228,"to_text":180,"on.draw":234,"Viewport":233,"scale":7,"clip":236,"vy":8,"initialize_editor":74,"clip_all":237,"Cursor_node":172,"vx":5,"on.mouse_press":179}
{"vx":5,"on.text_input":177,"Viewport":233,"vy":8,"on.mouse_press":179,"on.mouse_release":178,"scale":7,"on.update":238,"to_text":180,"on.keychord_press":200,"compute_layout":235,"fw_parent":237,"Page":202,"clip_all":237,"box_height":44,"on.code_change":212,"Cursor_node":172,"initialize_editor":74,"on":1,"clip":236,"Surface":196,"on.draw":234,"font":228}
{"vx":5,"on.text_input":177,"Viewport":233,"vy":8,"on.mouse_press":179,"on.mouse_release":178,"scale":7,"on.update":14,"to_text":180,"on.keychord_press":200,"compute_layout":235,"fw_parent":236,"Page":202,"clip_all":237,"box_height":44,"on.code_change":212,"Cursor_node":172,"initialize_editor":74,"on":1,"clip":236,"Surface":196,"on.draw":234,"font":228}
{"vx":5,"on.text_input":177,"Viewport":233,"vy":8,"on.mouse_press":179,"on.mouse_release":178,"scale":7,"on.update":14,"to_text":180,"on.keychord_press":200,"compute_layout":235,"fw_parent":235,"Page":202,"box_height":44,"on.code_change":212,"Cursor_node":172,"initialize_editor":74,"on":1,"clip":236,"Surface":196,"on.draw":234,"font":228}
{"vx":5,"Viewport":233,"initialize_editor":74,"vy":8,"compute_layout":235,"scale":7,"on.mouse_press":179,"on.mouse_release":178,"on.text_input":177,"on.update":14,"font":228,"on.keychord_press":200,"to_text":180,"Page":202,"fw_parent":234,"on":1,"Surface":196,"box_height":44,"on.code_change":212,"on.draw":234,"Cursor_node":172}
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"vx":5,"Viewport":233,"initialize_editor":74,"vy":8,"compute_layout":229,"scale":7,"on.mouse_press":179,"on.mouse_release":178,"on.text_input":177,"on.update":14,"font":228,"on.keychord_press":200,"to_text":180,"Page":202,"fw_parent":233,"on":1,"Surface":196,"box_height":44,"on.code_change":212,"on.draw":234,"Cursor_node":172}
{"vx":5,"Viewport":233,"initialize_editor":74,"vy":8,"compute_layout":229,"scale":7,"on.mouse_press":179,"on.mouse_release":178,"on.text_input":177,"on.update":14,"font":228,"on.keychord_press":200,"to_text":180,"Page":202,"fw_parent":232,"on":1,"Surface":196,"box_height":44,"on.code_change":212,"on.draw":225,"Cursor_node":172}
{"vx":5,"Viewport":232,"initialize_editor":74,"vy":8,"compute_layout":229,"scale":7,"on.mouse_press":179,"on.mouse_release":178,"on.text_input":177,"on.update":14,"font":228,"on.keychord_press":200,"to_text":180,"Page":202,"fw_parent":231,"on":1,"Surface":196,"box_height":44,"on.code_change":212,"on.draw":225,"Cursor_node":172}
{"vx":5,"Viewport":231,"initialize_editor":74,"vy":8,"compute_layout":229,"scale":7,"on.mouse_press":179,"on.mouse_release":178,"on.text_input":177,"on.update":14,"font":228,"on.keychord_press":200,"to_text":180,"Page":202,"fw_parent":230,"on":1,"Surface":196,"box_height":44,"on.code_change":212,"on.draw":225,"Cursor_node":172}
{"vx":5,"Viewport":230,"initialize_editor":74,"vy":8,"compute_layout":229,"scale":7,"on.mouse_press":179,"on.mouse_release":178,"on.text_input":177,"on.update":14,"font":228,"on.keychord_press":200,"to_text":180,"Page":202,"fw_parent":229,"on":1,"Surface":196,"box_height":44,"on.code_change":212,"on.draw":225,"Cursor_node":172}
Page2 = {
x=800, y=400,
-- page
type='text',
data={
"Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me."
},
width=400, bg={r=0.8,g=0,b=0.8}
}
{"on.draw":225,"compute_layout":229,"vx":5,"font":228,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":228,"scale":7,"Viewport":227,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in ipairs(Box_heights) do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
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 or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"on.draw":225,"compute_layout":205,"vx":5,"font":228,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":227,"scale":7,"Viewport":227,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":225,"compute_layout":205,"vx":5,"font":224,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":226,"scale":7,"Viewport":227,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":225,"compute_layout":205,"vx":5,"font":224,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":225,"scale":7,"Viewport":226,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":225,"compute_layout":205,"vx":5,"font":224,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":224,"scale":7,"Viewport":221,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":223,"compute_layout":205,"vx":5,"font":224,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":223,"scale":7,"Viewport":221,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":223,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":222,"scale":7,"Viewport":221,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":222,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":221,"scale":7,"Viewport":221,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
schema1_of_y = function(editor, y)
-- return line/pos of screen line starting near a given y offset,
-- and the (negative) offset remaining after the calculation
-- invariants:
-- - 0 >= y_offset >= -Line_height
-- - let loc, y_offset = schema1_of_y(pane, y)
-- y + y_offset == y_of_schema1(pane, loc)
return {line=1, pos=1}, 0
assert(y >= 0)
local y_offset = y
for i=1,#editor.lines do
Text.populate_screen_line_starting_pos(editor, i)
local height = line_height(editor, i, editor.left, editor.right)
if y_offset < height then
local line = editor.lines[i]
local nlines = math.floor(y_offset/editor.line_height)
assert(nlines >= 0 and nlines < #editor.line_cache[i].screen_line_starting_pos)
local pos = editor.line_cache[i].screen_line_starting_pos[nlines+1] -- switch to 1-indexing
y_offset = y_offset - nlines*editor.line_height
return {line=i, pos=pos}, -y_offset
end
y_offset = y_offset - height
end
-- y is below the pane
return {line=#pane.lines+1, pos=1}, y_offset -- positive value
end
{"on.draw":220,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":220,"scale":7,"Viewport":221,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":220,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":219,"scale":7,"Viewport":217,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":219,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":218,"scale":7,"Viewport":217,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in ipairs(Box_heights) do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"on.draw":218,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":217,"scale":7,"Viewport":217,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":216,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":216,"scale":7,"Viewport":217,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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
B(--[[skip_cursor_node]] true)
end
end
{"on.draw":216,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":215,"scale":7,"Viewport":215,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
to_text = function(x,y)
for _,node in ipairs(Surface) do
if node.type == 'text' then
print(x, y, node.data[1], node.x, node.y, node.w, node.h)
if x >= node.x and node.w and x < node.x + node.w then
if y >= node.y and node.h and y < node.y + node.h then
return node
end
end
end
end
end
{"on.draw":211,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":214,"scale":7,"Viewport":215,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(20, node.data)
local width = text:getWidth()
print(node.data[i], 'has width', width)
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"on.draw":211,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":213,"scale":7,"Viewport":214,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":211,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":212,"scale":7,"Viewport":213,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":211,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":212,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":211,"scale":7,"Viewport":204,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":211,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":201,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":210,"scale":7,"Viewport":204,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":210,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":201,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":209,"scale":7,"Viewport":204,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"on.draw":209,"compute_layout":205,"vx":5,"font":104,"Cursor_node":172,"vy":8,"on.code_change":201,"on.text_input":177,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":200,"Page":202,"fw_parent":208,"scale":7,"Viewport":204,"on":1,"to_text":180,"Surface":196,"initialize_editor":74,"box_height":44}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":208,"vx":5,"Viewport":204,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":207,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":205,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":207,"vx":5,"Viewport":204,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":206,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":205,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":206,"vx":5,"Viewport":204,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":205,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":205,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":204,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":204,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":205,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":204,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":203,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":194,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":203,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":202,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":194,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":29,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":201,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":194,"on.text_input":177,"Page":202}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":29,"vy":8,"initialize_editor":74,"on":1,"on.code_change":201,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":200,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":194,"on.text_input":177,"Page":197}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":29,"vy":8,"initialize_editor":74,"on":1,"on.code_change":199,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":199,"on.update":14,"box_height":44,"on.keychord_press":200,"scale":7,"compute_layout":194,"on.text_input":177,"Page":197}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":29,"vy":8,"initialize_editor":74,"on":1,"on.code_change":199,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":198,"on.update":14,"box_height":44,"on.keychord_press":176,"scale":7,"compute_layout":194,"on.text_input":177,"Page":197}
{"Cursor_node":172,"font":104,"Surface":196,"on.draw":195,"vx":5,"Viewport":29,"vy":8,"initialize_editor":74,"on":1,"on.code_change":198,"on.mouse_press":179,"to_text":180,"on.mouse_release":178,"fw_parent":197,"on.update":14,"box_height":44,"on.keychord_press":176,"scale":7,"compute_layout":194,"on.text_input":177,"Page":197}
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":194,"Page":197,"on.code_change":190,"on.text_input":177,"Surface":196,"on":1,"on.draw":195,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":196,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":194,"Page":192,"on.code_change":190,"on.text_input":177,"Surface":196,"on":1,"on.draw":195,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":195,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
update_editor_box = function(obj)
if obj.editor == nil then return end
if obj.y > Viewport.y then
obj.editor.screen_top1.line = 1
obj.editor.screen_top1.pos = 1
obj.editor.top = vy(obj.y)
else
obj.editor.screen_top1, obj.editor.top = schema1_of_y(obj.editor, Viewport.y - obj.y)
end
print('top', obj.editor.top)
print('screen_top1', obj.editor.screen_top1.line, obj.editor.screen_top1.pos)
obj.editor.left = math.floor(vx(obj.x))
obj.editor.right = math.ceil(vx(obj.x+obj.w))
edit.update_font_settings(obj.editor, scale(20))
Text.redraw_all(obj.editor)
end
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":194,"Page":192,"on.code_change":190,"on.text_input":177,"Surface":165,"on":1,"on.draw":195,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":194,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":194,"Page":192,"on.code_change":190,"on.text_input":177,"Surface":165,"on":1,"on.draw":193,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":193,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":187,"Page":192,"on.code_change":190,"on.text_input":177,"Surface":165,"on":1,"on.draw":193,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":192,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":187,"Page":192,"on.code_change":190,"on.text_input":177,"Surface":165,"on":1,"on.draw":162,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":191,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
{"on.mouse_release":178,"on.update":14,"box_height":44,"font":104,"compute_layout":187,"Page":191,"on.code_change":190,"on.text_input":177,"Surface":165,"on":1,"on.draw":162,"vx":5,"scale":7,"Viewport":29,"Cursor_node":172,"vy":8,"fw_parent":190,"to_text":180,"initialize_editor":74,"on.keychord_press":176,"on.mouse_press":179}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":187,"Page":189,"on.update":14,"scale":7,"on":1,"on.code_change":190,"fw_parent":189,"on.mouse_press":179,"Surface":165}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":187,"Page":189,"on.update":14,"scale":7,"on":1,"on.code_change":188,"fw_parent":188,"on.mouse_press":179,"Surface":165}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":187,"Page":184,"on.update":14,"scale":7,"on":1,"on.code_change":188,"fw_parent":187,"on.mouse_press":179,"Surface":165}
compute_layout = function(node, x,y, nodes_to_render, preserve_screen_top_of_cursor_node)
-- 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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(font(20), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
if node.editor == nil then
initialize_editor(node)
else
update_editor_box(obj, preserve_screen_top_of_cursor_node)
end
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
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)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
----[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":187,"Page":184,"on.update":14,"scale":7,"on":1,"on.code_change":185,"fw_parent":186,"on.mouse_press":179,"Surface":165}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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
print('before', Viewport.y)
Viewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)
print('after', Viewport.y)
end
B(--[[skip_cursor_node]] true)
end
end
Surface = {
-- test data
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data={'0'}, x=-20,y=-20},
{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}},
}
Page2 = {
-- page
type='text',
data={
"Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me."
},
width=400, bg={r=0.8,g=0,b=0.8}
}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":186,"Page":184,"on.update":14,"scale":7,"on":1,"on.code_change":185,"fw_parent":185,"on.mouse_press":179,"Surface":165}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":157,"Page":184,"on.update":14,"scale":7,"on":1,"on.code_change":185,"fw_parent":184,"on.mouse_press":179,"Surface":165}
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
-- leaf node containing raw text
print(x,y, node.data[1])
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":157,"Page":184,"on.update":14,"scale":7,"on":1,"on.code_change":183,"fw_parent":183,"on.mouse_press":179,"Surface":165}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":157,"Page":181,"on.update":14,"scale":7,"on":1,"on.code_change":183,"fw_parent":182,"on.mouse_press":179,"Surface":165}
on.draw = function()
for _,obj in ipairs(Surface) do
color(obj.r or 1, obj.g or 1, obj.b or 1)
if obj.type == 'rect' then
rect(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
line(unpack(obj.zdata))
elseif obj.type == 'circle' then
circ(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 == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
elseif obj.type == 'bezier' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
line(unpack(obj.zdata))
end
end
end
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":157,"Page":181,"on.update":14,"scale":7,"on":1,"on.code_change":182,"fw_parent":181,"on.mouse_press":179,"Surface":165}
{"on.draw":162,"to_text":180,"vx":5,"Viewport":29,"vy":8,"Cursor_node":172,"font":104,"on.mouse_release":178,"on.text_input":177,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"compute_layout":157,"Page":181,"on.update":14,"scale":7,"on":1,"on.code_change":140,"fw_parent":180,"on.mouse_press":179,"Surface":165}
{"to_text":180,"on.mouse_press":179,"on.mouse_release":178,"initialize_editor":74,"box_height":44,"on.keychord_press":176,"on":1,"on.text_input":177,"font":104,"on.code_change":140,"fw_parent":179,"Surface":165,"on.draw":162,"vx":5,"Page":111,"Viewport":29,"compute_layout":157,"scale":7,"vy":8,"Cursor_node":172,"on.update":14}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"on.text_input":177,"vy":8,"on.mouse_press":179,"on.mouse_release":178,"on.update":14,"on.keychord_press":176,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":178}
on.draw = function()
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
print('draw rectangle', obj.x)
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
to_text = function(x,y)
for _,node in ipairs(Surface) do
if node.type == 'text' then
print(x, y, node.data[1], node.x, node.y, node.w, node.h)
if x >= node.x and x < node.x + node.w then
if y >= node.y and y < node.y + node.h then
return node
end
end
end
end
end
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"on.text_input":177,"vy":8,"on.mouse_press":174,"on.mouse_release":178,"on.update":14,"on.keychord_press":176,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":177}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"on.text_input":177,"vy":8,"on.mouse_press":174,"on.mouse_release":175,"on.update":14,"on.keychord_press":176,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":176}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"vy":8,"on.mouse_press":174,"on.mouse_release":175,"on.update":14,"on.keychord_press":176,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":175}
B = function()
for _,obj in ipairs(Surface) do
if obj.type == 'line' then
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
elseif obj.type == 'bezier' then
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
if obj.w then
initialize_editor(obj)
else
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
end
end
end
end
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"vy":8,"on.mouse_press":174,"on.mouse_release":175,"on.update":14,"on.keychord_press":17,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":174}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"vy":8,"on.mouse_press":174,"on.mouse_release":171,"on.update":14,"on.keychord_press":17,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":173}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"vy":8,"on.mouse_press":173,"on.mouse_release":171,"on.update":14,"on.keychord_press":17,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":172}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"vy":8,"on.mouse_press":169,"on.mouse_release":171,"on.update":14,"on.keychord_press":17,"Cursor_node":172,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":171}
{"Surface":165,"to_text":168,"on.code_change":140,"vx":5,"on":1,"Viewport":29,"vy":8,"on.mouse_press":169,"on.mouse_release":171,"on.update":14,"on.keychord_press":17,"on.draw":162,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"Page":111,"font":104,"fw_parent":169}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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
B(--[[preserve screen_top of cursor node]] true)
end
end
{"Surface":165,"to_text":168,"on.code_change":140,"fw_parent":169,"on":1,"Viewport":29,"vy":8,"on.mouse_press":169,"on.mouse_release":170,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
{"Surface":165,"to_text":168,"on.code_change":140,"fw_parent":168,"on":1,"Viewport":29,"vy":8,"on.mouse_press":169,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
{"Surface":165,"to_text":168,"on.code_change":140,"fw_parent":167,"on":1,"Viewport":29,"vy":8,"on.mouse_press":167,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
Surface = {
-- test data
{type='rect', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{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":165,"to_text":166,"on.code_change":140,"fw_parent":166,"on":1,"Viewport":29,"vy":8,"on.mouse_press":167,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
{"Surface":165,"to_text":166,"on.code_change":140,"fw_parent":165,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
elseif Cursor_node then
end
end
edit.keychord_press(Cursor_node.editor, chord, key)
on.keychord_press = function(chord, key)
{"Surface":165,"to_text":164,"on.code_change":140,"fw_parent":164,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
{"Surface":116,"to_text":164,"on.code_change":140,"fw_parent":163,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
to_text = function(x,y)
for _,node in ipairs(Surface) do
if node.type == 'text' then
print(node.data[1])
if x >= node.x and x < node.x + node.w then
if y >= node.y and y < node.y + node.h then
return node
end
end
end
end
end
{"Surface":116,"to_text":163,"on.code_change":140,"fw_parent":162,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
{"Surface":116,"to_text":159,"on.code_change":140,"fw_parent":161,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":162}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
----[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"Surface":116,"to_text":159,"on.code_change":140,"fw_parent":160,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":161}
{"Surface":116,"to_text":159,"on.code_change":140,"fw_parent":159,"on":1,"Viewport":29,"vy":8,"on.mouse_press":160,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":158}
{"Surface":116,"to_text":159,"on.code_change":140,"fw_parent":158,"on":1,"Viewport":29,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"vx":5,"initialize_editor":74,"box_height":44,"scale":7,"compute_layout":157,"font":104,"Page":111,"on.draw":158}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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
B(--[[skip_cursor_node]] true)
end
end
{"compute_layout":157,"on.keychord_press":17,"Page":111,"on.code_change":140,"scale":7,"Surface":116,"font":104,"on.draw":158,"vx":5,"Viewport":29,"fw_parent":157,"vy":8,"initialize_editor":74,"on.mouse_press":12,"on":1,"on.mouse_release":13,"box_height":44,"on.update":14}
{"compute_layout":157,"on.keychord_press":17,"Page":111,"on.code_change":140,"scale":7,"Surface":116,"font":104,"on.draw":155,"vx":5,"Viewport":29,"fw_parent":156,"vy":8,"initialize_editor":74,"on.mouse_press":12,"on":1,"on.mouse_release":13,"box_height":44,"on.update":14}
{"Viewport":29,"fw_parent":155,"vy":8,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":156,"Page":111,"on.code_change":140,"Surface":116,"scale":7,"on.draw":155,"font":104,"vx":5,"initialize_editor":74}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
{"Viewport":29,"fw_parent":154,"vy":8,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":154,"Page":111,"on.code_change":140,"Surface":116,"scale":7,"on.draw":155,"font":104,"vx":5,"initialize_editor":74}
Surface = {
{type='rect', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{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}},
}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":150,"vx":5,"Viewport":29,"vy":8,"fw_parent":153,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":154,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":150,"vx":5,"Viewport":29,"vy":8,"fw_parent":152,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":153,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":150,"vx":5,"Viewport":29,"vy":8,"fw_parent":151,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":152,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":150,"vx":5,"Viewport":29,"vy":8,"fw_parent":150,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":151,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":150,"vx":5,"Viewport":29,"vy":8,"fw_parent":149,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":149,"vx":5,"Viewport":29,"vy":8,"fw_parent":148,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":148,"vx":5,"Viewport":29,"vy":8,"fw_parent":147,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
on.text_input = function(t)
if Cursor_node then
local old_top = {line=Cursor_node.editor.screen_top1.line, pos=Cursor_node.editor.screen_top1.pos}
edit.text_input(Cursor_node.editor, t)
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
B(--[[preserve screen_top of cursor node]] true)
end
end
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":147,"vx":5,"Viewport":29,"vy":8,"fw_parent":146,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":146,"vx":5,"Viewport":29,"vy":8,"fw_parent":145,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":145,"vx":5,"Viewport":29,"vy":8,"fw_parent":144,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in ipairs(Box_heights) do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":144,"vx":5,"Viewport":29,"vy":8,"fw_parent":143,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
Page2 = {
-- page
type='text',
data={
'Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me.'
},
width=400, bg={r=0.8,g=0,b=0.8}
}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":143,"vx":5,"Viewport":29,"vy":8,"fw_parent":142,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
{"Page":111,"on.code_change":140,"Surface":116,"on":1,"on.draw":142,"vx":5,"Viewport":29,"vy":8,"fw_parent":141,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"font":104,"scale":7}
{"font":104,"initialize_editor":74,"on.mouse_press":12,"fw_parent":140,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"vy":8,"on.code_change":140,"Page":111,"on":1,"scale":7,"Viewport":29,"vx":5,"on.draw":141,"Surface":116,"compute_layout":122}
{"Surface":116,"on.code_change":140,"on.draw":139,"vx":5,"Viewport":29,"vy":8,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"initialize_editor":74,"Page":111,"fw_parent":139,"compute_layout":122,"scale":7,"font":104}
{"vy":8,"scale":7,"on.mouse_press":12,"Surface":116,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":122,"Page":111,"on.code_change":109,"fw_parent":138,"font":104,"vx":5,"on.update":14,"Viewport":29,"on.draw":139,"on":1}
{"font":104,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":122,"Page":111,"Surface":116,"on.code_change":109,"on.draw":138,"fw_parent":137,"Viewport":29,"vy":8,"on":1,"initialize_editor":74,"vx":5,"on.mouse_press":12,"scale":7,"on.mouse_release":13}
{"font":104,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":122,"Page":111,"Surface":116,"on.code_change":109,"on.draw":137,"fw_parent":136,"Viewport":29,"vy":8,"on":1,"initialize_editor":74,"vx":5,"on.mouse_press":12,"scale":7,"on.mouse_release":13}
{"font":104,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":122,"Page":111,"Surface":116,"on.code_change":109,"on.draw":136,"fw_parent":135,"Viewport":29,"vy":8,"on":1,"initialize_editor":74,"vx":5,"on.mouse_press":12,"scale":7,"on.mouse_release":13}
{"font":104,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":122,"Page":111,"Surface":116,"on.code_change":109,"on.draw":135,"fw_parent":125,"Viewport":29,"vy":8,"on":1,"initialize_editor":74,"vx":5,"on.mouse_press":12,"scale":7,"on.mouse_release":13}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
----[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"on.mouse_release":13,"scale":7,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":130,"Page":111,"on.code_change":134,"on.draw":133,"vx":5,"Viewport":29,"on.update":14,"vy":8,"font":104,"Surface":116,"on":1,"fw_parent":133,"on.mouse_press":12}
{"on.mouse_release":13,"scale":7,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":130,"Page":111,"on.code_change":129,"on.draw":133,"vx":5,"Viewport":29,"on.update":14,"vy":8,"font":104,"Surface":116,"on":1,"fw_parent":132,"on.mouse_press":12}
{"on.mouse_release":13,"scale":7,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":130,"Page":111,"on.code_change":129,"on.draw":132,"vx":5,"Viewport":29,"on.update":14,"vy":8,"font":104,"Surface":116,"on":1,"fw_parent":131,"on.mouse_press":12}
{"on.draw":131,"vx":5,"Viewport":29,"vy":8,"fw_parent":130,"font":104,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":130,"on":1,"scale":7,"on.code_change":129,"Page":111,"Surface":116,"on.update":14}
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
B()
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
B()
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
B()
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.screen_top1)
end
B(--[[skip_cursor_node]] true)
end
end
{"on.draw":128,"vx":5,"Viewport":29,"vy":8,"fw_parent":129,"font":104,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":130,"on":1,"scale":7,"on.code_change":129,"Page":111,"Surface":116,"on.update":14}
{"on.draw":128,"vx":5,"Viewport":29,"vy":8,"fw_parent":128,"font":104,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":127,"on":1,"scale":7,"on.code_change":129,"Page":111,"Surface":116,"on.update":14}
{"vx":5,"Viewport":29,"on":1,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"Page":111,"Surface":116,"on.draw":128,"fw_parent":127,"scale":7,"on.code_change":109,"initialize_editor":74,"box_height":44,"font":104,"compute_layout":127}
{"vx":5,"Viewport":29,"on":1,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"Page":111,"Surface":116,"on.draw":125,"fw_parent":126,"scale":7,"on.code_change":109,"initialize_editor":74,"box_height":44,"font":104,"compute_layout":127}
{"vx":5,"Viewport":29,"on":1,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"Page":111,"Surface":116,"on.draw":125,"fw_parent":125,"scale":7,"on.code_change":109,"initialize_editor":74,"box_height":44,"font":104,"compute_layout":126}
{"on.code_change":109,"on.draw":125,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":122,"fw_parent":124,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":124,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":122,"fw_parent":123,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":123,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":122,"fw_parent":122,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":119,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":122,"fw_parent":121,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":119,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":121,"fw_parent":120,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":119,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":120,"fw_parent":119,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":119,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":115,"fw_parent":118,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":118,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":115,"fw_parent":117,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":117,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":115,"fw_parent":116,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":113,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":115,"fw_parent":115,"box_height":44,"on":1,"Surface":116}
{"on.code_change":109,"on.draw":113,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":115,"fw_parent":114,"box_height":44,"on":1,"Surface":93}
{"on.code_change":109,"on.draw":113,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":114,"fw_parent":113,"box_height":44,"on":1,"Surface":93}
{"on.code_change":109,"on.draw":113,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":112,"fw_parent":112,"box_height":44,"on":1,"Surface":93}
{"on.code_change":109,"on.draw":105,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":112,"fw_parent":111,"box_height":44,"on":1,"Surface":93}
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in ipairs(Box_heights) do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"on.code_change":109,"on.draw":105,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":111,"compute_layout":107,"fw_parent":110,"box_height":44,"on":1,"Surface":93}
{"on.code_change":109,"on.draw":105,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":110,"compute_layout":107,"fw_parent":109,"box_height":44,"on":1,"Surface":93}
{"on.code_change":109,"on.draw":105,"font":104,"vx":5,"Viewport":29,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"initialize_editor":74,"on.keychord_press":17,"Page":76,"compute_layout":107,"fw_parent":108,"box_height":44,"on":1,"Surface":93}
{"vy":8,"compute_layout":107,"on.mouse_press":12,"on.mouse_release":13,"on.code_change":108,"scale":7,"on.keychord_press":17,"Page":76,"on":1,"Surface":93,"on.update":14,"on.draw":105,"font":104,"vx":5,"fw_parent":107,"Viewport":29,"initialize_editor":74,"box_height":44}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
--[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"vy":8,"compute_layout":107,"on.mouse_press":12,"on.mouse_release":13,"on.code_change":103,"scale":7,"on.keychord_press":17,"Page":76,"on":1,"Surface":93,"on.update":14,"on.draw":105,"font":104,"vx":5,"fw_parent":106,"Viewport":29,"initialize_editor":74,"box_height":44}
{"on.draw":105,"vx":5,"Viewport":29,"vy":8,"on":1,"fw_parent":105,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":106,"Page":76,"font":104,"on.code_change":103,"scale":7,"Surface":93,"on.update":14}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
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
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"on.draw":105,"vx":5,"Viewport":29,"vy":8,"on":1,"fw_parent":104,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":102,"Page":76,"font":104,"on.code_change":103,"scale":7,"Surface":93,"on.update":14}
{"on.draw":91,"vx":5,"Viewport":29,"vy":8,"on":1,"fw_parent":103,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":102,"Page":76,"font":104,"on.code_change":103,"scale":7,"Surface":93,"on.update":14}
{"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"Page":76,"scale":7,"initialize_editor":74,"Surface":93,"compute_layout":102,"on.draw":91,"vx":5,"on":1,"Viewport":29,"on.code_change":103,"vy":8,"fw_parent":102,"on.mouse_press":12}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":102,"scale":7,"Page":76,"on.code_change":98,"Surface":93,"fw_parent":101,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
box_height = function(node)
-- return the height of a node. The result is scaled.
print('computing box height based on font size', node.scaled_fontsize, node.editor.font_height, node.editor.line_height)
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
table.insert(Box_heights, y)
end
end
return y
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
update_editor_box = function(node, skip_cursor_node)
if node.editor == nil then return end
if skip_cursor_node and node == Cursor_node then return end
if node.y > Viewport.y then
node.editor.screen_top1.line = 1
node.editor.screen_top1.pos = 1
node.editor.top = vy(node.y)
else
node.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, Viewport.y - node.y)
end
print('top', node.editor.top)
print('screen_top1', node.editor.screen_top1.line, node.editor.screen_top1.pos)
node.editor.left = math.floor(vx(node.x))
node.editor.right = math.ceil(vx(node.x+node.w))
edit.update_font_settings(node.editor, scale(20))
Text.redraw_all(node.editor)
end
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":101,"scale":7,"Page":76,"on.code_change":98,"Surface":93,"fw_parent":100,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":100,"scale":7,"Page":76,"on.code_change":98,"Surface":93,"fw_parent":99,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":99,"scale":7,"Page":76,"on.code_change":98,"Surface":93,"fw_parent":98,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":95,"scale":7,"Page":76,"on.code_change":98,"Surface":93,"fw_parent":97,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":95,"scale":7,"Page":76,"on.code_change":97,"Surface":93,"fw_parent":96,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":95,"scale":7,"Page":76,"on.code_change":96,"Surface":93,"fw_parent":95,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":95,"scale":7,"Page":76,"on.code_change":94,"Surface":93,"fw_parent":94,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":92,"scale":7,"Page":76,"on.code_change":94,"Surface":93,"fw_parent":93,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":92,"scale":7,"Page":76,"on.code_change":89,"Surface":93,"fw_parent":92,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":92,"scale":7,"Page":76,"on.code_change":89,"Surface":70,"fw_parent":91,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('Creating text of size', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
print('aaaa', obj.text)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":75,"scale":7,"Page":76,"on.code_change":89,"Surface":70,"fw_parent":90,"on.draw":91,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,2000,300 do
for y=-10000,10000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":75,"scale":7,"Page":76,"on.code_change":89,"Surface":70,"fw_parent":89,"on.draw":90,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":75,"scale":7,"Page":76,"on.code_change":89,"Surface":70,"fw_parent":88,"on.draw":72,"vx":5,"Viewport":29,"on":1,"vy":8,"initialize_editor":74}
{"on":1,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":88,"scale":7,"Surface":70,"on.draw":72,"vx":5,"Viewport":29,"on.update":14,"vy":8,"fw_parent":87}
{"on":1,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":87,"scale":7,"Surface":70,"on.draw":72,"vx":5,"Viewport":29,"on.update":14,"vy":8,"fw_parent":86}
{"on":1,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":86,"scale":7,"Surface":70,"on.draw":72,"vx":5,"Viewport":29,"on.update":14,"vy":8,"fw_parent":85}
{"on":1,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":85,"scale":7,"Surface":70,"on.draw":72,"vx":5,"Viewport":29,"on.update":14,"vy":8,"fw_parent":83}
{"on":1,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":84,"scale":7,"Surface":70,"on.draw":72,"vx":5,"Viewport":29,"on.update":14,"vy":8,"fw_parent":83}
{"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on":1,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":83,"Surface":70,"on.draw":72,"vx":5,"fw_parent":81,"Viewport":29,"initialize_editor":74,"scale":7}
{"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on":1,"on.update":14,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":82,"Surface":70,"on.draw":72,"vx":5,"fw_parent":81,"Viewport":29,"initialize_editor":74,"scale":7}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
----[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
-- ]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"Viewport":29,"fw_parent":80,"vy":8,"scale":7,"on.mouse_press":12,"on.mouse_release":13,"initialize_editor":74,"box_height":44,"on.keychord_press":17,"compute_layout":75,"Page":76,"on.code_change":81,"Surface":70,"on":1,"on.draw":72,"on.update":14,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":78,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":75,"Page":76,"on.code_change":80,"Surface":70,"on.draw":72,"scale":7,"initialize_editor":74,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":78,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":75,"Page":76,"on.code_change":79,"Surface":70,"initialize_editor":74,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":77,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":75,"Page":76,"on.code_change":78,"Surface":70,"initialize_editor":74,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":76,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":75,"Page":76,"on.code_change":77,"Surface":70,"initialize_editor":74,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":75,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":75,"Page":76,"on.code_change":61,"Surface":70,"initialize_editor":74,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":74,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":75,"Page":39,"on.code_change":61,"Surface":70,"initialize_editor":74,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":73,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":73,"Page":39,"on.code_change":61,"Surface":70,"initialize_editor":74,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":72,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":73,"Page":39,"on.code_change":61,"Surface":70,"initialize_editor":71,"on.draw":72,"scale":7,"vx":5}
update_editor_box = function(node, skip_cursor_node)
if node.editor == nil then return end
if skip_cursor_node and node == Cursor_node then return end
if node.y > Viewport.y then
node.editor.screen_top1.line = 1
node.editor.screen_top1.pos = 1
node.editor.top = vy(node.y)
else
node.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, Viewport.y - node.y)
end
print('top', node.editor.top)
print('screen_top1', node.editor.screen_top1.line, node.editor.screen_top1.pos)
node.editor.left = math.floor(vx(node.x))
node.editor.right = math.ceil(vx(node.x+obj.w))
edit.update_font_settings(node.editor, scale(20))
Text.redraw_all(node.editor)
end
{"Viewport":29,"vy":8,"fw_parent":71,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":66,"Page":39,"on.code_change":61,"Surface":70,"initialize_editor":71,"on.draw":72,"scale":7,"vx":5}
{"Viewport":29,"vy":8,"fw_parent":70,"on":1,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"on.keychord_press":17,"box_height":44,"compute_layout":66,"Page":39,"on.code_change":61,"Surface":70,"initialize_editor":71,"on.draw":69,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":66,"Page":39,"vy":8,"fw_parent":69,"on":1,"on.draw":69,"on.keychord_press":17,"on.code_change":61,"Surface":70,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":66,"Page":39,"vy":8,"fw_parent":68,"on":1,"on.draw":69,"on.keychord_press":17,"on.code_change":61,"Surface":68,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":66,"Page":39,"vy":8,"fw_parent":67,"on":1,"on.draw":67,"on.keychord_press":17,"on.code_change":61,"Surface":68,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":66,"Page":39,"vy":8,"fw_parent":66,"on":1,"on.draw":67,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":66,"Page":39,"vy":8,"fw_parent":65,"on":1,"on.draw":62,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":65,"Page":39,"vy":8,"fw_parent":64,"on":1,"on.draw":62,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
Surface = {
-- test data
{type='line', data={0,-1000, 0,1000}},
{type='line', data={-10000,0, 10000,0}},
{type='text', data={'0'}, x=-20,y=-20},
{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}},
}
{"box_height":44,"Viewport":29,"compute_layout":64,"Page":39,"vy":8,"fw_parent":63,"on":1,"on.draw":62,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":63,"Page":39,"vy":8,"fw_parent":62,"on":1,"on.draw":62,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":60,"Page":39,"vy":8,"fw_parent":61,"on":1,"on.draw":62,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":60,"Page":39,"vy":8,"fw_parent":60,"on":1,"on.draw":59,"on.keychord_press":17,"on.code_change":61,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":60,"Page":39,"vy":8,"fw_parent":59,"on":1,"on.draw":59,"on.keychord_press":17,"on.code_change":58,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":51,"Page":39,"vy":8,"fw_parent":58,"on":1,"on.draw":59,"on.keychord_press":17,"on.code_change":58,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":51,"Page":39,"vy":8,"fw_parent":57,"on":1,"on.draw":43,"on.keychord_press":17,"on.code_change":58,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"box_height":44,"Viewport":29,"compute_layout":51,"Page":39,"vy":8,"fw_parent":56,"on":1,"on.draw":43,"on.keychord_press":17,"on.code_change":57,"Surface":42,"on.mouse_release":13,"on.mouse_press":12,"on.update":14,"scale":7,"vx":5}
{"scale":7,"vx":5,"Viewport":29,"on.code_change":55,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":51,"on":1,"fw_parent":55,"Page":39,"on.draw":43,"box_height":44}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
{"scale":7,"vx":5,"Viewport":29,"on.code_change":55,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":51,"on":1,"on.code_change":49,"fw_parent":54,"Page":39,"on.draw":43,"box_height":44}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
--[[
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
]]
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"scale":7,"vx":5,"Viewport":29,"on.code_change":54,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":51,"on":1,"on.code_change":49,"fw_parent":53,"Page":39,"on.draw":43,"box_height":44}
{"scale":7,"vx":5,"Viewport":29,"on.code_change":53,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":51,"on":1,"on.code_change":49,"fw_parent":52,"Page":39,"on.draw":43,"box_height":44}
{"scale":7,"vx":5,"Viewport":29,"on.code_change":52,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":51,"on":1,"on.code_change":49,"fw_parent":51,"Page":39,"on.draw":43,"box_height":44}
{"scale":7,"vx":5,"Viewport":29,"on.code_change":50,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":51,"on":1,"on.code_change":49,"fw_parent":50,"Page":39,"on.draw":43,"box_height":44}
{"scale":7,"vx":5,"Viewport":29,"on.code_change":50,"vy":8,"on.mouse_press":12,"on.mouse_release":13,"on.update":14,"Surface":42,"on.keychord_press":17,"compute_layout":46,"on":1,"on.code_change":49,"fw_parent":49,"Page":39,"on.draw":43,"box_height":44}
{"compute_layout":46,"vy":8,"on.code_change":49,"on.update":14,"on":1,"scale":7,"on.mouse_press":12,"fw_parent":48,"on.mouse_release":13,"Page":39,"on.draw":43,"on.keychord_press":17,"vx":5,"Viewport":29,"box_height":44,"Surface":42}
{"compute_layout":46,"vy":8,"on.code_change":48,"on.update":14,"on":1,"scale":7,"on.mouse_press":12,"fw_parent":47,"on.mouse_release":13,"Page":39,"on.draw":43,"on.keychord_press":17,"vx":5,"Viewport":29,"box_height":44,"Surface":42}
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(Page, Page.x,Page.y, Surface) -- just in case we edited Page
end
on.code_change = function()
{"compute_layout":46,"vy":8,"on.code_change":47,"on.update":14,"on":1,"scale":7,"on.mouse_press":12,"fw_parent":46,"on.mouse_release":13,"Page":39,"on.draw":43,"on.keychord_press":17,"vx":5,"Viewport":29,"box_height":44,"Surface":42}
{"fw_parent":45,"box_height":44,"on.mouse_press":12,"Surface":42,"on.mouse_release":13,"on.draw":43,"compute_layout":46,"vx":5,"on":1,"Viewport":29,"on.keychord_press":17,"Page":39,"vy":8,"scale":7,"on.update":14}
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
{"fw_parent":44,"box_height":44,"on.mouse_press":12,"Surface":42,"on.mouse_release":13,"on.draw":43,"compute_layout":45,"vx":5,"on":1,"Viewport":29,"on.keychord_press":17,"Page":39,"vy":8,"scale":7,"on.update":14}
update_editor_box = function(obj, skip_cursor_node)
if obj.editor == nil then return end
if skip_cursor_node and obj == Cursor_node then return end
if obj.y > Viewport.y then
obj.editor.screen_top1.line = 1
obj.editor.screen_top1.pos = 1
obj.editor.top = vy(obj.y)
else
obj.editor.screen_top1, obj.editor.top = schema1_of_y(obj.editor, Viewport.y - obj.y)
end
print('top', obj.editor.top)
print('screen_top1', obj.editor.screen_top1.line, obj.editor.screen_top1.pos)
obj.editor.left = math.floor(vx(obj.x))
obj.editor.right = math.ceil(vx(obj.x+obj.w))
edit.update_font_settings(obj.editor, scale(20))
Text.redraw_all(obj.editor)
end
{"fw_parent":43,"box_height":44,"on.mouse_press":12,"Surface":42,"on.mouse_release":13,"on.draw":43,"vx":5,"on":1,"Viewport":29,"on.keychord_press":17,"Page":39,"vy":8,"scale":7,"on.update":14}
{"Viewport":29,"Page":39,"vy":8,"vx":5,"Surface":42,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":43,"on.update":14,"scale":7,"fw_parent":42,"on.keychord_press":17}
{"Viewport":29,"Page":39,"vy":8,"vx":5,"Surface":42,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":41,"on.update":14,"scale":7,"fw_parent":41,"on.keychord_press":17}
{"Viewport":29,"Page":39,"vy":8,"vx":5,"Surface":38,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":41,"on.update":14,"scale":7,"fw_parent":40,"on.keychord_press":17}
{"Viewport":29,"Page":39,"vy":8,"vx":5,"Surface":38,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":40,"on.update":14,"scale":7,"fw_parent":39,"on.keychord_press":17}
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, obj.show_cursor)
end
end
end
end
Surface = {
-- test data
{type='line', data={0,-1000, 0,1000}},
{type='line', data={0,0, 800,0}},
{type='text', data={'0'}, x=-20,y=-20},
{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}},
}
{"Viewport":29,"Page":39,"vy":8,"vx":5,"Surface":38,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":35,"on.update":14,"scale":7,"fw_parent":38,"on.keychord_press":17}
{"Viewport":29,"Page":19,"vy":8,"vx":5,"Surface":38,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":35,"on.update":14,"scale":7,"fw_parent":37,"on.keychord_press":17}
{"Viewport":29,"Page":19,"vy":8,"vx":5,"Surface":37,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":35,"on.update":14,"scale":7,"fw_parent":36,"on.keychord_press":17}
{"Viewport":29,"Page":19,"vy":8,"vx":5,"Surface":36,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":35,"on.update":14,"scale":7,"fw_parent":35,"on.keychord_press":17}
{"Viewport":29,"Page":19,"vy":8,"vx":5,"Surface":33,"on.mouse_press":12,"on":1,"on.mouse_release":13,"on.draw":35,"on.update":14,"scale":7,"fw_parent":34,"on.keychord_press":17}
{"on.keychord_press":17,"Viewport":29,"scale":7,"vy":8,"Page":19,"on.draw":34,"fw_parent":33,"on.mouse_press":12,"Surface":33,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":29,"scale":7,"vy":8,"Page":19,"on.draw":32,"fw_parent":32,"on.mouse_press":12,"Surface":33,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":29,"scale":7,"vy":8,"Page":19,"on.draw":32,"fw_parent":31,"on.mouse_press":12,"Surface":30,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":29,"scale":7,"vy":8,"Page":19,"on.draw":31,"fw_parent":30,"on.mouse_press":12,"Surface":30,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":29,"scale":7,"vy":8,"Page":19,"on.draw":27,"fw_parent":29,"on.mouse_press":12,"Surface":30,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":29,"scale":7,"vy":8,"Page":19,"on.draw":27,"fw_parent":28,"on.mouse_press":12,"Surface":28,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
print('left', vx(obj.x))
print('right', vx(obj.x+obj.w))
print('width', vx(obj.x+obj.w)-vx(obj.x))
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":27,"fw_parent":27,"on.mouse_press":12,"Surface":28,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":27,"fw_parent":26,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":26,"fw_parent":25,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":25,"fw_parent":24,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":24,"fw_parent":23,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":23,"fw_parent":22,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":22,"fw_parent":21,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":21,"fw_parent":20,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":11,"fw_parent":19,"on.mouse_press":12,"Surface":20,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":19,"on.draw":11,"fw_parent":18,"on.mouse_press":12,"Surface":3,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"Viewport":6,"scale":7,"vy":8,"Page":18,"on.draw":11,"fw_parent":17,"on.mouse_press":12,"Surface":3,"on.mouse_release":13,"on":1,"on.update":14,"vx":5}
{"on.keychord_press":17,"on.mouse_press":12,"Surface":3,"on.mouse_release":13,"scale":7,"on.update":14,"on":1,"vx":5,"Viewport":6,"vy":8,"fw_parent":16,"on.draw":11}
{"on.keychord_press":16,"on.mouse_press":12,"Surface":3,"on.mouse_release":13,"scale":7,"on.update":14,"on":1,"vx":5,"Viewport":6,"vy":8,"fw_parent":15,"on.draw":11}
{"on.keychord_press":15,"on.mouse_press":12,"Surface":3,"on.mouse_release":13,"scale":7,"on.update":14,"on":1,"vx":5,"Viewport":6,"vy":8,"fw_parent":14,"on.draw":11}
on.draw = function()
love.graphics.setColor(1,0,0)
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))
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 or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
to_text = function(x,y)
for _,node in ipairs(Surface) do
if node.type == 'text' then
if x >= node.x and x < node.x + node.w then
if y >= node.y and y < node.y + node.h then
return node
end
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('Creating text of size', scaled_fontsize)
love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
print('aaaa', obj.text)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('width', obj.w, 'scales to', scale(obj.w))
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
B = function(skip_cursor_node)
-- recompute various aspects based on the current viewport settings
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update it
for _,obj in ipairs(Surface) do
if obj.type == 'line' then
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
elseif obj.type == 'bezier' then
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
if obj.w then
update_editor_box(obj, skip_cursor_node)
else
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
end
end
end
end
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print('init', obj.data[1], obj.w)
print('at zoom', Viewport.zoom)
print('with width', obj.w)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,2000,300 do
for y=-1000,1000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in ipairs(Box_heights) do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
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
-- leaf node containing raw text
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for i,s in ipairs(node.data) do
local text = love.graphics.newText(font(scaled_fontsize), node.data)
local width = text:getWidth()
print(node.data[i], 'has width', width)
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(Page, Page.x,Page.y, Surface)
end
on.code_change = function()
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
--[[
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
]]
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,300 do
for y=-1000,1000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(Page, Page.x,Page.y, Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('Creating text of size', scaled_fontsize)
love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
print(obj.text)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print('init', obj.data[1], obj.w)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(Page, Page.x,Page.y, Surface)
end
on.code_change = function()
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
box_height = function(node)
-- return the height of a node. The result is scaled.
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
print('box height', i, y)
table.insert(Box_heights, y)
end
end
return y
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
--[[
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
]]
-- { type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
--[[
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
]]
{ type='rows', width=90, data={
-- {type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,200 do
for y=-1000,1000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
--[[
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
]]
-- { type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
--[[
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
]]
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
box_height = function(node)
-- return the height of a node. The result is scaled.
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
print('box height', i, y)
table.insert(Box_heights, y)
end
end
return y
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,400 do
for y=-1000,1000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
--[[
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
]]
-- { type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
--[[
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
]]
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
on.draw = function()
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
print('draw rectangle')
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
box_height = function(node)
-- return the height of a node. The result is scaled.
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
print('box height', i, y)
table.insert(Box_heights, y)
end
end
return y
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
print(obj.text)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,1000 do
for y=-1000,1000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,1000 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
box_height = function(node)
-- return the height of a node. The result is scaled.
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
print('box height', i, y)
table.insert(Box_heights, y)
end
end
return y
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
--[[
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
]]
-- { type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
-- {type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
print('== draw')
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
print('draw rectangle')
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
print('draw text', obj.data[1], obj.editor.lines[1].data, obj.editor.line_cache[1].fragments)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
box_height = function(node)
-- return the height of a node. The result is scaled.
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
table.insert(Box_heights, y)
end
end
return y
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 1,b=0}, 10)
red = not red
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
--[[
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
]]
-- { type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=(x+y)/1000%2,g=((x+y)/1000+1)%2,b=0}, 10)
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
print('draw text', obj.data[1], obj.editor.lines[1].data, obj.editor.line_cache[1].fragments)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in ipairs(Box_heights) do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=(x+y)/1000%2,g=(x+y)/1000%2+1,b=0}, 10)
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
-- { type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=(x+y)/1000%2,g=((x+y)/1000+1)%2,b=0}, 10)
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=1,g=0,b=0}, 10)
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
print('draw text', obj.data[1], obj.editor.lines[1].data, obj.editor.line_cache[1])
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
-- { type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
love.graphics.setColor(0,1,0)
for _,y in Box_heights do
love.graphics.line(vx(0), vy(y), vx(10), vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
-- love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for x=-1000,1000,100 do
for y=-1000,1000,100 do
add_thick_line({type='line', data={x,y, x+2000,y+2000, x,y+4000}, r=1,g=0,b=0}, 10)
end
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for y=-1000,1000,100 do
add_thick_line({type='line', data={-1000,y, 1000,y+2000, -6000,y+4000}, r=1,g=0,b=0}, 10)
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
box_height = function(node)
-- return the height of a node. The result is scaled.
Box_heights = {}
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
table.insert(Box_heights, y)
end
return y
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
--[[
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
-- "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
]]
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
print('draw text', obj.data[1], obj.editor.lines[1].data, obj.w)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for y=-1000,1000,100 do
add_thick_line({type='line', data={-6000,y, 6000,y+2000, -6000,y+4000}, r=1,g=0,b=0}, 10)
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
box_height = function(node)
-- return the height of a node. The result is scaled.
print('computing box height based on font size', node.scaled_fontsize, node.editor.font_height, node.editor.line_height)
if #node.editor.lines > 1 then Box_heights = {} end
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
if #node.editor.lines > 1 then
table.insert(Box_heights, y)
end
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
box_height = function(node)
-- return the height of a node. The result is scaled.
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
end
return y
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for y=-1000,1000,100 do
add_thick_line({type='line', data={-6000,y, 6000,y+2000}, r=1,g=0,b=0}, 10)
end
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
box_height = function(node)
-- return the height of a node. The result is scaled.
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
end
return y
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
for y=-1000,1000,100 do
add_thick_line({type='line', data={-6000,y, 6000,y+2000}, r=1,g=0,b=0}, 10)
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
print('draw text', obj.data[1], obj.editor.lines[1].data, obj.w)
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(scaled_fontsize)
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
box_height = function(node)
-- return the height of a node. The result is scaled.
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
end
return y
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
add_thick_line({type='line', data={0,0, 6000,1000}, r=1,g=0,b=0}, 10)
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
box_height = function(node)
-- return the height of a node. The result is scaled.
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
end
return y
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
add_thick_line({type='line', data={0,0, 6000,1000}, r=1,g=0,b=0}, 5)
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(font(obj, scaled_fontsize))
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
add_thick_line = function(s, thickness)
-- increase the thickness of a horizontal-ish line
table.insert(Surface, s)
for i=1,thickness-1 do
local s = copy_shape(s)
for j=2,#s.data, 2 do
s.data[j] = s.data[j]+1
end
table.insert(Surface, s)
end
end
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
add_thick_line = function(s, thickness)
-- increase the thickness of a horizontal-ish line
table.insert(Surface, s)
for i=1,thickness-1 do
for j=2,#s.data, 2 do
s.data[j] = s.data[j]+1
end
table.insert(Surface, s)
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
print('draw text', obj.data, obj.data[1], obj.w, obj.fg)
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(font(obj, scaled_fontsize))
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
table.insert(Surface, {type='line', data={0,0, 6000,1000}, r=1,g=0,b=0})
table.insert(Surface, {type='line', data={0,1, 6000,1001}, r=1,g=0,b=0})
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
table.insert(Surface, {type='line', data={0,0, 6000,1000}, r=1,g=0,b=0})
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
print('heights', obj.editor.line_height, obj.editor.font_height, obj.scaled_fontsize)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
A = function(preserve_screen_top_of_cursor_node)
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
table.insert(Surface, {type='line', data={0,0, 100,600}, r=1,g=0,b=0})
compute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)
-- continue the pipeline
B(preserve_screen_top_of_cursor_node)
-- TODO: ugly that we're manipulating editor objects twice
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
print('draw text', obj.data, obj.data[1], obj.w)
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
love.graphics.setFont(font(obj, scaled_fontsize))
-- obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
end
return y
end
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_pos
end
return y
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(Page, Page.x,Page.y, Surface)
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
-- y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
y = y + scale(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, Viewport.zoom, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('creating text of size', scaled_fontsize)
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.scaled_fontsize*#node.editor.line_cache[i].screen_line_starting_pos
-- y = y + scale(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, Viewport.zoom, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(Page, Page.x,Page.y, Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('updating editor', obj.data[1])
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
elseif Cursor_node then
end
end
edit.keychord_press(Cursor_node.editor, chord, key)
on.keychord_press = function(chord, key)
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
print('setting font', scaled_fontsize)
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
Page.x,Page.y,
Surface)
end
on.code_change = function()
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
Page.x,Page.y,
Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
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
-- leaf node containing raw text
print(x,y, node.data[1])
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
Page.x,Page.y,
Surface)
end
on.code_change = function()
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
for x=0,1000,100 do
love.graphics.line(vx(x),vy(-5), vx(x),vy(5))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
while #Surface > 3 do
table.remove(Surface)
end
print('code changed', Page.x,Page.y)
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
Page.x,Page.y,
Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw text', obj.w, obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
print('code changed')
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
Page.x,Page.y,
Surface)
end
on.code_change = function()
Page = {
-- page
type='cols', x=0, y=20,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
print('code changed')
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
if Cursor_node then
end
end
edit.text_input(Cursor_node.editor, t)
on.text_input = function(t)
on.draw = function()
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(vx(-5),vy(y), vx(5),vy(y))
end
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
elseif Cursor_node then
end
end
edit.keychord_press(Cursor_node.editor, chord, key)
on.keychord_press = function(chord, key)
if Pan then
Pan = nil
elseif Cursor_node then
end
end
edit.mouse_release(Cursor_node.editor, x,y, mouse_button)
on.mouse_release = function(x,y, mouse_button)
if Cursor_node then
Cursor_node.show_cursor = nil
Cursor_node = nil
end
local node = to_text(x,y)
if node then
Cursor_node = node
node.show_cursor = true
else
Pan = {x=Viewport.x+x,y=Viewport.y+y}
end
end
edit.mouse_press(node.editor, x,y, mouse_button)
on.mouse_press = function(x,y, mouse_button)
local node = to_text(x,y)
if node then
Cursor_node = node
node.show_cursor = true
else
Pan = {x=Viewport.x+x,y=Viewport.y+y}
end
end
edit.mouse_press(node.editor, x,y, mouse_button)
on.mouse_press = function(x,y, mouse_button)
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
assert(obj.w)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
if Pan then
Pan = nil
else
local node = to_text(x,y)
if node then
end
end
end
edit.mouse_release(node.editor, x,y, mouse_button)
on.mouse_release = function(x,y, mouse_button)
if Pan then
Pan = nil
else
local node = to_text(x,y)
if node then
end
end
edit.mouse_release(node.editor, x,y, mouse_button)
on.mouse_release = function(x,y, mouse_button)
Page = {
-- page
type='cols', x=0, y=20,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
local node = to_text(x,y)
if node then
node.show_cursor = true
print('show cursor')
else
print('pan')
Pan = {x=Viewport.x+x,y=Viewport.y+y}
end
end
edit.mouse_press(node.editor, x,y, mouse_button)
on.mouse_press = function(x,y, mouse_button)
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(obj.editor.left,vy(y), obj.editor.right,vy(y))
end
end
end
end
end
local node = to_text(x,y)
if node then
node.show_cursor = true
print('show cursor')
else
print('pan')
Pan = {x=Viewport.x+x,y=Viewport.y+y}
end
end
on.mouse_press = function(x,y, mouse_button)
Surface = {
-- test data
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data={'0'}, x=-20,y=-20},
{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}},
}
on.draw = function()
print('on.draw')
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
print('initializing editor')
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
initialize_editor(obj)
print('updating editor', obj.editor)
end
print('editor', obj.editor)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
local node = to_text(x,y)
if node then
node.show_cursor = true
else
Pan = {x=Viewport.x+x,y=Viewport.y+y}
end
end
on.mouse_press = function(x,y, mouse_button)
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
love.graphics.setColor(1,0,0)
for y=0,1000,100 do
love.graphics.line(obj.editor.left,y, obj.editor.right,y)
end
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 15)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
on.draw = function()
print('on.draw')
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
print('initializing editor')
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
initialize_editor(obj)
print('updating editor', obj.editor)
end
print('editor', obj.editor)
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
love.graphics.setColor(1,0,0)
for i=1,#obj.editor.lines do
local y = obj.y + obj.editor.line_cache[i].starty
love.graphics.line(obj.editor.left,y, obj.editor.right,y)
end
end
end
end
end
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
-- leaf node containing raw text
print(x,y, node.data[1])
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 15)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
on.draw = function()
print('on.draw')
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
initialize_editor(obj)
print('updating editor', obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 15)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
end
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
love.graphics.setColor(1,0,0)
for i=1,#obj.editor.lines do
local y = obj.y + obj.editor.line_cache[i].starty
love.graphics.line(0,y, 800,y)
end
end
end
end
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
print('on.code_change')
compute_layout = function(node, x,y, nodes_to_render)
print('compute_layout')
-- 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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
print('node editor', node.editor)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
print('on.code_change')
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
love.graphics.setColor(1,0,0)
for i=1,#obj.editor.lines do
local y = vy(obj.editor.line_cache[i].starty)
love.graphics.line(0,y, 800,y)
end
end
end
end
end
Page = {
-- page
type='cols', x=0, y=200,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
initialize_editor(obj)
print('updating editor', obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
love.graphics.setFont(font(scaled_fontsize))
obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
love.graphics.setColor(1,0,0)
for i=1,#obj.editor.lines do
local y = vy(obj.editor.lines[i].starty)
love.graphics.line(0,y, 800,y)
end
end
end
end
end
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + scale(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, Viewport.zoom, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
print('node editor', node.editor)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
Page = {
-- page
type='cols', x=0, y=400,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print(obj.fontsize, scaled_fontsize, scaled_lineheight)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print(obj.fontsize, scaled_fontsize, scaled_lineheight)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
print(node.editor)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print(obj.fontsize, scaled_fontsize, scaled_lineheight)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
local scaled_lineheight = math.floor(scaled_fontsize*1.3)
print(scaled_fontsize, scaled_lineheight)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, scaled_lineheight)
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
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
-- leaf node containing raw text
print(x,y, node.data[1])
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
-- --[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + scale(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, Viewport.zoom, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
while #Surface > 3 do
table.remove(Surface)
end
compute_layout(
Page,
-- --[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
while #Surface > 3 do
table.remove(Surface)
end
local node = compute_layout(
Page,
-- --[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0,
Surface)
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + scale(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
local node = compute_layout(
Page,
-- --[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page,
-- --[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1], obj.fg)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
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
-- leaf node containing raw text
print(node.data[1])
node.x = x
node.y = y
-- render background if necessary
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- render contents
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
if node_to_render then
node_to_render.w = node.w
node_to_render.h = node.h
end
elseif node.type == 'rows' then
node.x = x
node.y = y
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local node_to_render
if node.bg then
node_to_render = {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y}
table.insert(nodes_to_render, node_to_render)
end
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node_to_render then
node_to_render.w = w
node_to_render.h = h
end
end
return x+node.w,y+node.h
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
--Page,
-- --[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
--Page,
-- [[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- ]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
print('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page,
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
Text.clear_screen_line_cache(node.editor, i)
print('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)
end
return y
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('draw', obj.data[1])
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
]]
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
Text.clear_screen_line_cache(node.editor, i)
print('height', i, y)
end
return y
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
]]
print('AAA', #Surface)
end
on.code_change = function()
Page = {
-- page
type='cols', x=0, y=400,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
Page)
--[[
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
]]
print('AAA', #Surface)
end
on.code_change = function()
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
Text.clear_screen_line_cache(node.editor, i)
print('height', i, y)
end
return y
end
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.w = 0
for _,s in ipairs(node.data) do
local text = love.graphics.newText(font(node, scaled_fontsize), node.data)
local width = text:getWidth()
if node.w < width then node.w = width end
end
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
Page = {
-- page
type='cols', x=0, y=20,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
print(node.data[1], node.w)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
print('AAA', #Surface)
end
on.code_change = function()
Page = {
-- page
type='cols', x=0, y=300,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
Page = {
-- page
type='cols', x=0, y=20,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
'1',
'2',
'3',
},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node,
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
}
print('AAA', #Surface)
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node}
print('AAA', #Surface)
end
on.code_change = function()
print('AAAAAAAAAAAAAAAAA')
local node = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node}
print('AAA', #Surface)
end
on.code_change = function()
local node = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node}
print('AAA', #Surface)
end
on.code_change = function()
on.update = function(dt)
if Pan then
end
if App.mouse_down(1) then
clip_all()
end
end
Viewport.x = Pan.x - App.mouse_x()
Viewport.y = Pan.y - App.mouse_y()
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
print(node.w)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
local node = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node}
print('AAA')
end
on.code_change = function()
local node = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
Surface = {node}
end
on.code_change = function()
Surface = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
end
on.code_change = function()
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
for _,obj in ipairs(Surface) do
print(obj.type, obj.data)
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
elseif chord == 'C-0' then
-- reset zoom
Viewport.zoom = 1.0
end
end
on.keychord_press = function(chord, key)
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
elseif chord == 'C--' then
-- zoom out
Viewport.zoom = Viewport.zoom-0.1
end
end
on.keychord_press = function(chord, key)
on.draw = function()
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))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
if chord == 'C-=' then
-- zoom in
Viewport.zoom = Viewport.zoom+0.1
end
end
on.keychord_press = function(chord, key)
Surface = {
-- test data
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{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}},
}
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
if node.bg then
table.insert(nodes_to_render, {type='rectangle', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, w=node.w, h=node.h})
end
end
return x+node.w,y+node.h
end
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
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
table.insert(nodes_to_render, node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
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)
table.insert(nodes_to_render, node)
if node.type == 'text' then
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{type='text', data={'abc'},},
{type='text', data={'abc'},},
}},
{ type='rows', width=90, data={
{type='text', data={'def'},},
{type='text', data={'def'},},
}},
}},
}},
},
}
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='text', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{data={'abc'},},
{data={'abc'},},
}},
{ type='rows', width=90, data={
{data={'def'},},
{data={'def'},},
}},
}},
}},
},
}
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)
print('compute_layout: node of type', node.type, 'at', x,y)
table.insert(nodes_to_render, node)
if node.type == 'text' then
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
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)
print('compute_layout: node of type', node.type, 'at', x,y)
table.insert(nodes_to_render, node)
if node.type == 'text' then
-- leaf node containing raw text
node.x = x
node.y = y
if node.width then
node.w = node.width
else
local scaled_fontsize = scale(node.fontsize or 20)
node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)
node.w = node.text:getWidth()
end
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
on.draw = function()
for i,obj in ipairs(Surface) do
print(i, obj.type)
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
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)
print('compute_layout: node of type', node.type, 'at', x,y)
table.insert(nodes_to_render, node)
if node.type == 'text' and node.width then
-- leaf node containing raw text
node.x = x
node.y = y
node.w = node.width
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
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)
print('compute_layout: node of type', node.type)
table.insert(nodes_to_render, node)
if node.type == 'text' and node.width then
-- leaf node containing raw text
node.x = x
node.y = y
node.w = node.width
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
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)
print(node.type)
table.insert(nodes_to_render, node)
if node.type == 'text' and node.width then
-- leaf node containing raw text
node.x = x
node.y = y
node.w = node.width
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
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)
table.insert(nodes_to_render, node)
if node.type == 'text' and node.width then
-- leaf node containing raw text
node.x = x
node.y = y
node.w = node.width
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
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)
table.insert(nodes_to_render, node)
if node.type == 'text' and node.width then
-- leaf node containing raw text
node.x = x
node.y = y
node.w = node.width
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = dom.compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = dom.compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
Surface = {
-- test data
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='rectangle', x=50,y=50, width=20,height=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}},
}
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)
table.insert(nodes_to_render, node)
if node.type == 'text' and node.width then
-- leaf node containing raw text
node.x = x
node.y = y
node.w = node.width
initialize_editor(node)
node.h = box_height(node)
elseif node.type == 'rows' then
node.x = x
node.y = y
-- lay out children top to bottom
local subx,suby = x,y
local w,h = 0,0
local subnodes
for _,child in ipairs(node.data) do
if child.margin then
suby = suby+child.margin
h = h+child.margin
end
subx,suby = dom.compute_layout(child, x,suby, nodes_to_render)
if w < child.w then
w = child.w
end
h = h+child.h
end
node.w = w
node.h = h
elseif node.type == 'cols' then
node.x = x
node.y = y
-- lay out children left to right
local subx,suby = x,y
local w,h = 0,0
for _,child in ipairs(node.data) do
if child.margin then
subx = subx+child.margin
w = w+child.margin
end
subx,suby = dom.compute_layout(child, subx,y, nodes_to_render)
w = w + child.w
if h < child.h then
h = child.h
end
end
node.w = w
node.h = h
end
return x+node.w,y+node.h
end
on.draw = function()
for i,obj in ipairs(Surface) do
print(i, obj.type)
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print(obj.data)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print(obj.data)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='text',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='edit', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{data={'abc'},},
{data={'abc'},},
}},
{ type='rows', width=90, data={
{data={'def'},},
{data={'def'},},
}},
}},
}},
},
}
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
initialize_editor(obj)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
initialize_editor = function(obj)
if obj.w then
-- use an editor to wrap the text
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{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}},
}
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
if obj.w then
-- use an editor to wrap the text
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{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}},
}
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
if obj.w then
-- use an editor to wrap the text
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
compute_layout = function(node, x,y)
if node.type == 'text' and node.width then
node.x = x
node.y = y
node.w = node.width
node.h = box_height(node)
end
return node
end
--[[
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
]]
compute_layout = function(node, x,y)
if node.type == 'text' and node.width then
node.x = x
node.y = y
node.editor = edit.initialize
node.editor.top = y
node.editor.left = x
node.editor.right = x + node.w
node.w = node.width
node.h = box_height(node)
end
return node
end
--[[
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
]]
compute_layout = function(node, x,y)
if node.type == 'text' and node.width then
node.x = x
node.y = y
node.editor = edit.initialize
node.editor.top = y
node.editor.left = x
node.editor.right = x + node.w
node.w = node.width
node.h = dom.height(node)
end
return node
end
--[[
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
]]
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
compute_layout = function(node, x,y)
if node.type == 'text' and node.width then
node.x = x
node.y = y
node.editor.top = y
node.editor.left = x
node.editor.right = x + node.w
node.w = node.width
node.h = dom.height(node)
end
return node
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
print('rendering', obj.data)
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
compute_layout = function(node, x,y)
if node.type == 'text' and node.width then
node.x = x
node.y = y
node.editor.top = y
node.editor.left = x
node.editor.right = x + node.w
node.h = dom.height(node)
end
return node
end
on.code_change = function()
print('AAA')
Surface = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
end
on.code_change = function()
Surface = compute_layout(
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
0,0)
end
compute_layout = function(node, x,y)
if node.type == 'text' and node.width then
node.x = x
node.y = y
node.editor.top = y
node.editor.left = x
node.editor.right = x + node.w
node.h = dom.height(node)
end
end
box_height = function(node)
local y = 0
for i=1,#node.editor.lines do
local line = node.editor.lines[i]
if node.editor.line_cache[i] == nil then
node.editor.line_cache[i] = {}
end
node.editor.line_cache[i].fragments = nil
node.editor.line_cache[i].screen_line_starting_pos = nil
Text.compute_fragments(node.editor, i)
Text.populate_screen_line_starting_pos(node.editor, i)
y = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_pos
Text.clear_screen_line_cache(node.editor, i)
end
return y
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{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}},
}
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
if obj.width == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
-- use an editor to wrap the text
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursor
end
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
-- for now the editor is just a way to line-wrap text. Hide the cursor.
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true)
end
end
end
Page = {
-- page
type='cols', x=0, y=0,
width=800, data={
-- editor covering left side
{
type='edit',
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ type='rows', name='searches', margin=50, data={
{ type='text', data={''},},
{ type='cols', data={
{ type='text', data={'search:'},},
{ type='edit', name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ type='text', data={'table:'},},
{ type='cols', bg={r=0.8,g=0.8,b=0.8}, data={
{ type='rows', width=90, data={
{data={'abc'},},
{data={'abc'},},
}},
{ type='rows', width=90, data={
{data={'def'},},
{data={'def'},},
}},
}},
}},
},
}
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='edit', 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 = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='edit', data={'abc', 'def'}, x=100, 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 = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='edit', data={'abc', 'def'}, x=100, y=50, w=50,h=50, fg={r=0,g=0, 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}},
}
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
end
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
--{type='edit', data={'abc', 'def'}, x=100, y=50, w=50,h=50, fg={r=0,g=0, 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}},
}
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y or obj.scaled_fontsize ~= scaled_fontsize then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='edit', data={'abc', 'def'}, x=100, y=50, w=50,h=50, fg={r=0,g=0, 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 = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='edit', data={'abc', 'def'}, x=100, y=50, w=50,h=50, fg={r=0,g=0, b=0.5}},
{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}},
}
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize_state(obj.y, obj.x, obj.x+obj.w, scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
print(edit)
obj.editor = edit.initialize(obj.y, obj.x, obj.x+obj.w, scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize(obj.y, obj.x, obj.x+obj.w, scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize(obj.y, obj.x, obj.x+obj.w, scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.editor = edit.initialize(obj.y, obj.x, obj.x+obj.w, scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
end
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})
end
end
end
on.draw = function()
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.width),scale(obj.height))
elseif obj.type == 'line' then
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
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
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
elseif obj.type == 'text' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
end
end
end
Surface = {
-- test data
{type='rectangle', x=50,y=50, width=20,height=80, r=1,g=0,b=0},
{type='line', data={0,0, 0,600}},
{type='line', data={0,0, 800,0}},
{type='text', data='0', x=-20,y=-20},
{type='edit', data={'abc', 'def'}, x=100, y=50, w=50,h=50,},
{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}},
}
Page = {
-- page
x=0, y=0,
width=800, cols={
-- editor covering left side
{
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
width=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ name='searches', margin=50, rows={
{ data={''},},
{ cols={
{ data={'search:'},},
{ name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, width=90,},
}},
{ data={'table:'},},
{ bg={r=0.8,g=0.8,b=0.8}, cols={
{ width=90, rows={
{data={'abc'},},
{data={'abc'},},
}},
{ width=90, rows={
{data={'def'},},
{data={'def'},},
}},
}},
}},
},
}
Page = {
-- page
x=0, y=0,
w=800, cols={
-- editor covering left side
{
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",},
w=400, bg={r=1,g=1,b=0}
},
-- a table on the right
{ name='searches', margin=50, rows={
{ data={''}, w=90,},
{ cols={
{ data={'search:'}, w=90,},
{ name='search', bg={r=0.8,g=0.8,b=0.8}, data={''}, w=90,},
}},
{ data={''}, w=90,},
{ data={'table:'}, w=90,},
{ bg={r=0.8,g=0.8,b=0.8}, rows={
{ cols={
{data={'abc'}, w=90,},
{data={'def'}, w=90,},
}},
{ cols={
{data={'abc'}, w=90,},
{data={'def'}, w=90,},
}},
}},
}},
},
}
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
obj.zdata = {}
for i=1,#obj.data,2 do
table.insert(obj.zdata, vx(obj.data[i]))
table.insert(obj.zdata, vy(obj.data[i+1]))
end
end
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y then
obj.saved_zoom = Viewport.zoom
obj.saved_x = Viewport.x
obj.saved_y = Viewport.y
zdata = {}
for i=1,#obj.data,2 do
table.insert(zdata, vx(obj.data[i]))
table.insert(zdata, vy(obj.data[i+1]))
end
obj.zdata = love.math.newBezierCurve(zdata):render()
love.graphics.line(unpack(obj.zdata))
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
obj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)
end
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
end
love.graphics.line(unpack(obj.zdata))
elseif obj.type == 'edit' then
local scaled_fontsize = scale(obj.fontsize or 20)
if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize then
obj.scaled_fontsize = scaled_fontsize
if Font == nil then Font = {} end
if Font[scaled_fontsize] == nil then
Font[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)
end
print(edit, edit.initialize)
obj.editor = edit.initialize(obj.y, obj.x, obj.x+obj.w, scaled_fontsize, math.floor(scaled_fontsize*1.3))
obj.editor.lines = load_array(obj.data)
Text.redraw_all(obj.editor)
if obj.w == nil then
love.graphics.draw(obj.text, vx(obj.x), vy(obj.y))
else
edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
Page = {
type='text', x=0, y=0,
name='editor',
doc='prose goes here, on the left half of the window',
margin=Margin_left,
data={
"Lorem Ipsum",
'1',
'2',
'3',
'mno',
'Acb',
'g',
'hij',
'klm',
'nop',
},
width=400,
}
This file contains no definition, but is used as a marker in the save dir to
indicate all definitions have been copied from the repo to the save dir.
This file contains no definition, but is used as a marker in the save dir to indicate all definitions have been copied from the repo to the save dir.